Migrate from kodein to koin
This commit is contained in:
parent
2831f60c30
commit
5fb07e0508
38 changed files with 223 additions and 207 deletions
|
@ -112,8 +112,7 @@ dependencies {
|
||||||
implementation 'org.permissionsdispatcher:permissionsdispatcher:4.6.0'
|
implementation 'org.permissionsdispatcher:permissionsdispatcher:4.6.0'
|
||||||
kapt 'org.permissionsdispatcher:permissionsdispatcher-processor:4.6.0'
|
kapt 'org.permissionsdispatcher:permissionsdispatcher-processor:4.6.0'
|
||||||
|
|
||||||
implementation 'com.github.salomonbrys.kodein:kodein:4.1.0'
|
implementation "org.koin:koin-android:2.1.1"
|
||||||
compileOnly 'org.glassfish:javax.annotation:3.1.1'
|
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package org.ligi.passandroid
|
package org.ligi.passandroid
|
||||||
|
|
||||||
import com.github.salomonbrys.kodein.Kodein
|
|
||||||
import com.github.salomonbrys.kodein.bind
|
|
||||||
import com.github.salomonbrys.kodein.instance
|
|
||||||
import com.github.salomonbrys.kodein.singleton
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.koin.core.module.Module
|
||||||
|
import org.koin.dsl.module
|
||||||
import org.ligi.passandroid.injections.FixedPassListPassStore
|
import org.ligi.passandroid.injections.FixedPassListPassStore
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
import org.ligi.passandroid.model.Settings
|
import org.ligi.passandroid.model.Settings
|
||||||
|
@ -20,26 +18,25 @@ import java.util.*
|
||||||
|
|
||||||
class TestApp : App() {
|
class TestApp : App() {
|
||||||
|
|
||||||
override fun createKodein() = Kodein.Module {
|
override fun createKoin(): Module {
|
||||||
bind<PassStore>() with singleton {
|
|
||||||
FixedPassListPassStore(emptyList())
|
return module {
|
||||||
|
single { passStore as PassStore }
|
||||||
|
single { settings }
|
||||||
|
single { tracker }
|
||||||
|
single { mock(EventBus::class.java) }
|
||||||
}
|
}
|
||||||
bind<Settings>() with singleton {
|
|
||||||
mock(Settings::class.java).apply {
|
|
||||||
`when`(getSortOrder()).thenReturn(PassSortOrder.DATE_ASC)
|
|
||||||
`when`(getPassesDir()).thenReturn(File(""))
|
|
||||||
`when`(doTraceDroidEmailSend()).thenReturn(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bind<Tracker>(overrides = true) with singleton { mock(Tracker::class.java) }
|
|
||||||
bind<EventBus>() with singleton { mock(EventBus::class.java) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
val tracker = mock(Tracker::class.java)
|
||||||
fun passStore(): PassStore = kodein.instance()
|
val passStore = FixedPassListPassStore(emptyList())
|
||||||
fun settings(): Settings = kodein.instance()
|
val settings = mock(Settings::class.java).apply {
|
||||||
|
`when`(getSortOrder()).thenReturn(PassSortOrder.DATE_ASC)
|
||||||
|
`when`(getPassesDir()).thenReturn(File(""))
|
||||||
|
`when`(doTraceDroidEmailSend()).thenReturn(false)
|
||||||
|
}
|
||||||
|
|
||||||
fun populatePassStoreWithSinglePass() {
|
fun populatePassStoreWithSinglePass() {
|
||||||
|
|
||||||
|
@ -51,13 +48,13 @@ class TestApp : App() {
|
||||||
|
|
||||||
fixedPassListPassStore().setList(passList)
|
fixedPassListPassStore().setList(passList)
|
||||||
|
|
||||||
passStore().classifier.moveToTopic(pass, "test")
|
passStore.classifier.moveToTopic(pass, "test")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun emptyPassStore() {
|
fun emptyPassStore() {
|
||||||
fixedPassListPassStore().setList(emptyList())
|
fixedPassListPassStore().setList(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fixedPassListPassStore() = passStore() as FixedPassListPassStore
|
private fun fixedPassListPassStore() = passStore as FixedPassListPassStore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class TheAddToCalendar {
|
||||||
fun testIfWeOnlyHaveCalendarStartDate() {
|
fun testIfWeOnlyHaveCalendarStartDate() {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
|
|
||||||
TestApp.passStore().currentPass!!.calendarTimespan = PassImpl.TimeSpan(time)
|
TestApp.passStore.currentPass!!.calendarTimespan = PassImpl.TimeSpan(time)
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||||
|
@ -44,7 +44,7 @@ class TheAddToCalendar {
|
||||||
hasType("vnd.android.cursor.item/event"),
|
hasType("vnd.android.cursor.item/event"),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.plusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.plusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||||
hasExtra("title", TestApp.passStore().currentPass!!.description)
|
hasExtra("title", TestApp.passStore.currentPass!!.description)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class TheAddToCalendar {
|
||||||
fun testIfWeOnlyHaveCalendarEndDate() {
|
fun testIfWeOnlyHaveCalendarEndDate() {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
|
|
||||||
TestApp.passStore().currentPass!!.calendarTimespan = PassImpl.TimeSpan(to = time)
|
TestApp.passStore.currentPass!!.calendarTimespan = PassImpl.TimeSpan(to = time)
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||||
|
@ -63,7 +63,7 @@ class TheAddToCalendar {
|
||||||
hasType("vnd.android.cursor.item/event"),
|
hasType("vnd.android.cursor.item/event"),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.minusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.minusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.toEpochSecond() * 1000),
|
||||||
hasExtra("title", TestApp.passStore().currentPass!!.description)
|
hasExtra("title", TestApp.passStore.currentPass!!.description)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class TheAddToCalendar {
|
||||||
fun testIfWeOnlyHaveCalendarStartAndEndDate() {
|
fun testIfWeOnlyHaveCalendarStartAndEndDate() {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
|
|
||||||
TestApp.passStore().currentPass!!.calendarTimespan = PassImpl.TimeSpan(time, time2)
|
TestApp.passStore.currentPass!!.calendarTimespan = PassImpl.TimeSpan(time, time2)
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||||
|
@ -82,7 +82,7 @@ class TheAddToCalendar {
|
||||||
hasType("vnd.android.cursor.item/event"),
|
hasType("vnd.android.cursor.item/event"),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time2.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time2.toEpochSecond() * 1000),
|
||||||
hasExtra("title", TestApp.passStore().currentPass!!.description)
|
hasExtra("title", TestApp.passStore.currentPass!!.description)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ class TheAddToCalendar {
|
||||||
fun testIfWeOnlyHaveExpirationDate() {
|
fun testIfWeOnlyHaveExpirationDate() {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
|
|
||||||
(TestApp.passStore().currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(time))
|
(TestApp.passStore.currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(time))
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||||
|
@ -105,7 +105,7 @@ class TheAddToCalendar {
|
||||||
hasType("vnd.android.cursor.item/event"),
|
hasType("vnd.android.cursor.item/event"),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.plusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.plusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||||
hasExtra("title", TestApp.passStore().currentPass!!.description)
|
hasExtra("title", TestApp.passStore.currentPass!!.description)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ class TheAddToCalendar {
|
||||||
fun testIfWeOnlyHaveExpirationEndDate() {
|
fun testIfWeOnlyHaveExpirationEndDate() {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
|
|
||||||
(TestApp.passStore().currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(to = time))
|
(TestApp.passStore.currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(to = time))
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||||
|
@ -127,7 +127,7 @@ class TheAddToCalendar {
|
||||||
hasType("vnd.android.cursor.item/event"),
|
hasType("vnd.android.cursor.item/event"),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.minusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.minusHours(DEFAULT_EVENT_LENGTH_IN_HOURS).toEpochSecond() * 1000),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time.toEpochSecond() * 1000),
|
||||||
hasExtra("title", TestApp.passStore().currentPass!!.description)
|
hasExtra("title", TestApp.passStore.currentPass!!.description)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ class TheAddToCalendar {
|
||||||
fun testIfWeOnlyHaveExpirationStartAndEndDate() {
|
fun testIfWeOnlyHaveExpirationStartAndEndDate() {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
|
|
||||||
(TestApp.passStore().currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(time, time2))
|
(TestApp.passStore.currentPass as PassImpl).validTimespans = listOf(PassImpl.TimeSpan(time, time2))
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
intending(hasType("vnd.android.cursor.item/event")).respondWith(Instrumentation.ActivityResult(RESULT_CANCELED, null))
|
||||||
|
@ -149,7 +149,7 @@ class TheAddToCalendar {
|
||||||
hasType("vnd.android.cursor.item/event"),
|
hasType("vnd.android.cursor.item/event"),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, time.toEpochSecond() * 1000),
|
||||||
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time2.toEpochSecond() * 1000),
|
hasExtra(CalendarContract.EXTRA_EVENT_END_TIME, time2.toEpochSecond() * 1000),
|
||||||
hasExtra("title", TestApp.passStore().currentPass!!.description)
|
hasExtra("title", TestApp.passStore.currentPass!!.description)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.*
|
import androidx.test.espresso.matcher.ViewMatchers.*
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.SdkSuppress
|
import androidx.test.filters.SdkSuppress
|
||||||
import com.github.salomonbrys.kodein.instance
|
|
||||||
import com.linkedin.android.testbutler.TestButler
|
import com.linkedin.android.testbutler.TestButler
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
@ -28,7 +27,7 @@ class TheBarCodeEditing {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val rule = TruleskActivityRule(PassEditActivity::class.java, false)
|
val rule = TruleskActivityRule(PassEditActivity::class.java, false)
|
||||||
|
|
||||||
val passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore = TestApp.passStore
|
||||||
|
|
||||||
private lateinit var currentPass: PassImpl
|
private lateinit var currentPass: PassImpl
|
||||||
|
|
||||||
|
|
|
@ -20,14 +20,14 @@ class TheCondensedPassViewMode {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
var rule = TruleskActivityRule(PassListActivity::class.java, false) {
|
var rule = TruleskActivityRule(PassListActivity::class.java, false) {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
val currentPass = TestApp.passStore().currentPass as PassImpl
|
val currentPass = TestApp.passStore.currentPass as PassImpl
|
||||||
currentPass.calendarTimespan = PassImpl.TimeSpan(ZonedDateTime.of(2016, 11, 23, 20, 42, 42, 5, ZoneId.systemDefault()))
|
currentPass.calendarTimespan = PassImpl.TimeSpan(ZonedDateTime.of(2016, 11, 23, 20, 42, 42, 5, ZoneId.systemDefault()))
|
||||||
currentPass.fields = mutableListOf(PassField("textprobe", "bar", "yo", false))
|
currentPass.fields = mutableListOf(PassField("textprobe", "bar", "yo", false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDateShowsForCondensedOff() {
|
fun testDateShowsForCondensedOff() {
|
||||||
`when`(TestApp.settings().isCondensedModeEnabled()).thenReturn(false)
|
`when`(TestApp.settings.isCondensedModeEnabled()).thenReturn(false)
|
||||||
|
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class TheCondensedPassViewMode {
|
||||||
@Test
|
@Test
|
||||||
fun testFieldShowsForCondensedOn() {
|
fun testFieldShowsForCondensedOn() {
|
||||||
|
|
||||||
`when`(TestApp.settings().isCondensedModeEnabled()).thenReturn(true)
|
`when`(TestApp.settings.isCondensedModeEnabled()).thenReturn(true)
|
||||||
|
|
||||||
rule.launchActivity()
|
rule.launchActivity()
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class TheFieldListEditFragment {
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val rule = TruleskIntentRule(PassEditActivity::class.java) {
|
val rule = TruleskIntentRule(PassEditActivity::class.java) {
|
||||||
TestApp.passStore().currentPass = PassImpl(UUID.randomUUID().toString()).apply {
|
TestApp.passStore.currentPass = PassImpl(UUID.randomUUID().toString()).apply {
|
||||||
fields = arrayListOf(field)
|
fields = arrayListOf(field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ package org.ligi.passandroid
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.widget.ImageView
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
import android.widget.ImageView
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
@ -68,7 +68,7 @@ class TheFullscreenBarcodeActivity {
|
||||||
val pass = PassImpl(UUID.randomUUID().toString())
|
val pass = PassImpl(UUID.randomUUID().toString())
|
||||||
pass.barCode = BarCode(format, BARCODE_MESSAGE)
|
pass.barCode = BarCode(format, BARCODE_MESSAGE)
|
||||||
|
|
||||||
TestApp.passStore().currentPass = pass
|
TestApp.passStore.currentPass = pass
|
||||||
|
|
||||||
rule.launchActivity(null)
|
rule.launchActivity(null)
|
||||||
onView(withId(R.id.fullscreen_barcode)).check(matches(isDisplayed()))
|
onView(withId(R.id.fullscreen_barcode)).check(matches(isDisplayed()))
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.ligi.trulesk.TruleskIntentRule
|
||||||
@TargetApi(14)
|
@TargetApi(14)
|
||||||
class ThePassEditActivity {
|
class ThePassEditActivity {
|
||||||
|
|
||||||
val passStore = TestApp.passStore()
|
val passStore = TestApp.passStore
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
var rule = TruleskIntentRule(PassEditActivity::class.java) {
|
var rule = TruleskIntentRule(PassEditActivity::class.java) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import androidx.test.espresso.matcher.ViewMatchers.*
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.ligi.passandroid.App.Companion.passStore
|
|
||||||
import org.ligi.passandroid.ui.PassListActivity
|
import org.ligi.passandroid.ui.PassListActivity
|
||||||
import org.ligi.passandroid.ui.PassListFragment
|
import org.ligi.passandroid.ui.PassListFragment
|
||||||
import org.ligi.trulesk.TruleskIntentRule
|
import org.ligi.trulesk.TruleskIntentRule
|
||||||
|
@ -29,7 +28,7 @@ class ThePassListSwiping {
|
||||||
|
|
||||||
onView(withText(R.string.topic_trash)).perform(click())
|
onView(withText(R.string.topic_trash)).perform(click())
|
||||||
|
|
||||||
assertThat(passStore.classifier.getTopics()).containsExactly(rule.activity.getString(R.string.topic_trash))
|
assertThat(TestApp.passStore.classifier.getTopics()).containsExactly(rule.activity.getString(R.string.topic_trash))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ class ThePassListSwiping {
|
||||||
|
|
||||||
onView(withText(R.string.topic_archive)).perform(click())
|
onView(withText(R.string.topic_archive)).perform(click())
|
||||||
|
|
||||||
assertThat(passStore.classifier.getTopics()).containsExactly(rule.activity.getString(R.string.topic_archive))
|
assertThat(TestApp.passStore.classifier.getTopics()).containsExactly(rule.activity.getString(R.string.topic_archive))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -51,7 +50,7 @@ class ThePassListSwiping {
|
||||||
|
|
||||||
onView(withText(android.R.string.ok)).perform(click())
|
onView(withText(android.R.string.ok)).perform(click())
|
||||||
|
|
||||||
assertThat(passStore.classifier.getTopics()).containsExactly(CUSTOM_PROBE)
|
assertThat(TestApp.passStore.classifier.getTopics()).containsExactly(CUSTOM_PROBE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.*
|
||||||
@TargetApi(14)
|
@TargetApi(14)
|
||||||
class ThePassViewActivity {
|
class ThePassViewActivity {
|
||||||
|
|
||||||
private fun getActPass() = TestApp.passStore().currentPass as PassImpl
|
private fun getActPass() = TestApp.passStore.currentPass as PassImpl
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
var rule = TruleskActivityRule(PassViewActivity::class.java, false)
|
var rule = TruleskActivityRule(PassViewActivity::class.java, false)
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ThePassViewHolder {
|
||||||
|
|
||||||
private val currentPass by lazy {
|
private val currentPass by lazy {
|
||||||
TestApp.populatePassStoreWithSinglePass()
|
TestApp.populatePassStoreWithSinglePass()
|
||||||
App.passStore.currentPass as PassImpl
|
TestApp.passStore.currentPass as PassImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class TheUnzipPassController {
|
||||||
verify(failCallback).fail(any(String.class));
|
verify(failCallback).fail(any(String.class));
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
fail("should be able to load file");
|
fail("should be able to load file " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.ligi.passandroid.functions
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import org.assertj.core.api.Fail.fail
|
import org.assertj.core.api.Fail.fail
|
||||||
|
import org.ligi.passandroid.TestApp
|
||||||
import org.ligi.passandroid.model.InputStreamWithSource
|
import org.ligi.passandroid.model.InputStreamWithSource
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
import org.ligi.passandroid.model.pass.Pass
|
import org.ligi.passandroid.model.pass.Pass
|
||||||
|
@ -30,7 +31,7 @@ fun loadPassFromAsset(asset: String, callback: (pass: Pass?) -> Unit) {
|
||||||
object : UnzipPassController.SuccessCallback {
|
object : UnzipPassController.SuccessCallback {
|
||||||
override fun call(uuid: String) {
|
override fun call(uuid: String) {
|
||||||
callback.invoke(AppleStylePassReader.read(File(getTestTargetPath(instrumentation.targetContext), uuid), "en",
|
callback.invoke(AppleStylePassReader.read(File(getTestTargetPath(instrumentation.targetContext), uuid), "en",
|
||||||
instrumentation.targetContext))
|
instrumentation.targetContext,TestApp.tracker))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mock
|
mock
|
||||||
|
|
|
@ -2,10 +2,14 @@ package org.ligi.passandroid
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import com.github.salomonbrys.kodein.*
|
|
||||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.koin.android.ext.koin.androidContext
|
||||||
|
import org.koin.android.ext.koin.androidLogger
|
||||||
|
import org.koin.core.context.startKoin
|
||||||
|
import org.koin.core.module.Module
|
||||||
|
import org.koin.dsl.module
|
||||||
import org.ligi.passandroid.json_adapter.ColorAdapter
|
import org.ligi.passandroid.json_adapter.ColorAdapter
|
||||||
import org.ligi.passandroid.json_adapter.ZonedTimeAdapter
|
import org.ligi.passandroid.json_adapter.ZonedTimeAdapter
|
||||||
import org.ligi.passandroid.model.AndroidFileSystemPassStore
|
import org.ligi.passandroid.model.AndroidFileSystemPassStore
|
||||||
|
@ -17,43 +21,43 @@ import org.ligi.tracedroid.logging.Log
|
||||||
|
|
||||||
open class App : Application() {
|
open class App : Application() {
|
||||||
|
|
||||||
|
private val moshi = Moshi.Builder()
|
||||||
|
.add(ZonedTimeAdapter())
|
||||||
|
.add(ColorAdapter())
|
||||||
|
.build()
|
||||||
|
|
||||||
|
private val settings by lazy { AndroidSettings(this) }
|
||||||
|
|
||||||
|
open fun createKoin(): Module {
|
||||||
|
|
||||||
|
return module {
|
||||||
|
single { AndroidFileSystemPassStore(this@App, get(), moshi, get()) as PassStore }
|
||||||
|
single { settings as Settings }
|
||||||
|
single { EventBus.getDefault() }
|
||||||
|
single { createTracker(this@App) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
kodein = Kodein {
|
startKoin {
|
||||||
import(createTrackerKodeinModule(this@App))
|
if (BuildConfig.DEBUG) androidLogger()
|
||||||
import(createKodein(), allowOverride = true)
|
androidContext(this@App)
|
||||||
|
modules(createKoin())
|
||||||
}
|
}
|
||||||
|
|
||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||||
AndroidThreeTen.init(this)
|
AndroidThreeTen.init(this)
|
||||||
initTraceDroid()
|
initTraceDroid()
|
||||||
|
|
||||||
val settings: Settings = kodein.instance()
|
|
||||||
AppCompatDelegate.setDefaultNightMode(settings.getNightMode())
|
AppCompatDelegate.setDefaultNightMode(settings.getNightMode())
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun createKodein() = Kodein.Module {
|
|
||||||
val moshi = Moshi.Builder()
|
|
||||||
.add(ZonedTimeAdapter())
|
|
||||||
.add(ColorAdapter())
|
|
||||||
.build()
|
|
||||||
|
|
||||||
|
|
||||||
bind<PassStore>() with singleton { AndroidFileSystemPassStore(this@App, instance(), moshi, instance()) }
|
|
||||||
bind<Settings>() with singleton { AndroidSettings(this@App) }
|
|
||||||
bind<EventBus>() with singleton { EventBus.getDefault() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initTraceDroid() {
|
private fun initTraceDroid() {
|
||||||
TraceDroid.init(this)
|
TraceDroid.init(this)
|
||||||
Log.setTAG("PassAndroid")
|
Log.setTAG("PassAndroid")
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
lateinit var kodein: Kodein
|
|
||||||
val tracker by lazy { kodein.Instance(TT(Tracker::class.java)) }
|
|
||||||
val passStore by lazy { kodein.Instance(TT(PassStore::class.java)) }
|
|
||||||
val settings by lazy { kodein.Instance(TT(Settings::class.java)) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,31 +4,31 @@ import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.ligi.passandroid.App
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.model.InputStreamWithSource
|
import org.ligi.passandroid.model.InputStreamWithSource
|
||||||
import java.io.BufferedInputStream
|
import java.io.BufferedInputStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
const val IPHONE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
|
const val IPHONE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
|
||||||
|
|
||||||
fun fromURI(context: Context, uri: Uri): InputStreamWithSource? {
|
fun fromURI(context: Context, uri: Uri, tracker: Tracker): InputStreamWithSource? {
|
||||||
App.tracker.trackEvent("protocol", "to_inputstream", uri.scheme, null)
|
tracker.trackEvent("protocol", "to_inputstream", uri.scheme, null)
|
||||||
return when (uri.scheme) {
|
return when (uri.scheme) {
|
||||||
"content" -> fromContent(context, uri)
|
"content" -> fromContent(context, uri)
|
||||||
|
|
||||||
"http", "https" ->
|
"http", "https" ->
|
||||||
// TODO check if SPDY should be here
|
// TODO check if SPDY should be here
|
||||||
return fromOKHttp(uri)
|
return fromOKHttp(uri, tracker)
|
||||||
|
|
||||||
"file" -> getDefaultInputStreamForUri(uri)
|
"file" -> getDefaultInputStreamForUri(uri)
|
||||||
else -> {
|
else -> {
|
||||||
App.tracker.trackException("unknown scheme in ImportAsyncTask" + uri.scheme, false)
|
tracker.trackException("unknown scheme in ImportAsyncTask" + uri.scheme, false)
|
||||||
getDefaultInputStreamForUri(uri)
|
getDefaultInputStreamForUri(uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fromOKHttp(uri: Uri): InputStreamWithSource? {
|
private fun fromOKHttp(uri: Uri, tracker: Tracker): InputStreamWithSource? {
|
||||||
val client = OkHttpClient()
|
val client = OkHttpClient()
|
||||||
val url = URL(uri.toString())
|
val url = URL(uri.toString())
|
||||||
val requestBuilder = Request.Builder().url(url)
|
val requestBuilder = Request.Builder().url(url)
|
||||||
|
@ -47,7 +47,7 @@ private fun fromOKHttp(uri: Uri): InputStreamWithSource? {
|
||||||
|
|
||||||
for ((key, value) in iPhoneFakeMap) {
|
for ((key, value) in iPhoneFakeMap) {
|
||||||
if (uri.toString().contains(value)) {
|
if (uri.toString().contains(value)) {
|
||||||
App.tracker.trackEvent("quirk_fix", "ua_fake", key, null)
|
tracker.trackEvent("quirk_fix", "ua_fake", key, null)
|
||||||
requestBuilder.header("User-Agent", IPHONE_USER_AGENT)
|
requestBuilder.header("User-Agent", IPHONE_USER_AGENT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,10 @@ import okio.buffer
|
||||||
import okio.sink
|
import okio.sink
|
||||||
import okio.source
|
import okio.source
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.ligi.passandroid.App
|
import org.koin.core.KoinComponent
|
||||||
|
import org.koin.core.inject
|
||||||
import org.ligi.passandroid.BuildConfig
|
import org.ligi.passandroid.BuildConfig
|
||||||
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.events.PassStoreChangeEvent
|
import org.ligi.passandroid.events.PassStoreChangeEvent
|
||||||
import org.ligi.passandroid.model.pass.Pass
|
import org.ligi.passandroid.model.pass.Pass
|
||||||
import org.ligi.passandroid.model.pass.PassImpl
|
import org.ligi.passandroid.model.pass.PassImpl
|
||||||
|
@ -17,13 +19,19 @@ import org.ligi.passandroid.reader.PassReader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AndroidFileSystemPassStore(private val context: Context, settings: Settings, private val moshi: Moshi, private val bus: EventBus) : PassStore {
|
class AndroidFileSystemPassStore(
|
||||||
|
private val context: Context, settings: Settings,
|
||||||
|
private val moshi: Moshi,
|
||||||
|
private val bus: EventBus
|
||||||
|
) : PassStore, KoinComponent {
|
||||||
private val path: File = settings.getPassesDir()
|
private val path: File = settings.getPassesDir()
|
||||||
|
|
||||||
override val passMap = HashMap<String, Pass>()
|
override val passMap = HashMap<String, Pass>()
|
||||||
|
|
||||||
override var currentPass: Pass? = null
|
override var currentPass: Pass? = null
|
||||||
|
|
||||||
|
private val tracker: Tracker by inject ()
|
||||||
|
|
||||||
override val classifier: PassClassifier by lazy {
|
override val classifier: PassClassifier by lazy {
|
||||||
val classificationFile = File(settings.getStateDir(), "classifier_state.json")
|
val classificationFile = File(settings.getStateDir(), "classifier_state.json")
|
||||||
FileBackedPassClassifier(classificationFile, this, moshi)
|
FileBackedPassClassifier(classificationFile, this, moshi)
|
||||||
|
@ -71,7 +79,7 @@ class AndroidFileSystemPassStore(private val context: Context, settings: Setting
|
||||||
try {
|
try {
|
||||||
result = jsonAdapter.fromJson(file.source().buffer())
|
result = jsonAdapter.fromJson(file.source().buffer())
|
||||||
} catch (ignored: JsonDataException) {
|
} catch (ignored: JsonDataException) {
|
||||||
App.tracker.trackException("invalid main.json", false)
|
tracker.trackException("invalid main.json", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +89,7 @@ class AndroidFileSystemPassStore(private val context: Context, settings: Setting
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null && File(pathForID, "pass.json").exists()) {
|
if (result == null && File(pathForID, "pass.json").exists()) {
|
||||||
result = AppleStylePassReader.read(pathForID, language, context)
|
result = AppleStylePassReader.read(pathForID, language, context, tracker)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import org.ligi.passandroid.App;
|
|
||||||
|
|
||||||
public class AppleStylePassTranslation extends HashMap<String, String> {
|
public class AppleStylePassTranslation extends HashMap<String, String> {
|
||||||
|
|
||||||
|
@ -74,7 +73,6 @@ public class AppleStylePassTranslation extends HashMap<String, String> {
|
||||||
}
|
}
|
||||||
return new String(fileData);
|
return new String(fileData);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
App.Companion.getTracker().trackException("problem_reading_translation", e, false);
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,21 @@ package org.ligi.passandroid.model.pass
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import com.github.salomonbrys.kodein.instance
|
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import org.ligi.passandroid.App
|
import org.koin.core.KoinComponent
|
||||||
|
import org.koin.core.inject
|
||||||
import org.ligi.passandroid.Tracker
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.functions.generateBitmapDrawable
|
import org.ligi.passandroid.functions.generateBitmapDrawable
|
||||||
import org.ligi.tracedroid.logging.Log
|
import org.ligi.tracedroid.logging.Log
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
class BarCode(val format: PassBarCodeFormat?, val message: String? = UUID.randomUUID().toString().toUpperCase()) {
|
class BarCode(val format: PassBarCodeFormat?, val message: String? = UUID.randomUUID().toString().toUpperCase()) : KoinComponent {
|
||||||
|
|
||||||
|
val tracker: Tracker by inject ()
|
||||||
var alternativeText: String? = null
|
var alternativeText: String? = null
|
||||||
|
|
||||||
fun getBitmap(resources: Resources): BitmapDrawable? {
|
fun getBitmap(resources: Resources): BitmapDrawable? {
|
||||||
val tracker: Tracker = App.kodein.instance()
|
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
// no message -> no barcode
|
// no message -> no barcode
|
||||||
tracker.trackException("No Barcode in pass - strange", false)
|
tracker.trackException("No Barcode in pass - strange", false)
|
||||||
|
|
|
@ -7,8 +7,8 @@ import android.graphics.Color
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.ligi.kaxt.parseColor
|
import org.ligi.kaxt.parseColor
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.functions.getHumanCategoryString
|
import org.ligi.passandroid.functions.getHumanCategoryString
|
||||||
import org.ligi.passandroid.functions.readJSONSafely
|
import org.ligi.passandroid.functions.readJSONSafely
|
||||||
import org.ligi.passandroid.model.ApplePassbookQuirkCorrector
|
import org.ligi.passandroid.model.ApplePassbookQuirkCorrector
|
||||||
|
@ -26,7 +26,7 @@ import java.util.*
|
||||||
|
|
||||||
object AppleStylePassReader {
|
object AppleStylePassReader {
|
||||||
|
|
||||||
fun read(passFile: File, language: String, context: Context): Pass? {
|
fun read(passFile: File, language: String, context: Context, tracker: Tracker): Pass? {
|
||||||
|
|
||||||
val translation = AppleStylePassTranslation()
|
val translation = AppleStylePassTranslation()
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ object AppleStylePassReader {
|
||||||
|
|
||||||
var passJSON: JSONObject? = null
|
var passJSON: JSONObject? = null
|
||||||
|
|
||||||
val localizedPath = findLocalizedPath(passFile, language)
|
val localizedPath = findLocalizedPath(passFile, language, tracker)
|
||||||
|
|
||||||
if (localizedPath != null) {
|
if (localizedPath != null) {
|
||||||
val file = File(localizedPath, "pass.strings")
|
val file = File(localizedPath, "pass.strings")
|
||||||
|
@ -77,7 +77,7 @@ object AppleStylePassReader {
|
||||||
|
|
||||||
if (passJSON == null) {
|
if (passJSON == null) {
|
||||||
Log.w("could not load pass.json from passcode ")
|
Log.w("could not load pass.json from passcode ")
|
||||||
App.tracker.trackEvent("problem_event", "pass", "without_pass_json", null)
|
tracker.trackEvent("problem_event", "pass", "without_pass_json", null)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ object AppleStylePassReader {
|
||||||
if (barcodeJSON != null) {
|
if (barcodeJSON != null) {
|
||||||
val barcodeFormatString = barcodeJSON.getString("format")
|
val barcodeFormatString = barcodeJSON.getString("format")
|
||||||
|
|
||||||
App.tracker.trackEvent("measure_event", "barcode_format", barcodeFormatString, 0L)
|
tracker.trackEvent("measure_event", "barcode_format", barcodeFormatString, 0L)
|
||||||
val barcodeFormat = BarCode.getFormatFromString(barcodeFormatString)
|
val barcodeFormat = BarCode.getFormatFromString(barcodeFormatString)
|
||||||
val barCode = BarCode(barcodeFormat, barcodeJSON.getString("message"))
|
val barCode = BarCode(barcodeFormat, barcodeJSON.getString("message"))
|
||||||
pass.barCode = barCode
|
pass.barCode = barCode
|
||||||
|
@ -105,9 +105,9 @@ object AppleStylePassReader {
|
||||||
} catch (e: JSONException) {
|
} catch (e: JSONException) {
|
||||||
// be robust when it comes to bad dates - had a RL crash with "2013-12-25T00:00-57:00" here
|
// be robust when it comes to bad dates - had a RL crash with "2013-12-25T00:00-57:00" here
|
||||||
// OK then we just have no date here
|
// OK then we just have no date here
|
||||||
App.tracker.trackException("problem parsing relevant date", e, false)
|
tracker.trackException("problem parsing relevant date", e, false)
|
||||||
} catch (e: DateTimeException) {
|
} catch (e: DateTimeException) {
|
||||||
App.tracker.trackException("problem parsing relevant date", e, false)
|
tracker.trackException("problem parsing relevant date", e, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -118,9 +118,9 @@ object AppleStylePassReader {
|
||||||
} catch (e: JSONException) {
|
} catch (e: JSONException) {
|
||||||
// be robust when it comes to bad dates - had a RL crash with "2013-12-25T00:00-57:00" here
|
// be robust when it comes to bad dates - had a RL crash with "2013-12-25T00:00-57:00" here
|
||||||
// OK then we just have no date here
|
// OK then we just have no date here
|
||||||
App.tracker.trackException("problem parsing expiration date", e, false)
|
tracker.trackException("problem parsing expiration date", e, false)
|
||||||
} catch (e: DateTimeException) {
|
} catch (e: DateTimeException) {
|
||||||
App.tracker.trackException("problem parsing expiration date", e, false)
|
tracker.trackException("problem parsing expiration date", e, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -196,12 +196,12 @@ object AppleStylePassReader {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pass.creator = passJSON.getString("organizationName")
|
pass.creator = passJSON.getString("organizationName")
|
||||||
App.tracker.trackEvent("measure_event", "organisation_parse", pass.creator, 1L)
|
tracker.trackEvent("measure_event", "organisation_parse", pass.creator, 1L)
|
||||||
} catch (ignored: JSONException) {
|
} catch (ignored: JSONException) {
|
||||||
// ok - we have no organisation - big deal ..-)
|
// ok - we have no organisation - big deal ..-)
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplePassbookQuirkCorrector(App.tracker).correctQuirks(pass)
|
ApplePassbookQuirkCorrector(tracker).correctQuirks(pass)
|
||||||
|
|
||||||
return pass
|
return pass
|
||||||
}
|
}
|
||||||
|
@ -240,18 +240,18 @@ object AppleStylePassReader {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findLocalizedPath(path: File, language: String): String? {
|
private fun findLocalizedPath(path: File, language: String, tracker: Tracker): String? {
|
||||||
val localized = File(path, "$language.lproj")
|
val localized = File(path, "$language.lproj")
|
||||||
|
|
||||||
if (localized.exists() && localized.isDirectory) {
|
if (localized.exists() && localized.isDirectory) {
|
||||||
App.tracker.trackEvent("measure_event", "pass", language + "_native_lproj", null)
|
tracker.trackEvent("measure_event", "pass", language + "_native_lproj", null)
|
||||||
return localized.path
|
return localized.path
|
||||||
}
|
}
|
||||||
|
|
||||||
val fallback = File(path, "en.lproj")
|
val fallback = File(path, "en.lproj")
|
||||||
|
|
||||||
if (fallback.exists() && fallback.isDirectory) {
|
if (fallback.exists() && fallback.isDirectory) {
|
||||||
App.tracker.trackEvent("measure_event", "pass", "en_lproj", null)
|
tracker.trackEvent("measure_event", "pass", "en_lproj", null)
|
||||||
return fallback.path
|
return fallback.path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
package org.ligi.passandroid.ui
|
package org.ligi.passandroid.ui
|
||||||
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.cardview.widget.CardView
|
import androidx.cardview.widget.CardView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import android.view.LayoutInflater
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import android.view.ViewGroup
|
import org.koin.core.KoinComponent
|
||||||
import com.github.salomonbrys.kodein.instance
|
import org.koin.core.inject
|
||||||
import org.ligi.kaxt.startActivityFromClass
|
import org.ligi.kaxt.startActivityFromClass
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
import org.ligi.passandroid.model.PassStoreProjection
|
import org.ligi.passandroid.model.PassStoreProjection
|
||||||
|
@ -17,10 +17,13 @@ import org.ligi.passandroid.ui.pass_view_holder.CondensedPassViewHolder
|
||||||
import org.ligi.passandroid.ui.pass_view_holder.PassViewHolder
|
import org.ligi.passandroid.ui.pass_view_holder.PassViewHolder
|
||||||
import org.ligi.passandroid.ui.pass_view_holder.VerbosePassViewHolder
|
import org.ligi.passandroid.ui.pass_view_holder.VerbosePassViewHolder
|
||||||
|
|
||||||
class PassAdapter(private val passListActivity: AppCompatActivity, private val passStoreProjection: PassStoreProjection) : RecyclerView.Adapter<PassViewHolder>() {
|
class PassAdapter(
|
||||||
|
private val passListActivity: AppCompatActivity,
|
||||||
|
private val passStoreProjection: PassStoreProjection
|
||||||
|
) : RecyclerView.Adapter<PassViewHolder>(), KoinComponent {
|
||||||
|
|
||||||
val passStore: PassStore = App.kodein.instance()
|
private val passStore: PassStore by inject ()
|
||||||
val settings: Settings = App.kodein.instance()
|
private val settings: Settings by inject ()
|
||||||
|
|
||||||
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): PassViewHolder {
|
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): PassViewHolder {
|
||||||
val inflater = LayoutInflater.from(viewGroup.context)
|
val inflater = LayoutInflater.from(viewGroup.context)
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
package org.ligi.passandroid.ui
|
package org.ligi.passandroid.ui
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.github.salomonbrys.kodein.instance
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.ligi.passandroid.App
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.passandroid.Tracker
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
import org.ligi.passandroid.model.Settings
|
import org.ligi.passandroid.model.Settings
|
||||||
|
|
||||||
open class PassAndroidActivity : AppCompatActivity() {
|
open class PassAndroidActivity : AppCompatActivity() {
|
||||||
|
|
||||||
val passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore by inject()
|
||||||
val settings: Settings = App.kodein.instance()
|
val settings: Settings by inject()
|
||||||
val bus: EventBus = App.kodein.instance()
|
val bus: EventBus by inject()
|
||||||
val tracker: Tracker = App.kodein.instance()
|
val tracker: Tracker by inject()
|
||||||
|
|
||||||
private var lastSetNightMode: Int? = null
|
private var lastSetNightMode: Int? = null
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,18 @@ package org.ligi.passandroid.ui
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.annotation.IdRes
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import com.github.salomonbrys.kodein.instance
|
import androidx.annotation.IdRes
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import kotlinx.android.synthetic.main.edit.*
|
import kotlinx.android.synthetic.main.edit.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.kaxt.doAfterEdit
|
import org.ligi.kaxt.doAfterEdit
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.events.PassRefreshEvent
|
import org.ligi.passandroid.events.PassRefreshEvent
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
|
@ -39,8 +38,8 @@ class PassEditActivity : AppCompatActivity() {
|
||||||
private lateinit var currentPass: PassImpl
|
private lateinit var currentPass: PassImpl
|
||||||
private val imageEditHelper by lazy { ImageEditHelper(this, passStore) }
|
private val imageEditHelper by lazy { ImageEditHelper(this, passStore) }
|
||||||
|
|
||||||
internal val passStore: PassStore = App.kodein.instance()
|
internal val passStore: PassStore by inject()
|
||||||
internal val bus: EventBus = App.kodein.instance()
|
internal val bus: EventBus by inject()
|
||||||
|
|
||||||
private val passViewHelper: PassViewHelper by lazy { PassViewHelper(this) }
|
private val passViewHelper: PassViewHelper by lazy { PassViewHelper(this) }
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,21 @@ import android.app.Activity
|
||||||
import android.app.ProgressDialog
|
import android.app.ProgressDialog
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.annotation.UiThread
|
import androidx.annotation.UiThread
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import android.widget.Toast
|
import org.koin.core.KoinComponent
|
||||||
import org.ligi.passandroid.App
|
import org.koin.core.inject
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
|
import org.ligi.passandroid.Tracker
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal open class PassExportTaskAndShare(protected val activity: Activity, private val inputPath: File) {
|
internal open class PassExportTaskAndShare(
|
||||||
|
protected val activity: Activity,
|
||||||
|
private val inputPath: File
|
||||||
|
) : KoinComponent {
|
||||||
|
|
||||||
|
val tracker: Tracker by inject()
|
||||||
@UiThread
|
@UiThread
|
||||||
fun execute() {
|
fun execute() {
|
||||||
val file = File(activity.filesDir, "share/share.espass") // important - the FileProvider must be configured for this path
|
val file = File(activity.filesDir, "share/share.espass") // important - the FileProvider must be configured for this path
|
||||||
|
@ -31,7 +37,7 @@ internal open class PassExportTaskAndShare(protected val activity: Activity, pri
|
||||||
}
|
}
|
||||||
|
|
||||||
if (passExporter.exception != null) {
|
if (passExporter.exception != null) {
|
||||||
App.tracker.trackException("passExporterException", passExporter.exception!!, false)
|
tracker.trackException("passExporterException", passExporter.exception!!, false)
|
||||||
Toast.makeText(activity, "could not export pass: " + passExporter.exception, Toast.LENGTH_LONG).show()
|
Toast.makeText(activity, "could not export pass: " + passExporter.exception, Toast.LENGTH_LONG).show()
|
||||||
} else {
|
} else {
|
||||||
val uriForFile = FileProvider.getUriForFile(activity, activity.getString(R.string.authority_fileprovider), file)
|
val uriForFile = FileProvider.getUriForFile(activity, activity.getString(R.string.authority_fileprovider), file)
|
||||||
|
|
|
@ -4,14 +4,16 @@ import net.lingala.zip4j.ZipFile
|
||||||
import net.lingala.zip4j.model.ZipParameters
|
import net.lingala.zip4j.model.ZipParameters
|
||||||
import net.lingala.zip4j.model.enums.CompressionLevel
|
import net.lingala.zip4j.model.enums.CompressionLevel
|
||||||
import net.lingala.zip4j.model.enums.CompressionMethod
|
import net.lingala.zip4j.model.enums.CompressionMethod
|
||||||
|
import org.koin.core.KoinComponent
|
||||||
import org.ligi.passandroid.App
|
import org.koin.core.inject
|
||||||
|
import org.ligi.passandroid.Tracker
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class PassExporter(private val inputPath: File, val file: File) {
|
class PassExporter(private val inputPath: File, val file: File) : KoinComponent {
|
||||||
var exception: Exception? = null
|
var exception: Exception? = null
|
||||||
|
|
||||||
|
val tracker: Tracker by inject()
|
||||||
|
|
||||||
fun export() {
|
fun export() {
|
||||||
try {
|
try {
|
||||||
file.delete()
|
file.delete()
|
||||||
|
@ -28,7 +30,7 @@ class PassExporter(private val inputPath: File, val file: File) {
|
||||||
|
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
exception.printStackTrace()
|
exception.printStackTrace()
|
||||||
App.tracker.trackException("when exporting pass to zip", exception, false)
|
tracker.trackException("when exporting pass to zip", exception, false)
|
||||||
this.exception = exception // we need to take action on the main thread later
|
this.exception = exception // we need to take action on the main thread later
|
||||||
file.delete() // prevent zombies from taking over
|
file.delete() // prevent zombies from taking over
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,13 @@ import android.os.Bundle
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.github.salomonbrys.kodein.instance
|
|
||||||
import kotlinx.android.synthetic.main.activity_import.*
|
import kotlinx.android.synthetic.main.activity_import.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.kaxt.startActivityFromClass
|
import org.ligi.kaxt.startActivityFromClass
|
||||||
import org.ligi.kaxtui.alert
|
import org.ligi.kaxtui.alert
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.Tracker
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.functions.fromURI
|
import org.ligi.passandroid.functions.fromURI
|
||||||
|
@ -25,8 +24,8 @@ import permissions.dispatcher.RuntimePermissions
|
||||||
@RuntimePermissions
|
@RuntimePermissions
|
||||||
class PassImportActivity : AppCompatActivity() {
|
class PassImportActivity : AppCompatActivity() {
|
||||||
|
|
||||||
val tracker: Tracker = App.kodein.instance()
|
val tracker: Tracker by inject()
|
||||||
val passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore by inject()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -51,7 +50,7 @@ class PassImportActivity : AppCompatActivity() {
|
||||||
fun doImport(withPermission: Boolean) {
|
fun doImport(withPermission: Boolean) {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val fromURI = fromURI(this@PassImportActivity, intent!!.data!!)
|
val fromURI = fromURI(this@PassImportActivity, intent!!.data!!, tracker)
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
package org.ligi.passandroid.ui
|
package org.ligi.passandroid.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.annotation.VisibleForTesting
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper.*
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.github.salomonbrys.kodein.instance
|
import androidx.annotation.VisibleForTesting
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper.*
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
import kotlinx.android.synthetic.main.pass_recycler.view.*
|
import kotlinx.android.synthetic.main.pass_recycler.view.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.ligi.passandroid.App
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.events.PassStoreChangeEvent
|
import org.ligi.passandroid.events.PassStoreChangeEvent
|
||||||
import org.ligi.passandroid.events.ScanFinishedEvent
|
import org.ligi.passandroid.events.ScanFinishedEvent
|
||||||
|
@ -32,9 +31,9 @@ class PassListFragment : Fragment() {
|
||||||
private lateinit var passStoreProjection: PassStoreProjection
|
private lateinit var passStoreProjection: PassStoreProjection
|
||||||
private lateinit var adapter: PassAdapter
|
private lateinit var adapter: PassAdapter
|
||||||
|
|
||||||
val passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore by inject()
|
||||||
val settings: Settings = App.kodein.instance()
|
val settings: Settings by inject()
|
||||||
val bus: EventBus = App.kodein.instance()
|
val bus: EventBus by inject()
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val inflate = inflater.inflate(R.layout.pass_recycler, container, false)
|
val inflate = inflater.inflate(R.layout.pass_recycler, container, false)
|
||||||
|
|
|
@ -2,14 +2,14 @@ package org.ligi.passandroid.ui
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.app.NavUtils
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import com.github.salomonbrys.kodein.instance
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.app.NavUtils
|
||||||
import kotlinx.android.synthetic.main.delete_dialog_layout.view.*
|
import kotlinx.android.synthetic.main.delete_dialog_layout.view.*
|
||||||
|
import org.koin.core.KoinComponent
|
||||||
|
import org.koin.core.inject
|
||||||
import org.ligi.kaxt.startActivityFromClass
|
import org.ligi.kaxt.startActivityFromClass
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.Tracker
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.maps.PassbookMapsFacade
|
import org.ligi.passandroid.maps.PassbookMapsFacade
|
||||||
|
@ -19,11 +19,11 @@ import org.ligi.passandroid.model.pass.Pass
|
||||||
import org.ligi.passandroid.printing.doPrint
|
import org.ligi.passandroid.printing.doPrint
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class PassMenuOptions(val activity: Activity, val pass: Pass) {
|
class PassMenuOptions(val activity: Activity, val pass: Pass) : KoinComponent {
|
||||||
|
|
||||||
var passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore by inject()
|
||||||
var tracker: Tracker = App.kodein.instance()
|
val tracker: Tracker by inject()
|
||||||
var settings: Settings = App.kodein.instance()
|
val settings: Settings by inject()
|
||||||
|
|
||||||
fun process(item: MenuItem): Boolean {
|
fun process(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
|
|
|
@ -4,22 +4,22 @@ import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.google.android.material.navigation.NavigationView
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import com.github.salomonbrys.kodein.instance
|
import com.google.android.material.navigation.NavigationView
|
||||||
import kotlinx.android.synthetic.main.navigation_drawer_header.view.*
|
import kotlinx.android.synthetic.main.navigation_drawer_header.view.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.ligi.passandroid.App
|
import org.koin.core.KoinComponent
|
||||||
|
import org.koin.core.inject
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.events.PassStoreChangeEvent
|
import org.ligi.passandroid.events.PassStoreChangeEvent
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
|
|
||||||
class PassNavigationView(context: Context, attrs: AttributeSet) : NavigationView(context, attrs) {
|
class PassNavigationView(context: Context, attrs: AttributeSet) : NavigationView(context, attrs), KoinComponent {
|
||||||
|
|
||||||
val passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore by inject()
|
||||||
val bus: EventBus = App.kodein.instance()
|
val bus: EventBus by inject()
|
||||||
|
|
||||||
private fun getIntent(id: Int) = when (id) {
|
private fun getIntent(id: Int) = when (id) {
|
||||||
R.id.menu_settings -> Intent(context, PreferenceActivity::class.java)
|
R.id.menu_settings -> Intent(context, PreferenceActivity::class.java)
|
||||||
|
|
|
@ -2,23 +2,22 @@ package org.ligi.passandroid.ui
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.core.text.util.LinkifyCompat
|
|
||||||
import android.text.util.Linkify
|
import android.text.util.Linkify
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.core.text.util.LinkifyCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import com.github.salomonbrys.kodein.instance
|
|
||||||
import kotlinx.android.synthetic.main.activity_pass_view.*
|
import kotlinx.android.synthetic.main.activity_pass_view.*
|
||||||
import kotlinx.android.synthetic.main.barcode.*
|
import kotlinx.android.synthetic.main.barcode.*
|
||||||
import kotlinx.android.synthetic.main.pass_list_item.*
|
import kotlinx.android.synthetic.main.pass_list_item.*
|
||||||
import kotlinx.android.synthetic.main.pass_view_extra_data.*
|
import kotlinx.android.synthetic.main.pass_view_extra_data.*
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.compat.HtmlCompat
|
import org.ligi.compat.HtmlCompat
|
||||||
import org.ligi.kaxt.startActivityFromClass
|
import org.ligi.kaxt.startActivityFromClass
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.maps.PassbookMapsFacade
|
import org.ligi.passandroid.maps.PassbookMapsFacade
|
||||||
import org.ligi.passandroid.model.PassBitmapDefinitions
|
import org.ligi.passandroid.model.PassBitmapDefinitions
|
||||||
|
@ -29,7 +28,7 @@ import org.ligi.passandroid.ui.pass_view_holder.VerbosePassViewHolder
|
||||||
class PassViewFragment : Fragment() {
|
class PassViewFragment : Fragment() {
|
||||||
|
|
||||||
private val passViewHelper by lazy { PassViewHelper(requireActivity()) }
|
private val passViewHelper by lazy { PassViewHelper(requireActivity()) }
|
||||||
private var passStore : PassStore = App.kodein.instance()
|
internal val passStore : PassStore by inject()
|
||||||
lateinit var pass : Pass
|
lateinit var pass : Pass
|
||||||
|
|
||||||
private fun processImage(view: ImageView, name: String, pass: Pass) {
|
private fun processImage(view: ImageView, name: String, pass: Pass) {
|
||||||
|
|
|
@ -6,14 +6,17 @@ import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO
|
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import org.ligi.passandroid.App
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
|
import org.ligi.passandroid.model.Settings
|
||||||
import permissions.dispatcher.NeedsPermission
|
import permissions.dispatcher.NeedsPermission
|
||||||
import permissions.dispatcher.RuntimePermissions
|
import permissions.dispatcher.RuntimePermissions
|
||||||
|
|
||||||
@RuntimePermissions
|
@RuntimePermissions
|
||||||
class PrefsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener {
|
class PrefsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
val settings : Settings by inject()
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||||
|
@ -26,7 +29,7 @@ class PrefsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPref
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||||
if (key == getString(R.string.preference_key_nightmode)) {
|
if (key == getString(R.string.preference_key_nightmode)) {
|
||||||
@AppCompatDelegate.NightMode val nightMode = App.settings.getNightMode()
|
@AppCompatDelegate.NightMode val nightMode = settings.getNightMode()
|
||||||
|
|
||||||
if (nightMode == MODE_NIGHT_AUTO) {
|
if (nightMode == MODE_NIGHT_AUTO) {
|
||||||
ensureDayNightWithPermissionCheck()
|
ensureDayNightWithPermissionCheck()
|
||||||
|
|
|
@ -11,9 +11,8 @@ import android.os.Build
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.github.salomonbrys.kodein.instance
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.ligi.passandroid.App
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
import org.ligi.passandroid.Tracker
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.events.ScanFinishedEvent
|
import org.ligi.passandroid.events.ScanFinishedEvent
|
||||||
|
@ -43,9 +42,9 @@ class SearchPassesIntentService : IntentService("SearchPassesIntentService") {
|
||||||
|
|
||||||
private var lastProgressUpdate: Long = 0
|
private var lastProgressUpdate: Long = 0
|
||||||
|
|
||||||
val passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore by inject()
|
||||||
val bus: EventBus = App.kodein.instance()
|
val bus: EventBus by inject()
|
||||||
val tracker: Tracker = App.kodein.instance()
|
val tracker: Tracker by inject()
|
||||||
|
|
||||||
override fun onHandleIntent(intent: Intent?) {
|
override fun onHandleIntent(intent: Intent?) {
|
||||||
|
|
||||||
|
@ -130,7 +129,7 @@ class SearchPassesIntentService : IntentService("SearchPassesIntentService") {
|
||||||
Log.i("found" + file.absolutePath)
|
Log.i("found" + file.absolutePath)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val ins = fromURI(baseContext, Uri.parse("file://" + file.absolutePath))
|
val ins = fromURI(baseContext, Uri.parse("file://" + file.absolutePath), tracker)
|
||||||
val onSuccessCallback = SearchSuccessCallback(baseContext,
|
val onSuccessCallback = SearchSuccessCallback(baseContext,
|
||||||
passStore,
|
passStore,
|
||||||
foundList,
|
foundList,
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
package org.ligi.passandroid.ui
|
package org.ligi.passandroid.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import com.github.salomonbrys.kodein.instance
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.ortiz.touch.TouchImageView
|
import com.ortiz.touch.TouchImageView
|
||||||
import org.ligi.passandroid.App
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
|
|
||||||
class TouchImageActivity : AppCompatActivity() {
|
class TouchImageActivity : AppCompatActivity() {
|
||||||
|
|
||||||
val passStore: PassStore = App.kodein.instance()
|
val passStore: PassStore by inject()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.ligi.passandroid.ui
|
package org.ligi.passandroid.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
|
import org.ligi.passandroid.model.Settings
|
||||||
import org.ligi.passandroid.ui.UnzipPassController.FailCallback
|
import org.ligi.passandroid.ui.UnzipPassController.FailCallback
|
||||||
import org.ligi.passandroid.ui.UnzipPassController.SuccessCallback
|
import org.ligi.passandroid.ui.UnzipPassController.SuccessCallback
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -14,7 +14,7 @@ open class UnzipControllerSpec(var targetPath: File,
|
||||||
val failCallback: FailCallback?) {
|
val failCallback: FailCallback?) {
|
||||||
var overwrite = false
|
var overwrite = false
|
||||||
|
|
||||||
constructor(context: Context, passStore: PassStore, onSuccessCallback: SuccessCallback?, failCallback: FailCallback?)
|
constructor(context: Context, passStore: PassStore, onSuccessCallback: SuccessCallback?, failCallback: FailCallback?, settings: Settings)
|
||||||
: this(App.settings.getPassesDir(), context, passStore, onSuccessCallback, failCallback)
|
: this(settings.getPassesDir(), context, passStore, onSuccessCallback, failCallback)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,18 +11,25 @@ import net.lingala.zip4j.exception.ZipException
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.source
|
import okio.source
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.ligi.passandroid.App
|
import org.koin.core.KoinComponent
|
||||||
|
import org.koin.core.inject
|
||||||
|
import org.ligi.passandroid.Tracker
|
||||||
import org.ligi.passandroid.functions.createPassForImageImport
|
import org.ligi.passandroid.functions.createPassForImageImport
|
||||||
import org.ligi.passandroid.functions.createPassForPDFImport
|
import org.ligi.passandroid.functions.createPassForPDFImport
|
||||||
import org.ligi.passandroid.functions.readJSONSafely
|
import org.ligi.passandroid.functions.readJSONSafely
|
||||||
|
import org.ligi.passandroid.model.AndroidSettings
|
||||||
import org.ligi.passandroid.model.InputStreamWithSource
|
import org.ligi.passandroid.model.InputStreamWithSource
|
||||||
import org.ligi.passandroid.model.PassStore
|
import org.ligi.passandroid.model.PassStore
|
||||||
|
import org.ligi.passandroid.model.Settings
|
||||||
import org.ligi.tracedroid.logging.Log
|
import org.ligi.tracedroid.logging.Log
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object UnzipPassController {
|
object UnzipPassController : KoinComponent {
|
||||||
|
|
||||||
|
val tracker :Tracker by inject()
|
||||||
|
val settings : Settings by inject()
|
||||||
|
|
||||||
interface SuccessCallback {
|
interface SuccessCallback {
|
||||||
fun call(uuid: String)
|
fun call(uuid: String)
|
||||||
|
@ -39,7 +46,7 @@ object UnzipPassController {
|
||||||
processFile(FileUnzipControllerSpec(tempFile.absolutePath, spec))
|
processFile(FileUnzipControllerSpec(tempFile.absolutePath, spec))
|
||||||
tempFile.delete()
|
tempFile.delete()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
App.tracker.trackException("problem processing InputStream", e, false)
|
tracker.trackException("problem processing InputStream", e, false)
|
||||||
spec.failCallback?.fail("problem with temp file: $e")
|
spec.failCallback?.fail("problem with temp file: $e")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +165,6 @@ object UnzipPassController {
|
||||||
}
|
}
|
||||||
|
|
||||||
class InputStreamUnzipControllerSpec(internal val inputStreamWithSource: InputStreamWithSource, context: Context, passStore: PassStore,
|
class InputStreamUnzipControllerSpec(internal val inputStreamWithSource: InputStreamWithSource, context: Context, passStore: PassStore,
|
||||||
onSuccessCallback: SuccessCallback?, failCallback: FailCallback?) : UnzipControllerSpec(context, passStore, onSuccessCallback, failCallback)
|
onSuccessCallback: SuccessCallback?, failCallback: FailCallback?) : UnzipControllerSpec(context, passStore, onSuccessCallback, failCallback, settings)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
package org.ligi.passandroid.ui.edit
|
package org.ligi.passandroid.ui.edit
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import kotlinx.android.synthetic.main.edit_field.view.*
|
import kotlinx.android.synthetic.main.edit_field.view.*
|
||||||
import kotlinx.android.synthetic.main.edit_fields.view.*
|
import kotlinx.android.synthetic.main.edit_fields.view.*
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.kaxt.doAfterEdit
|
import org.ligi.kaxt.doAfterEdit
|
||||||
import org.ligi.passandroid.App
|
|
||||||
import org.ligi.passandroid.R
|
import org.ligi.passandroid.R
|
||||||
|
import org.ligi.passandroid.model.PassStore
|
||||||
import org.ligi.passandroid.model.pass.PassField
|
import org.ligi.passandroid.model.pass.PassField
|
||||||
import org.ligi.passandroid.model.pass.PassImpl
|
import org.ligi.passandroid.model.pass.PassImpl
|
||||||
|
|
||||||
|
|
||||||
class FieldsEditFragment : Fragment() {
|
class FieldsEditFragment : Fragment() {
|
||||||
|
|
||||||
private fun getPass(): PassImpl = App.passStore.currentPass as PassImpl
|
val passStore by inject<PassStore>()
|
||||||
|
|
||||||
|
private fun getPass(): PassImpl = passStore.currentPass as PassImpl
|
||||||
|
|
||||||
private var isEditingHiddenFields: Boolean = false
|
private var isEditingHiddenFields: Boolean = false
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package org.ligi.passandroid
|
package org.ligi.passandroid
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.salomonbrys.kodein.Kodein
|
|
||||||
import com.github.salomonbrys.kodein.bind
|
|
||||||
import com.github.salomonbrys.kodein.singleton
|
|
||||||
|
|
||||||
fun createTrackerKodeinModule(context: Context) = Kodein.Module {
|
fun createTracker(context: Context) = NotTracker() as Tracker
|
||||||
bind<Tracker>() with singleton { NotTracker() }
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package org.ligi.passandroid
|
package org.ligi.passandroid
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.salomonbrys.kodein.Kodein
|
|
||||||
import com.github.salomonbrys.kodein.bind
|
|
||||||
import com.github.salomonbrys.kodein.singleton
|
|
||||||
|
|
||||||
fun createTrackerKodeinModule(context: Context) = Kodein.Module {
|
fun createTracker(context: Context) = AnalyticsTracker(context) as Tracker
|
||||||
bind<Tracker>() with singleton { AnalyticsTracker(context) }
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,12 +11,16 @@ import com.google.android.gms.maps.SupportMapFragment
|
||||||
import com.google.android.gms.maps.model.LatLng
|
import com.google.android.gms.maps.model.LatLng
|
||||||
import com.google.android.gms.maps.model.LatLngBounds
|
import com.google.android.gms.maps.model.LatLngBounds
|
||||||
import com.google.android.gms.maps.model.MarkerOptions
|
import com.google.android.gms.maps.model.MarkerOptions
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
import org.ligi.kaxt.startActivityFromClass
|
import org.ligi.kaxt.startActivityFromClass
|
||||||
|
import org.ligi.passandroid.model.PassStore
|
||||||
import org.ligi.passandroid.ui.PassViewActivityBase
|
import org.ligi.passandroid.ui.PassViewActivityBase
|
||||||
|
|
||||||
class LocationsMapFragment : SupportMapFragment() {
|
class LocationsMapFragment : SupportMapFragment() {
|
||||||
var clickToFullscreen = false
|
var clickToFullscreen = false
|
||||||
|
|
||||||
|
val passStore : PassStore by inject()
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val root = super.onCreateView(inflater, container, savedInstanceState)
|
val root = super.onCreateView(inflater, container, savedInstanceState)
|
||||||
val baseActivity = activity as PassViewActivityBase
|
val baseActivity = activity as PassViewActivityBase
|
||||||
|
@ -25,7 +29,7 @@ class LocationsMapFragment : SupportMapFragment() {
|
||||||
map.setOnMapLoadedCallback {
|
map.setOnMapLoadedCallback {
|
||||||
if (clickToFullscreen)
|
if (clickToFullscreen)
|
||||||
map.setOnMapClickListener {
|
map.setOnMapClickListener {
|
||||||
App.passStore.currentPass = baseActivity.currentPass
|
passStore.currentPass = baseActivity.currentPass
|
||||||
baseActivity.startActivityFromClass(FullscreenMapActivity::class.java)
|
baseActivity.startActivityFromClass(FullscreenMapActivity::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue