Skip to content

Commit

Permalink
Merge pull request #23 from r0adkll/master
Browse files Browse the repository at this point in the history
Release v1.6.0
  • Loading branch information
r0adkll authored Aug 19, 2018
2 parents c953e3f + e4f57a4 commit 7746bb1
Show file tree
Hide file tree
Showing 33 changed files with 1,170 additions and 851 deletions.
14 changes: 14 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Release Candidate

## Version
* <!-- Insert Version Number i.e. 2.1.3, 1.0.0, etc -->

## Changelog
<!-- List of developer orientated changes that go into this release -->
<!-- i.e. -->
<!-- Pull 193 -->
<!-- Issue #200 -->
<!-- etc -->

## Notes
<!-- Misc. notes or caveats related to this release/build -->
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 1.6.0
* [#12](https://gitlab.com/r0adkll/pokemon-tcg-deckbuilder/issues/12) - New deck testing feature where users can test out single hand deals or an overall multi-hand percentage view.
* [#20](https://gitlab.com/r0adkll/pokemon-tcg-deckbuilder/issues/20) - Added convienence filters for mass selecting standard or expanded expansions when searching
* Misc bug fixes

# 1.5.4
* Hotfix for bug with leaving the testing menu option out of the tablet menu config
* Minor tweaks to testing interface
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ apply plugin: 'io.fabric'
def GIT_SHA = 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()
def GIT_TAG = 'git describe --tags'.execute([], project.rootDir).text.trim()

def VERSION_NAME = "1.5.4"
def VERSION_NAME = "1.6.0"


ext.gitVersioner = [
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
<activity android:name=".arch.ui.features.exporter.preview.PdfPreviewActivity" />
<activity android:name=".arch.ui.features.browse.SetBrowserActivity"
android:theme="@style/Theme.DeckBuilder.Translucent" />
<activity android:name=".arch.ui.features.testing.DeckTestingActivity" />
<activity android:name=".arch.ui.features.testing.DeckTestingActivity"
android:screenOrientation="sensorPortrait"/>

<service android:name=".arch.data.features.cards.service.CacheService"
android:exported="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import com.r0adkll.deckbuilder.arch.domain.features.editing.repository.EditRepos
import com.r0adkll.deckbuilder.arch.domain.features.testing.DeckTester
import com.r0adkll.deckbuilder.arch.domain.features.testing.TestResults
import com.r0adkll.deckbuilder.arch.domain.features.validation.repository.DeckValidator
import com.r0adkll.deckbuilder.util.extensions.isMulligan
import com.r0adkll.deckbuilder.util.extensions.shuffle
import io.pokemontcg.model.Card
import io.pokemontcg.model.SubType
import io.pokemontcg.model.SuperType
Expand Down Expand Up @@ -78,6 +80,21 @@ class DefaultDeckTester @Inject constructor(
}


override fun testHandById(deckId: String, iterations: Int): Observable<List<PokemonCard>> {
return deckRepository.getDeck(deckId)
.flatMap { deck ->
validator.validate(deck.cards)
.map {
if (it.isValid) {
deal(deck.cards, iterations)
} else {
throw InvalidDeckException()
}
}
}
}


private fun deal(cards: List<PokemonCard>, iterations: Int): List<PokemonCard> {
val deck = cards.toMutableList()
(0 until iterations).forEach {
Expand All @@ -89,18 +106,15 @@ class DefaultDeckTester @Inject constructor(


private fun test(cards: List<PokemonCard>, iterations: Int): TestResults {
var mulligans = 0;
var mulligans = 0
var startingHands = HashMap<PokemonCard, Int>()

(0..iterations).forEach {
val shuffledCards = cards.shuffled()
val shuffledCards = cards.shuffle(DEFAULT_SHUFFLE_PER_HAND)
val firstHand = shuffledCards.subList(0, DEFAULT_HAND_SIZE)

// 1) Check for mulligans
val didMulligan = firstHand.none {
it.supertype == SuperType.POKEMON
&& (it.subtype == SubType.BASIC || it.evolvesFrom.isNullOrBlank())
}
val didMulligan = firstHand.isMulligan()

// 2) If we didn't mulligan, then update mapping
if (didMulligan) {
Expand All @@ -119,5 +133,8 @@ class DefaultDeckTester @Inject constructor(

companion object {
const val DEFAULT_HAND_SIZE = 7

// This value is to emulate the ideal # of riffle shuffles one should do when shuffling the deck
const val DEFAULT_SHUFFLE_PER_HAND = 7
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ interface DeckTester {
fun testSession(sessionId: Long, iterations: Int = 1000): Observable<TestResults>
fun testDeck(deck: Deck, iterations: Int = 1000): Observable<TestResults>
fun testDeckById(deckId: String, iterations: Int = 1000): Observable<TestResults>
fun testHand(sessionId: Long, iterations: Int = 1000): Observable<List<PokemonCard>>
fun testHand(sessionId: Long, iterations: Int = 7): Observable<List<PokemonCard>>
fun testHandById(deckId: String, iterations: Int = 7): Observable<List<PokemonCard>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ class DeckBuilderActivity : BaseActivity(), HasComponent<DeckBuilderComponent>,
finishEditItem.isVisible = state.isEditing

val testItem = menu.findItem(R.id.action_test)
// testItem.isVisible = BuildConfig.DEBUG
testItem.isVisible = BuildConfig.DEBUG
testItem.isEnabled = state.validation.isValid
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import com.r0adkll.deckbuilder.arch.ui.features.decks.adapter.Item
import com.r0adkll.deckbuilder.arch.ui.features.decks.di.DecksModule
import com.r0adkll.deckbuilder.arch.ui.features.exporter.MultiExportActivity
import com.r0adkll.deckbuilder.arch.ui.features.home.di.HomeComponent
import com.r0adkll.deckbuilder.arch.ui.features.testing.DeckTestingActivity
import com.r0adkll.deckbuilder.internal.analytics.Analytics
import com.r0adkll.deckbuilder.internal.analytics.Event
import com.r0adkll.deckbuilder.util.DialogUtils
import com.r0adkll.deckbuilder.util.DialogUtils.DialogText.*
import com.r0adkll.deckbuilder.util.ScreenUtils
import com.r0adkll.deckbuilder.util.ScreenUtils.smallestWidth
import com.r0adkll.deckbuilder.util.extensions.isVisible
import com.r0adkll.deckbuilder.util.extensions.plusAssign
import com.r0adkll.deckbuilder.util.extensions.snackbar
Expand All @@ -50,6 +52,7 @@ class DecksFragment : BaseFragment(), DecksUi, DecksUi.Intentions, DecksUi.Actio
private val shareClicks: Relay<Deck> = PublishRelay.create()
private val duplicateClicks: Relay<Deck> = PublishRelay.create()
private val deleteClicks: Relay<Deck> = PublishRelay.create()
private val testClicks: Relay<Deck> = PublishRelay.create()

private lateinit var adapter: DecksRecyclerAdapter

Expand All @@ -62,7 +65,8 @@ class DecksFragment : BaseFragment(), DecksUi, DecksUi.Intentions, DecksUi.Actio
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)

adapter = DecksRecyclerAdapter(activity!!, shareClicks, duplicateClicks, deleteClicks, dismissPreview, viewPreview)
adapter = DecksRecyclerAdapter(activity!!, shareClicks, duplicateClicks, deleteClicks,
testClicks, dismissPreview, viewPreview)
adapter.setOnItemClickListener(object : ListRecyclerAdapter.OnItemClickListener<Item> {
override fun onItemClick(v: View, item: Item, position: Int) {
if (item is Item.DeckItem) {
Expand All @@ -80,7 +84,7 @@ class DecksFragment : BaseFragment(), DecksUi, DecksUi.Intentions, DecksUi.Actio

adapter.setEmptyView(empty_view)

val layoutManager = GridLayoutManager(activity, if (ScreenUtils.smallestWidth(resources, ScreenUtils.Config.TABLET_10)) 6 else 2)
val layoutManager = GridLayoutManager(activity, if (smallestWidth(ScreenUtils.Config.TABLET_10)) 6 else 2)
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
val item = adapter.items[position]
Expand All @@ -93,7 +97,7 @@ class DecksFragment : BaseFragment(), DecksUi, DecksUi.Intentions, DecksUi.Actio
recycler.layoutManager = layoutManager
recycler.adapter = adapter

fab.setOnClickListener {
fab.setOnClickListener { _ ->
if (quickTip.isVisible()) {
quickTip.hide(fab)
}
Expand All @@ -120,6 +124,13 @@ class DecksFragment : BaseFragment(), DecksUi, DecksUi.Intentions, DecksUi.Actio
startActivity(intent)
}

disposables += testClicks
.subscribe {
Analytics.event(Event.SelectContent.Action("test_decklist"))
val intent = DeckTestingActivity.createIntent(activity!!, it.id)
startActivity(intent)
}

disposables += viewPreview
.subscribe {
startActivity(SetBrowserActivity.createIntent(activity!!, "sm7"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ class DecksRecyclerAdapter(
private val shareClicks: Relay<Deck>,
private val duplicateClicks: Relay<Deck>,
private val deleteClicks: Relay<Deck>,
private val testClicks: Relay<Deck>,
private val dismissPreview: Relay<Unit>,
private val viewPreview: Relay<Unit>
) : ListRecyclerAdapter<Item, UiViewHolder<Item>>(context) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UiViewHolder<Item> {
val itemView = inflater.inflate(viewType, parent, false)
return UiViewHolder.create(itemView, viewType, shareClicks, duplicateClicks, deleteClicks,
dismissPreview, viewPreview)
return UiViewHolder.create(itemView, viewType, shareClicks, duplicateClicks, testClicks,
deleteClicks, dismissPreview, viewPreview)
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.r0adkll.deckbuilder.arch.ui.features.decks.adapter

import android.annotation.SuppressLint
import android.support.annotation.LayoutRes
import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.PopupMenu
import android.widget.TextView
import com.jakewharton.rxrelay2.Relay
import com.r0adkll.deckbuilder.GlideApp
Expand Down Expand Up @@ -46,16 +48,18 @@ sealed class UiViewHolder<in I : Item>(itemView: View) : RecyclerView.ViewHolder
itemView: View,
private val shareClicks: Relay<Deck>,
private val duplicateClicks: Relay<Deck>,
private val testClicks: Relay<Deck>,
private val deleteClicks: Relay<Deck>
) : UiViewHolder<Item.DeckItem>(itemView) {

private val image: DeckImageView by bindView(R.id.image)
private val title: TextView by bindView(R.id.title)
private val actionShare: ImageView by bindView(R.id.action_share)
private val actionDuplicate: ImageView by bindView(R.id.action_duplicate)
private val actionDelete: ImageView by bindView(R.id.action_delete)
private val actionMore: ImageView by bindView(R.id.action_more)
private val actionTest: ImageView by bindView(R.id.action_test)


@SuppressLint("ClickableViewAccessibility")
override fun bind(item: Item.DeckItem) {
val deck = item.deck
title.text = deck.name
Expand All @@ -80,9 +84,23 @@ sealed class UiViewHolder<in I : Item>(itemView: View) : RecyclerView.ViewHolder
.into(image)
}

val popupMenu = PopupMenu(itemView.context, actionMore)
popupMenu.inflate(R.menu.deck_actions)
popupMenu.setOnMenuItemClickListener { item ->
when(item.itemId) {
R.id.action_duplicate -> { duplicateClicks.accept(deck); true }
R.id.action_delete -> { deleteClicks.accept(deck); true }
else -> false
}
}

actionMore.setOnTouchListener(popupMenu.dragToOpenListener)
actionMore.setOnClickListener {
popupMenu.show()
}

actionShare.setOnClickListener { shareClicks.accept(deck) }
actionDuplicate.setOnClickListener { duplicateClicks.accept(deck) }
actionDelete.setOnClickListener { deleteClicks.accept(deck) }
actionTest.setOnClickListener { testClicks.accept(deck) }
}


Expand Down Expand Up @@ -119,13 +137,14 @@ sealed class UiViewHolder<in I : Item>(itemView: View) : RecyclerView.ViewHolder
layoutId: Int,
shareClicks: Relay<Deck>,
duplicateClicks: Relay<Deck>,
testClicks: Relay<Deck>,
deleteClicks: Relay<Deck>,
dismissPreview: Relay<Unit>,
viewPreview: Relay<Unit>): UiViewHolder<Item> {
val viewType = ViewType.of(layoutId)
return when(viewType) {
PREVIEW -> PreviewViewHolder(itemView, dismissPreview, viewPreview) as UiViewHolder<Item>
DECK -> DeckViewHolder(itemView, shareClicks, duplicateClicks, deleteClicks) as UiViewHolder<Item>
DECK -> DeckViewHolder(itemView, shareClicks, duplicateClicks, testClicks, deleteClicks) as UiViewHolder<Item>
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class FilterFragment : BaseFragment(), FilterUi, FilterUi.Intentions, FilterUi.A
is FilterAttribute.SuperTypeAttribute -> attr.superType.displayName
is FilterAttribute.SubTypeAttribute -> attr.subType.displayName
is FilterAttribute.ContainsAttribute -> attr.attribute
is FilterAttribute.ExpansionAttribute -> attr.format.name.toLowerCase()
}))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.r0adkll.deckbuilder.arch.ui.features.filter

import com.r0adkll.deckbuilder.arch.domain.Format
import com.r0adkll.deckbuilder.arch.domain.Rarity
import com.r0adkll.deckbuilder.arch.domain.features.cards.model.Expansion
import com.r0adkll.deckbuilder.arch.domain.features.cards.model.Filter
import com.r0adkll.deckbuilder.arch.domain.features.cards.model.SearchField
import com.r0adkll.deckbuilder.arch.ui.features.filter.FilterUi.FilterAttribute
import com.r0adkll.deckbuilder.arch.ui.features.filter.FilterUi.FilterAttribute.SubTypeAttribute
import com.r0adkll.deckbuilder.arch.ui.features.filter.FilterUi.FilterAttribute.SuperTypeAttribute
import com.r0adkll.deckbuilder.util.extensions.expanded
import com.r0adkll.deckbuilder.util.extensions.standard
import io.pokemontcg.model.SuperType
import io.pokemontcg.model.Type

Expand All @@ -32,6 +35,7 @@ object FilterReducer {
is SuperTypeAttribute -> filter.copy(superType = filter.toggle(attribute.superType))
is SubTypeAttribute -> filter.copy(subTypes = filter.subTypes.toggle(attribute.subType))
is FilterAttribute.ContainsAttribute -> filter.copy(contains = filter.contains.toggle(attribute.attribute))
is FilterAttribute.ExpansionAttribute -> filter.toggle(attribute.expansions, attribute.format)
}


Expand Down Expand Up @@ -67,4 +71,27 @@ object FilterReducer {

private fun Filter.toggle(value: SuperType): SuperType? =
if (this.superType == value) null else value


private fun Filter.toggle(expansions: List<Expansion>, format: Format): Filter {
val isStandardSelected = this.expansions.containsAll(expansions.standard())
val isExpandedSelected = this.expansions.containsAll(expansions.expanded())

return when(format) {
Format.STANDARD -> if ((!isStandardSelected && !isExpandedSelected) || (isStandardSelected && isExpandedSelected)) {
// Select only standard expansions
this.copy(expansions = expansions.standard())
} else if (isStandardSelected && !isExpandedSelected) {
this.copy(expansions = emptyList())
} else {
this
}
Format.EXPANDED -> if (!isExpandedSelected) {
this.copy(expansions = expansions.expanded())
} else {
this.copy(expansions = emptyList())
}
else -> this
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.r0adkll.deckbuilder.arch.ui.features.filter

import android.support.annotation.StringRes
import com.r0adkll.deckbuilder.R
import com.r0adkll.deckbuilder.arch.domain.Format
import com.r0adkll.deckbuilder.arch.domain.Rarity
import com.r0adkll.deckbuilder.arch.domain.features.cards.model.Expansion
import com.r0adkll.deckbuilder.arch.domain.features.cards.model.Filter
Expand Down Expand Up @@ -113,6 +114,12 @@ data class FilterSpec(val specs: List<Spec>) : PaperParcelable {
override fun apply(filter: Filter): List<Item> {
val items = ArrayList<Item>()
items += Item.Header(R.string.filter_header_expansions)

val attributes = listOf(FilterAttribute.ExpansionAttribute(Format.STANDARD, expansions),
FilterAttribute.ExpansionAttribute(Format.EXPANDED, expansions))
val selectedAttributes = getSelectedFormatAttributes(filter)
items += Item.Attribute(attributes, selectedAttributes)

items += getVisibleExpansions(filter)
if (visibility != UNLIMITED) {
items += Item.ViewMore(when(visibility){
Expand All @@ -136,6 +143,20 @@ data class FilterSpec(val specs: List<Spec>) : PaperParcelable {
}
}


private fun getSelectedFormatAttributes(filter: Filter): List<FilterAttribute> {
val standardExpansions = expansions.filter { it.standardLegal }
val expandedExpansions = expansions.filter { it.expandedLegal }
val attrs = ArrayList<FilterAttribute.ExpansionAttribute>()
if (filter.expansions.containsAll(standardExpansions)) {
attrs += FilterAttribute.ExpansionAttribute(Format.STANDARD, expansions)
}
if (filter.expansions.containsAll(expandedExpansions)) {
attrs += FilterAttribute.ExpansionAttribute(Format.EXPANDED, expansions)
}
return attrs
}

companion object {
@JvmField val CREATOR = PaperParcelFilterSpec_Spec_ExpansionSpec.CREATOR
}
Expand Down
Loading

0 comments on commit 7746bb1

Please sign in to comment.