mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-11-08 12:02:33 +01:00
Update theme providers and readd koin modules
This commit is contained in:
parent
cb2adc75d8
commit
d96d1d06a7
@ -26,11 +26,6 @@ import com.pitchedapps.frost.utils.ARG_COOKIE
|
||||
import com.pitchedapps.frost.utils.ARG_IMAGE_URL
|
||||
import com.pitchedapps.frost.utils.ARG_TEXT
|
||||
import com.pitchedapps.frost.utils.isIndirectImageUrl
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
import okhttp3.internal.closeQuietly
|
||||
import okhttp3.mockwebserver.Dispatcher
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
@ -46,6 +41,11 @@ import org.junit.rules.RuleChain
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.rules.Timeout
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ImageActivityTest {
|
||||
|
@ -20,9 +20,9 @@ import android.content.Context
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.BeforeTest
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
abstract class BaseDbTest {
|
||||
|
@ -16,11 +16,11 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.db
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.fail
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class CacheDbTest : BaseDbTest() {
|
||||
|
||||
|
@ -16,10 +16,10 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.db
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class CookieDbTest : BaseDbTest() {
|
||||
|
||||
|
@ -21,8 +21,8 @@ import androidx.room.testing.MigrationTestHelper
|
||||
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import kotlin.test.Test
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.test.Test
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class CookieMigrationTest {
|
||||
|
@ -17,13 +17,13 @@
|
||||
package com.pitchedapps.frost.db
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.core.error.NoBeanDefFoundException
|
||||
import org.koin.test.KoinTest
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.functions
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.core.error.NoBeanDefFoundException
|
||||
import org.koin.test.KoinTest
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DatabaseTest : KoinTest {
|
||||
|
@ -18,9 +18,9 @@ package com.pitchedapps.frost.db
|
||||
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.facebook.defaultTabs
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class GenericDbTest : BaseDbTest() {
|
||||
|
||||
|
@ -19,11 +19,11 @@ package com.pitchedapps.frost.db
|
||||
import com.pitchedapps.frost.services.NOTIF_CHANNEL_GENERAL
|
||||
import com.pitchedapps.frost.services.NOTIF_CHANNEL_MESSAGES
|
||||
import com.pitchedapps.frost.services.NotificationContent
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class NotificationDbTest : BaseDbTest() {
|
||||
|
||||
|
@ -17,8 +17,8 @@
|
||||
package com.pitchedapps.frost.facebook
|
||||
|
||||
import android.webkit.CookieManager
|
||||
import kotlin.test.assertTrue
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class FbCookieTest {
|
||||
|
||||
|
@ -35,14 +35,14 @@ import com.pitchedapps.frost.services.setupNotificationChannels
|
||||
import com.pitchedapps.frost.utils.FrostPglAdBlock
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import java.util.Random
|
||||
import javax.inject.Inject
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.ext.koin.androidLogger
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.dsl.module
|
||||
import java.util.Random
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-28.
|
||||
|
@ -45,9 +45,9 @@ import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.launchNewTask
|
||||
import com.pitchedapps.frost.utils.loadAssets
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.ArrayList
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-28.
|
||||
@ -94,10 +94,10 @@ class StartActivity : KauBaseActivity() {
|
||||
L.i { "Cookies loaded at time ${System.currentTimeMillis()}" }
|
||||
L._d {
|
||||
"Cookies: ${
|
||||
cookies.joinToString(
|
||||
"\t",
|
||||
transform = CookieEntity::toSensitiveString
|
||||
)
|
||||
cookies.joinToString(
|
||||
"\t",
|
||||
transform = CookieEntity::toSensitiveString
|
||||
)
|
||||
}"
|
||||
}
|
||||
loadAssets(themeProvider)
|
||||
@ -106,11 +106,13 @@ class StartActivity : KauBaseActivity() {
|
||||
cookies.isEmpty() -> launchNewTask<LoginActivity>()
|
||||
// Has cookies but no selected account
|
||||
prefs.userId == -1L -> launchNewTask<SelectorActivity>(cookies)
|
||||
else -> startActivity<MainActivity>(intentBuilder = {
|
||||
putParcelableArrayListExtra(EXTRA_COOKIES, cookies)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
})
|
||||
else -> startActivity<MainActivity>(
|
||||
intentBuilder = {
|
||||
putParcelableArrayListExtra(EXTRA_COOKIES, cookies)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
}
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
L._e(e) { "Load start failed" }
|
||||
|
@ -144,7 +144,8 @@ class AboutActivity : AboutActivityBase(null) {
|
||||
}
|
||||
}
|
||||
|
||||
class AboutLinks : AbstractItem<AboutLinks.ViewHolder>(),
|
||||
class AboutLinks :
|
||||
AbstractItem<AboutLinks.ViewHolder>(),
|
||||
ThemableIItem by ThemableIItemDelegate() {
|
||||
override fun getViewHolder(v: View): ViewHolder = ViewHolder(v)
|
||||
|
||||
@ -186,12 +187,14 @@ class AboutActivity : AboutActivityBase(null) {
|
||||
)
|
||||
|
||||
images =
|
||||
(icons.map { (icon, onClick) -> c.drawable(icon) to onClick } + iicons.map { (icon, onClick) ->
|
||||
icon.toDrawable(
|
||||
c,
|
||||
32
|
||||
) to onClick
|
||||
}).mapIndexed { i, (icon, onClick) ->
|
||||
(
|
||||
icons.map { (icon, onClick) -> c.drawable(icon) to onClick } + iicons.map { (icon, onClick) ->
|
||||
icon.toDrawable(
|
||||
c,
|
||||
32
|
||||
) to onClick
|
||||
}
|
||||
).mapIndexed { i, (icon, onClick) ->
|
||||
ImageView(c).apply {
|
||||
layoutParams = ViewGroup.LayoutParams(size, size)
|
||||
id = 109389 + i
|
||||
|
@ -129,10 +129,10 @@ import com.pitchedapps.frost.views.FrostVideoViewer
|
||||
import com.pitchedapps.frost.views.FrostViewPager
|
||||
import com.pitchedapps.frost.widgets.NotificationWidget
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 20/12/17.
|
||||
@ -141,9 +141,12 @@ import kotlinx.coroutines.launch
|
||||
*/
|
||||
@UseExperimental(ExperimentalCoroutinesApi::class)
|
||||
@AndroidEntryPoint
|
||||
abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
abstract class BaseMainActivity :
|
||||
BaseActivity(),
|
||||
MainActivityContract,
|
||||
FileChooserContract by FileChooserDelegate(),
|
||||
VideoViewHolder, SearchViewHolder {
|
||||
VideoViewHolder,
|
||||
SearchViewHolder {
|
||||
|
||||
/**
|
||||
* Note that tabs themselves are initialized through a coroutine during onCreate
|
||||
@ -341,15 +344,17 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
shouldShow = false
|
||||
fab.backgroundTintList = ColorStateList.valueOf(themeProvider.headerColor.withMinAlpha(200))
|
||||
fab.hide()
|
||||
appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
|
||||
if (!hasFab) return@OnOffsetChangedListener
|
||||
val percent = abs(verticalOffset.toFloat() / appBarLayout.totalScrollRange)
|
||||
val shouldShow = percent < 0.2
|
||||
if (this@BaseMainActivity.shouldShow != shouldShow) {
|
||||
this@BaseMainActivity.shouldShow = shouldShow
|
||||
fab.showIf(shouldShow)
|
||||
appbar.addOnOffsetChangedListener(
|
||||
AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
|
||||
if (!hasFab) return@OnOffsetChangedListener
|
||||
val percent = abs(verticalOffset.toFloat() / appBarLayout.totalScrollRange)
|
||||
val shouldShow = percent < 0.2
|
||||
if (this@BaseMainActivity.shouldShow != shouldShow) {
|
||||
this@BaseMainActivity.shouldShow = shouldShow
|
||||
fab.showIf(shouldShow)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
override fun showFab(iicon: IIcon, clickEvent: () -> Unit) {
|
||||
@ -851,11 +856,13 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
this@SectionsPagerAdapter.pages.forEachIndexed { index, fbItem ->
|
||||
tabs.addTab(
|
||||
tabs.newTab()
|
||||
.setCustomView(BadgedIcon(this@BaseMainActivity).apply {
|
||||
iicon = fbItem.icon
|
||||
}.also {
|
||||
it.setAllAlpha(if (index == 0) SELECTED_TAB_ALPHA else UNSELECTED_TAB_ALPHA)
|
||||
})
|
||||
.setCustomView(
|
||||
BadgedIcon(this@BaseMainActivity).apply {
|
||||
iicon = fbItem.icon
|
||||
}.also {
|
||||
it.setAllAlpha(if (index == 0) SELECTED_TAB_ALPHA else UNSELECTED_TAB_ALPHA)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
lastPosition = 0
|
||||
|
@ -34,12 +34,12 @@ import com.pitchedapps.frost.injectors.ThemeProvider
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.createFreshDir
|
||||
import com.pitchedapps.frost.utils.setFrostColors
|
||||
import java.io.File
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.component.inject
|
||||
import java.io.File
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 05/01/18.
|
||||
|
@ -67,11 +67,6 @@ import com.pitchedapps.frost.utils.frostUriFromFile
|
||||
import com.pitchedapps.frost.utils.isIndirectImageUrl
|
||||
import com.pitchedapps.frost.utils.logFrostEvent
|
||||
import com.pitchedapps.frost.utils.setFrostColors
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -80,6 +75,11 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.component.inject
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-15.
|
||||
@ -219,11 +219,11 @@ class ImageActivity : KauBaseActivity() {
|
||||
setState(FabStates.SHARE)
|
||||
}
|
||||
imagePhoto.setOnImageEventListener(object :
|
||||
SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
override fun onImageLoadError(e: Exception) {
|
||||
loadError(e)
|
||||
}
|
||||
})
|
||||
SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
override fun onImageLoadError(e: Exception) {
|
||||
loadError(e)
|
||||
}
|
||||
})
|
||||
setFrostColors {
|
||||
themeWindow = false
|
||||
}
|
||||
|
@ -63,7 +63,9 @@ import org.koin.android.ext.android.inject
|
||||
* A beautiful intro activity
|
||||
* Phone showcases are drawn via layers
|
||||
*/
|
||||
class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer,
|
||||
class IntroActivity :
|
||||
KauBaseActivity(),
|
||||
ViewPager.PageTransformer,
|
||||
ViewPager.OnPageChangeListener {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
@ -48,8 +48,6 @@ import com.pitchedapps.frost.utils.logFrostEvent
|
||||
import com.pitchedapps.frost.utils.setFrostColors
|
||||
import com.pitchedapps.frost.utils.uniqueOnly
|
||||
import com.pitchedapps.frost.web.LoginWebView
|
||||
import java.net.UnknownHostException
|
||||
import kotlin.coroutines.resume
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
@ -59,6 +57,8 @@ import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.koin.android.ext.android.inject
|
||||
import java.net.UnknownHostException
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-01.
|
||||
|
@ -175,9 +175,12 @@ class SettingsActivity : KPrefActivity() {
|
||||
descRes = R.string.about_frost_desc
|
||||
iicon = GoogleMaterial.Icon.gmd_info
|
||||
onClick = {
|
||||
startActivityForResult<AboutActivity>(9, bundleBuilder = {
|
||||
withSceneTransitionAnimation(this@SettingsActivity)
|
||||
})
|
||||
startActivityForResult<AboutActivity>(
|
||||
9,
|
||||
bundleBuilder = {
|
||||
withSceneTransitionAnimation(this@SettingsActivity)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,10 +43,10 @@ import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.iitems.TabIItem
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.setFrostColors
|
||||
import java.util.Collections
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.inject
|
||||
import java.util.Collections
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 26/11/17.
|
||||
|
@ -156,9 +156,12 @@ class WebOverlayDesktopActivity : WebOverlayActivityBase(USER_AGENT_DESKTOP_CONS
|
||||
class WebOverlayActivity : WebOverlayActivityBase()
|
||||
|
||||
@UseExperimental(ExperimentalCoroutinesApi::class)
|
||||
abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT) : BaseActivity(),
|
||||
ActivityContract, FrostContentContainer,
|
||||
VideoViewHolder, FileChooserContract by FileChooserDelegate() {
|
||||
abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT) :
|
||||
BaseActivity(),
|
||||
ActivityContract,
|
||||
FrostContentContainer,
|
||||
VideoViewHolder,
|
||||
FileChooserContract by FileChooserDelegate() {
|
||||
|
||||
override val frameWrapper: FrameLayout by bindView(R.id.frame_wrapper)
|
||||
val toolbar: Toolbar by bindView(R.id.overlay_toolbar)
|
||||
|
@ -36,12 +36,14 @@ import kotlinx.android.parcel.Parcelize
|
||||
@Entity(
|
||||
tableName = "frost_cache",
|
||||
primaryKeys = ["id", "type"],
|
||||
foreignKeys = [ForeignKey(
|
||||
entity = CookieEntity::class,
|
||||
parentColumns = ["cookie_id"],
|
||||
childColumns = ["id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)]
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = CookieEntity::class,
|
||||
parentColumns = ["cookie_id"],
|
||||
childColumns = ["id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
@Parcelize
|
||||
data class CacheEntity(
|
||||
|
@ -26,8 +26,8 @@ import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
import org.koin.dsl.module
|
||||
import javax.inject.Singleton
|
||||
|
||||
interface FrostPrivateDao {
|
||||
fun cookieDao(): CookieDao
|
||||
|
@ -32,12 +32,14 @@ import com.pitchedapps.frost.utils.L
|
||||
@Entity(
|
||||
tableName = "notifications",
|
||||
primaryKeys = ["notif_id", "userId"],
|
||||
foreignKeys = [ForeignKey(
|
||||
entity = CookieEntity::class,
|
||||
parentColumns = ["cookie_id"],
|
||||
childColumns = ["userId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)],
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = CookieEntity::class,
|
||||
parentColumns = ["cookie_id"],
|
||||
childColumns = ["userId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index("notif_id"), Index("userId")]
|
||||
)
|
||||
data class NotificationEntity(
|
||||
|
@ -26,12 +26,6 @@ import com.pitchedapps.frost.utils.createFreshDir
|
||||
import com.pitchedapps.frost.utils.createFreshFile
|
||||
import com.pitchedapps.frost.utils.frostJsoup
|
||||
import com.pitchedapps.frost.utils.unescapeHtml
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -43,6 +37,12 @@ import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.jsoup.nodes.Entities
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 04/01/18.
|
||||
|
@ -28,13 +28,17 @@ enum class MainActivityLayout(
|
||||
val iconColor: (ThemeProvider) -> Int
|
||||
) {
|
||||
|
||||
TOP_BAR(R.string.top_bar,
|
||||
TOP_BAR(
|
||||
R.string.top_bar,
|
||||
{ it.headerColor },
|
||||
{ it.iconColor }),
|
||||
{ it.iconColor }
|
||||
),
|
||||
|
||||
BOTTOM_BAR(R.string.bottom_bar,
|
||||
BOTTOM_BAR(
|
||||
R.string.bottom_bar,
|
||||
{ it.bgColor },
|
||||
{ it.textColor });
|
||||
{ it.textColor }
|
||||
);
|
||||
|
||||
companion object {
|
||||
val values = values() // save one instance
|
||||
|
@ -39,53 +39,65 @@ enum class Theme(
|
||||
val iconColorGetter: (ThemePrefs) -> Int
|
||||
) {
|
||||
|
||||
DEFAULT(R.string.kau_default,
|
||||
DEFAULT(
|
||||
R.string.kau_default,
|
||||
"default",
|
||||
{ 0xde000000.toInt() },
|
||||
{ FACEBOOK_BLUE },
|
||||
{ 0xfffafafa.toInt() },
|
||||
{ FACEBOOK_BLUE },
|
||||
{ Color.WHITE }),
|
||||
{ Color.WHITE }
|
||||
),
|
||||
|
||||
LIGHT(R.string.kau_light,
|
||||
LIGHT(
|
||||
R.string.kau_light,
|
||||
"material_light",
|
||||
{ 0xde000000.toInt() },
|
||||
{ FACEBOOK_BLUE },
|
||||
{ 0xfffafafa.toInt() },
|
||||
{ FACEBOOK_BLUE },
|
||||
{ Color.WHITE }),
|
||||
{ Color.WHITE }
|
||||
),
|
||||
|
||||
DARK(R.string.kau_dark,
|
||||
DARK(
|
||||
R.string.kau_dark,
|
||||
"material_dark",
|
||||
{ Color.WHITE },
|
||||
{ BLUE_LIGHT },
|
||||
{ 0xff303030.toInt() },
|
||||
{ 0xff2e4b86.toInt() },
|
||||
{ Color.WHITE }),
|
||||
{ Color.WHITE }
|
||||
),
|
||||
|
||||
AMOLED(R.string.kau_amoled,
|
||||
AMOLED(
|
||||
R.string.kau_amoled,
|
||||
"material_amoled",
|
||||
{ Color.WHITE },
|
||||
{ BLUE_LIGHT },
|
||||
{ Color.BLACK },
|
||||
{ Color.BLACK },
|
||||
{ Color.WHITE }),
|
||||
{ Color.WHITE }
|
||||
),
|
||||
|
||||
GLASS(R.string.kau_glass,
|
||||
GLASS(
|
||||
R.string.kau_glass,
|
||||
"material_glass",
|
||||
{ Color.WHITE },
|
||||
{ BLUE_LIGHT },
|
||||
{ 0x80000000.toInt() },
|
||||
{ 0xb3000000.toInt() },
|
||||
{ Color.WHITE }),
|
||||
{ Color.WHITE }
|
||||
),
|
||||
|
||||
CUSTOM(R.string.kau_custom,
|
||||
CUSTOM(
|
||||
R.string.kau_custom,
|
||||
"custom",
|
||||
{ it.customTextColor },
|
||||
{ it.customAccentColor },
|
||||
{ it.customBackgroundColor },
|
||||
{ it.customHeaderColor },
|
||||
{ it.customIconColor });
|
||||
{ it.customIconColor }
|
||||
);
|
||||
|
||||
@VisibleForTesting
|
||||
internal val file = file?.let { "$it.css" }
|
||||
|
@ -28,15 +28,15 @@ import com.pitchedapps.frost.prefs.Prefs
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.cookies
|
||||
import com.pitchedapps.frost.utils.launchLogin
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.dsl.module
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-30.
|
||||
|
@ -90,31 +90,33 @@ private class SearchParserImpl : FrostParserBase<FrostSearches>(false) {
|
||||
?: doc.getElementById("root")
|
||||
?: return null
|
||||
|
||||
return FrostSearches(container.select("table[role=presentation]").mapNotNull { el ->
|
||||
// Our assumption is that search entries start with an image, followed by general info
|
||||
// There may be other <td />s, but we will not be parsing them
|
||||
// Furthermore, the <td /> entry wraps a link, containing all the necessary info
|
||||
val a = el.select("td")
|
||||
.getOrNull(1)
|
||||
?.selectFirst("a")
|
||||
?: return@mapNotNull null
|
||||
val url =
|
||||
a.attr("href").takeIf { it.isNotEmpty() }
|
||||
?.formattedFbUrl?.formattedSearchUrl
|
||||
return FrostSearches(
|
||||
container.select("table[role=presentation]").mapNotNull { el ->
|
||||
// Our assumption is that search entries start with an image, followed by general info
|
||||
// There may be other <td />s, but we will not be parsing them
|
||||
// Furthermore, the <td /> entry wraps a link, containing all the necessary info
|
||||
val a = el.select("td")
|
||||
.getOrNull(1)
|
||||
?.selectFirst("a")
|
||||
?: return@mapNotNull null
|
||||
// Currently, children should all be <div /> elements, where the first entry is the name/title
|
||||
// And the other entries are additional info.
|
||||
// There are also cases of nested tables, eg for the "join" button in groups.
|
||||
// Those elements have <span /> texts, so we will filter by div to ignore those
|
||||
val texts = a.children().filter { it.tagName() == "div" && it.hasText() }
|
||||
val title = texts.firstOrNull()?.text() ?: return@mapNotNull null
|
||||
val info = texts.takeIf { it.size > 1 }?.last()?.text()
|
||||
L.e { a }
|
||||
create(
|
||||
href = url,
|
||||
title = title,
|
||||
description = info
|
||||
).also { L.e { it } }
|
||||
})
|
||||
val url =
|
||||
a.attr("href").takeIf { it.isNotEmpty() }
|
||||
?.formattedFbUrl?.formattedSearchUrl
|
||||
?: return@mapNotNull null
|
||||
// Currently, children should all be <div /> elements, where the first entry is the name/title
|
||||
// And the other entries are additional info.
|
||||
// There are also cases of nested tables, eg for the "join" button in groups.
|
||||
// Those elements have <span /> texts, so we will filter by div to ignore those
|
||||
val texts = a.children().filter { it.tagName() == "div" && it.hasText() }
|
||||
val title = texts.firstOrNull()?.text() ?: return@mapNotNull null
|
||||
val info = texts.takeIf { it.size > 1 }?.last()?.text()
|
||||
L.e { a }
|
||||
create(
|
||||
href = url,
|
||||
title = title,
|
||||
description = info
|
||||
).also { L.e { it } }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.REQUEST_REFRESH
|
||||
import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
|
||||
import com.pitchedapps.frost.utils.frostEvent
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.Job
|
||||
@ -51,6 +50,7 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.component.inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-11-07.
|
||||
@ -59,7 +59,10 @@ import org.koin.core.component.inject
|
||||
* Must be attached to activities implementing [MainActivityContract]
|
||||
*/
|
||||
@UseExperimental(ExperimentalCoroutinesApi::class)
|
||||
abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract,
|
||||
abstract class BaseFragment :
|
||||
Fragment(),
|
||||
CoroutineScope,
|
||||
FragmentContract,
|
||||
DynamicUiContract {
|
||||
|
||||
companion object {
|
||||
|
@ -77,7 +77,8 @@ open class HeaderIItem(
|
||||
itemId: Int = R.layout.iitem_header
|
||||
) : KauIItem<HeaderIItem.ViewHolder>(R.layout.iitem_header, ::ViewHolder, itemId) {
|
||||
|
||||
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<HeaderIItem>(itemView),
|
||||
class ViewHolder(itemView: View) :
|
||||
FastAdapter.ViewHolder<HeaderIItem>(itemView),
|
||||
KoinComponent {
|
||||
|
||||
private val themeProvider: ThemeProvider by inject()
|
||||
|
@ -101,7 +101,8 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) :
|
||||
}
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<NotificationIItem>(itemView),
|
||||
class ViewHolder(itemView: View) :
|
||||
FastAdapter.ViewHolder<NotificationIItem>(itemView),
|
||||
KoinComponent {
|
||||
|
||||
private val themeProvider: ThemeProvider by inject()
|
||||
|
@ -36,10 +36,12 @@ import org.koin.core.component.inject
|
||||
/**
|
||||
* Created by Allan Wang on 26/11/17.
|
||||
*/
|
||||
class TabIItem(val item: FbItem) : KauIItem<TabIItem.ViewHolder>(
|
||||
R.layout.iitem_tab_preview,
|
||||
{ ViewHolder(it) }
|
||||
), IDraggable {
|
||||
class TabIItem(val item: FbItem) :
|
||||
KauIItem<TabIItem.ViewHolder>(
|
||||
R.layout.iitem_tab_preview,
|
||||
{ ViewHolder(it) }
|
||||
),
|
||||
IDraggable {
|
||||
|
||||
override val isDraggable: Boolean = true
|
||||
|
||||
|
@ -22,11 +22,11 @@ import androidx.annotation.VisibleForTesting
|
||||
import ca.allanwang.kau.kotlin.lazyContext
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileNotFoundException
|
||||
import java.util.Locale
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-31.
|
||||
|
@ -21,8 +21,8 @@ import androidx.annotation.VisibleForTesting
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.web.FrostWebViewClient
|
||||
import kotlin.random.Random
|
||||
import org.apache.commons.text.StringEscapeUtils
|
||||
import kotlin.random.Random
|
||||
|
||||
class JsBuilder {
|
||||
private val css = StringBuilder()
|
||||
|
@ -30,63 +30,109 @@ import com.pitchedapps.frost.enums.Theme
|
||||
import com.pitchedapps.frost.enums.ThemeCategory
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileNotFoundException
|
||||
import javax.inject.Inject
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.core.context.GlobalContext
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileNotFoundException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
interface ThemeProvider {
|
||||
val textColor: Int
|
||||
|
||||
val accentColor: Int
|
||||
|
||||
val accentColorForWhite: Int
|
||||
|
||||
val nativeBgColor: Int
|
||||
|
||||
fun nativeBgColor(unread: Boolean): Int
|
||||
|
||||
val bgColor: Int
|
||||
|
||||
val headerColor: Int
|
||||
|
||||
val iconColor: Int
|
||||
|
||||
val isCustomTheme: Boolean
|
||||
|
||||
/**
|
||||
* Note that while this can be loaded from any thread, it is typically done through [preload]]
|
||||
*/
|
||||
fun injector(category: ThemeCategory): InjectorContract
|
||||
|
||||
fun setTheme(id: Int)
|
||||
|
||||
fun reset()
|
||||
|
||||
suspend fun preload()
|
||||
|
||||
companion object {
|
||||
|
||||
fun get(): ThemeProvider = GlobalContext.get().get()
|
||||
|
||||
fun module() = org.koin.dsl.module {
|
||||
single<ThemeProvider> { ThemeProviderImpl(get(), get()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides [InjectorContract] for each [ThemeCategory].
|
||||
* Can be reloaded to take in changes from [Prefs]
|
||||
*/
|
||||
class ThemeProvider @Inject internal constructor(
|
||||
class ThemeProviderImpl @Inject internal constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val prefs: Prefs
|
||||
) {
|
||||
) : ThemeProvider {
|
||||
|
||||
private var theme: Theme = Theme.values[prefs.theme]
|
||||
set(value) {
|
||||
field = value
|
||||
prefs.theme = value.ordinal
|
||||
}
|
||||
|
||||
private val injectors: MutableMap<ThemeCategory, InjectorContract> = mutableMapOf()
|
||||
|
||||
val textColor: Int
|
||||
override val textColor: Int
|
||||
get() = theme.textColorGetter(prefs)
|
||||
|
||||
val accentColor: Int
|
||||
override val accentColor: Int
|
||||
get() = theme.accentColorGetter(prefs)
|
||||
|
||||
val accentColorForWhite: Int
|
||||
override val accentColorForWhite: Int
|
||||
get() = when {
|
||||
accentColor.isColorVisibleOn(Color.WHITE) -> accentColor
|
||||
textColor.isColorVisibleOn(Color.WHITE) -> textColor
|
||||
else -> FACEBOOK_BLUE
|
||||
}
|
||||
|
||||
val nativeBgColor: Int
|
||||
override val nativeBgColor: Int
|
||||
get() = bgColor.withAlpha(30)
|
||||
|
||||
fun nativeBgColor(unread: Boolean) = bgColor
|
||||
override fun nativeBgColor(unread: Boolean) = bgColor
|
||||
.colorToForeground(if (unread) 0.7f else 0.0f)
|
||||
.withAlpha(30)
|
||||
|
||||
val bgColor: Int
|
||||
override val bgColor: Int
|
||||
get() = theme.backgroundColorGetter(prefs)
|
||||
|
||||
val headerColor: Int
|
||||
override val headerColor: Int
|
||||
get() = theme.headerColorGetter(prefs)
|
||||
|
||||
val iconColor: Int
|
||||
override val iconColor: Int
|
||||
get() = theme.iconColorGetter(prefs)
|
||||
|
||||
val isCustomTheme: Boolean
|
||||
override val isCustomTheme: Boolean
|
||||
get() = theme == Theme.CUSTOM
|
||||
|
||||
/**
|
||||
* Note that while this can be loaded from any thread, it is typically done through [preload]]
|
||||
*/
|
||||
fun injector(category: ThemeCategory): InjectorContract =
|
||||
override fun injector(category: ThemeCategory): InjectorContract =
|
||||
injectors.getOrPut(category) { createInjector(category) }
|
||||
|
||||
/**
|
||||
@ -128,28 +174,28 @@ class ThemeProvider @Inject internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun setTheme(id: Int) {
|
||||
override fun setTheme(id: Int) {
|
||||
if (theme.ordinal == id) return
|
||||
theme = Theme.values[id]
|
||||
reset()
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
override fun reset() {
|
||||
injectors.clear()
|
||||
}
|
||||
|
||||
suspend fun preload() {
|
||||
override suspend fun preload() {
|
||||
withContext(Dispatchers.IO) {
|
||||
reset()
|
||||
ThemeCategory.values().forEach { injector(it) }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun get(): ThemeProvider = GlobalContext.get().get()
|
||||
|
||||
fun module() = org.koin.dsl.module {
|
||||
single { ThemeProvider(get(), get()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
interface ThemeProviderModule {
|
||||
@Binds
|
||||
@Singleton
|
||||
fun themeProvider(to: ThemeProviderImpl): ThemeProvider
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) {
|
||||
|
||||
private fun View.setThemeClick(theme: Theme) {
|
||||
setOnClickListener { v ->
|
||||
prefs.theme = theme.ordinal
|
||||
themeProvider.setTheme(theme.ordinal)
|
||||
(activity as IntroActivity).apply {
|
||||
binding.ripple.ripple(themeProvider.bgColor, v.x + v.pivotX, v.y + v.pivotY)
|
||||
theme()
|
||||
|
@ -35,9 +35,9 @@ import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.IntroActivity
|
||||
import com.pitchedapps.frost.injectors.ThemeProvider
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import kotlin.math.abs
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.component.inject
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-28.
|
||||
|
@ -16,12 +16,12 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.kotlin
|
||||
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.channels.BroadcastChannel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
@UseExperimental(ExperimentalCoroutinesApi::class)
|
||||
fun <T> BroadcastChannel<T>.subscribeDuringJob(
|
||||
|
@ -17,7 +17,6 @@
|
||||
package com.pitchedapps.frost.kotlin
|
||||
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
@ -29,6 +28,7 @@ import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/**
|
||||
* Flyweight to keep track of values so long as they are valid.
|
||||
|
@ -20,6 +20,7 @@ import ca.allanwang.kau.kpref.KPref
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import com.pitchedapps.frost.BuildConfig
|
||||
import com.pitchedapps.frost.enums.FeedSort
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-28.
|
||||
@ -29,7 +30,8 @@ import com.pitchedapps.frost.enums.FeedSort
|
||||
* As of 2020-07-18, prefs have been split up into multiple folders
|
||||
*/
|
||||
@Deprecated(level = DeprecationLevel.WARNING, message = "Use pref segments")
|
||||
class OldPrefs(factory: KPrefFactory) : KPref("${BuildConfig.APPLICATION_ID}.prefs", factory) {
|
||||
class OldPrefs @Inject internal constructor(factory: KPrefFactory) :
|
||||
KPref("${BuildConfig.APPLICATION_ID}.prefs", factory) {
|
||||
|
||||
var lastLaunch: Long by kpref("last_launch", -1L)
|
||||
|
||||
|
@ -37,10 +37,10 @@ import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import org.koin.core.context.GlobalContext
|
||||
import org.koin.dsl.module
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* [Prefs] is no longer an actual pref, but we will expose the reset function as it is used elsewhere
|
||||
@ -62,12 +62,12 @@ interface Prefs :
|
||||
fun get(): Prefs = GlobalContext.get().get()
|
||||
|
||||
fun module() = module {
|
||||
single<BehaviourPrefs> { BehaviourPrefsImpl(factory = get()) }
|
||||
single<CorePrefs> { CorePrefsImpl(factory = get()) }
|
||||
single<FeedPrefs> { FeedPrefsImpl(factory = get()) }
|
||||
single<NotifPrefs> { NotifPrefsImpl(factory = get()) }
|
||||
single<ThemePrefs> { ThemePrefsImpl(factory = get()) }
|
||||
single<ShowcasePrefs> { ShowcasePrefsImpl(factory = get()) }
|
||||
single<BehaviourPrefs> { BehaviourPrefsImpl(get(), get()) }
|
||||
single<CorePrefs> { CorePrefsImpl(get(), get()) }
|
||||
single<FeedPrefs> { FeedPrefsImpl(get(), get()) }
|
||||
single<NotifPrefs> { NotifPrefsImpl(get(), get()) }
|
||||
single<ThemePrefs> { ThemePrefsImpl(get(), get()) }
|
||||
single<ShowcasePrefs> { ShowcasePrefsImpl(get()) }
|
||||
single<Prefs> {
|
||||
PrefsImpl(
|
||||
behaviourPrefs = get(),
|
||||
|
@ -22,8 +22,6 @@ import com.pitchedapps.frost.BuildConfig
|
||||
import com.pitchedapps.frost.prefs.OldPrefs
|
||||
import com.pitchedapps.frost.prefs.PrefsBase
|
||||
import javax.inject.Inject
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
interface BehaviourPrefs : PrefsBase {
|
||||
var biometricsEnabled: Boolean
|
||||
@ -52,11 +50,9 @@ interface BehaviourPrefs : PrefsBase {
|
||||
}
|
||||
|
||||
class BehaviourPrefsImpl @Inject internal constructor(
|
||||
factory: KPrefFactory
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.behaviour", factory),
|
||||
BehaviourPrefs, KoinComponent {
|
||||
|
||||
private val oldPrefs: OldPrefs by inject()
|
||||
factory: KPrefFactory,
|
||||
oldPrefs: OldPrefs,
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.behaviour", factory), BehaviourPrefs {
|
||||
|
||||
override var biometricsEnabled: Boolean by kpref(
|
||||
"biometrics_enabled",
|
||||
|
@ -22,8 +22,6 @@ import com.pitchedapps.frost.BuildConfig
|
||||
import com.pitchedapps.frost.prefs.OldPrefs
|
||||
import com.pitchedapps.frost.prefs.PrefsBase
|
||||
import javax.inject.Inject
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
interface CorePrefs : PrefsBase {
|
||||
var lastLaunch: Long
|
||||
@ -58,11 +56,9 @@ interface CorePrefs : PrefsBase {
|
||||
}
|
||||
|
||||
class CorePrefsImpl @Inject internal constructor(
|
||||
factory: KPrefFactory
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.core", factory),
|
||||
CorePrefs, KoinComponent {
|
||||
|
||||
private val oldPrefs: OldPrefs by inject()
|
||||
factory: KPrefFactory,
|
||||
oldPrefs: OldPrefs,
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.core", factory), CorePrefs {
|
||||
|
||||
override var lastLaunch: Long by kpref("last_launch", oldPrefs.lastLaunch /* -1L */)
|
||||
|
||||
|
@ -23,8 +23,6 @@ import com.pitchedapps.frost.enums.MainActivityLayout
|
||||
import com.pitchedapps.frost.prefs.OldPrefs
|
||||
import com.pitchedapps.frost.prefs.PrefsBase
|
||||
import javax.inject.Inject
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
interface FeedPrefs : PrefsBase {
|
||||
var webTextScaling: Int
|
||||
@ -53,11 +51,9 @@ interface FeedPrefs : PrefsBase {
|
||||
}
|
||||
|
||||
class FeedPrefsImpl @Inject internal constructor(
|
||||
factory: KPrefFactory
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.feed", factory),
|
||||
FeedPrefs, KoinComponent {
|
||||
|
||||
private val oldPrefs: OldPrefs by inject()
|
||||
factory: KPrefFactory,
|
||||
oldPrefs: OldPrefs
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.feed", factory), FeedPrefs {
|
||||
|
||||
override var webTextScaling: Int by kpref("web_text_scaling", oldPrefs.webTextScaling /* 100 */)
|
||||
|
||||
|
@ -22,8 +22,6 @@ import com.pitchedapps.frost.BuildConfig
|
||||
import com.pitchedapps.frost.prefs.OldPrefs
|
||||
import com.pitchedapps.frost.prefs.PrefsBase
|
||||
import javax.inject.Inject
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
interface NotifPrefs : PrefsBase {
|
||||
var notificationKeywords: Set<String>
|
||||
@ -50,11 +48,9 @@ interface NotifPrefs : PrefsBase {
|
||||
}
|
||||
|
||||
class NotifPrefsImpl @Inject internal constructor(
|
||||
factory: KPrefFactory
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.notif", factory),
|
||||
NotifPrefs, KoinComponent {
|
||||
|
||||
private val oldPrefs: OldPrefs by inject()
|
||||
factory: KPrefFactory,
|
||||
oldPrefs: OldPrefs,
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.notif", factory), NotifPrefs {
|
||||
|
||||
override var notificationKeywords: Set<String> by kpref(
|
||||
"notification_keywords",
|
||||
|
@ -38,8 +38,7 @@ interface ShowcasePrefs : PrefsBase {
|
||||
*/
|
||||
class ShowcasePrefsImpl @Inject internal constructor(
|
||||
factory: KPrefFactory
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.showcase", factory),
|
||||
ShowcasePrefs {
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.showcase", factory), ShowcasePrefs {
|
||||
|
||||
override val firstWebOverlay: Boolean by kprefSingle("first_web_overlay")
|
||||
|
||||
|
@ -19,12 +19,9 @@ package com.pitchedapps.frost.prefs.sections
|
||||
import ca.allanwang.kau.kpref.KPref
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import com.pitchedapps.frost.BuildConfig
|
||||
import com.pitchedapps.frost.injectors.ThemeProvider
|
||||
import com.pitchedapps.frost.prefs.OldPrefs
|
||||
import com.pitchedapps.frost.prefs.PrefsBase
|
||||
import javax.inject.Inject
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
interface ThemePrefs : PrefsBase {
|
||||
var theme: Int
|
||||
@ -43,16 +40,15 @@ interface ThemePrefs : PrefsBase {
|
||||
}
|
||||
|
||||
class ThemePrefsImpl @Inject internal constructor(
|
||||
factory: KPrefFactory
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.theme", factory),
|
||||
ThemePrefs, KoinComponent {
|
||||
factory: KPrefFactory,
|
||||
oldPrefs: OldPrefs,
|
||||
) : KPref("${BuildConfig.APPLICATION_ID}.prefs.theme", factory), ThemePrefs {
|
||||
|
||||
private val oldPrefs: OldPrefs by inject()
|
||||
private val themeProvider: ThemeProvider by inject()
|
||||
|
||||
override var theme: Int by kpref("theme", oldPrefs.theme /* 0 */) {
|
||||
themeProvider.setTheme(it)
|
||||
}
|
||||
/**
|
||||
* Note that this is purely for the pref storage. Updating themes should use
|
||||
* ThemeProvider
|
||||
*/
|
||||
override var theme: Int by kpref("theme", oldPrefs.theme /* 0 */)
|
||||
|
||||
override var customTextColor: Int by kpref(
|
||||
"color_text",
|
||||
|
@ -20,9 +20,9 @@ import android.app.job.JobParameters
|
||||
import android.app.job.JobService
|
||||
import androidx.annotation.CallSuper
|
||||
import ca.allanwang.kau.utils.ContextHelper
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
abstract class BaseJobService : JobService(), CoroutineScope {
|
||||
|
||||
|
@ -24,10 +24,10 @@ import android.content.Context
|
||||
import android.os.PersistableBundle
|
||||
import com.pitchedapps.frost.activities.ImageActivity
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import java.io.FileFilter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.FileFilter
|
||||
|
||||
class LocalService : BaseJobService() {
|
||||
|
||||
|
@ -43,7 +43,7 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
header(R.string.theme_customization)
|
||||
|
||||
text(R.string.theme, prefs::theme, { prefs.theme = it }) {
|
||||
text(R.string.theme, prefs::theme, { themeProvider.setTheme(it) }) {
|
||||
onClick = {
|
||||
materialDialog {
|
||||
title(R.string.theme)
|
||||
@ -78,53 +78,68 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
themeProvider.reset()
|
||||
}
|
||||
|
||||
colorPicker(R.string.text_color, prefs::customTextColor, {
|
||||
prefs.customTextColor = it
|
||||
reload()
|
||||
invalidateCustomTheme()
|
||||
shouldRestartMain()
|
||||
}) {
|
||||
colorPicker(
|
||||
R.string.text_color, prefs::customTextColor,
|
||||
{
|
||||
prefs.customTextColor = it
|
||||
reload()
|
||||
invalidateCustomTheme()
|
||||
shouldRestartMain()
|
||||
}
|
||||
) {
|
||||
dependsOnCustom()
|
||||
allowCustomAlpha = false
|
||||
}
|
||||
|
||||
colorPicker(R.string.accent_color, prefs::customAccentColor, {
|
||||
prefs.customAccentColor = it
|
||||
reload()
|
||||
invalidateCustomTheme()
|
||||
shouldRestartMain()
|
||||
}) {
|
||||
colorPicker(
|
||||
R.string.accent_color, prefs::customAccentColor,
|
||||
{
|
||||
prefs.customAccentColor = it
|
||||
reload()
|
||||
invalidateCustomTheme()
|
||||
shouldRestartMain()
|
||||
}
|
||||
) {
|
||||
dependsOnCustom()
|
||||
allowCustomAlpha = false
|
||||
}
|
||||
|
||||
colorPicker(R.string.background_color, prefs::customBackgroundColor, {
|
||||
prefs.customBackgroundColor = it
|
||||
bgCanvas.ripple(it, duration = 500L)
|
||||
invalidateCustomTheme()
|
||||
setFrostTheme(themeProvider, true)
|
||||
shouldRestartMain()
|
||||
}) {
|
||||
colorPicker(
|
||||
R.string.background_color, prefs::customBackgroundColor,
|
||||
{
|
||||
prefs.customBackgroundColor = it
|
||||
bgCanvas.ripple(it, duration = 500L)
|
||||
invalidateCustomTheme()
|
||||
setFrostTheme(themeProvider, true)
|
||||
shouldRestartMain()
|
||||
}
|
||||
) {
|
||||
dependsOnCustom()
|
||||
allowCustomAlpha = true
|
||||
}
|
||||
|
||||
colorPicker(R.string.header_color, prefs::customHeaderColor, {
|
||||
prefs.customHeaderColor = it
|
||||
frostNavigationBar(prefs, themeProvider)
|
||||
toolbarCanvas.ripple(it, RippleCanvas.MIDDLE, RippleCanvas.END, duration = 500L)
|
||||
reload()
|
||||
shouldRestartMain()
|
||||
}) {
|
||||
colorPicker(
|
||||
R.string.header_color, prefs::customHeaderColor,
|
||||
{
|
||||
prefs.customHeaderColor = it
|
||||
frostNavigationBar(prefs, themeProvider)
|
||||
toolbarCanvas.ripple(it, RippleCanvas.MIDDLE, RippleCanvas.END, duration = 500L)
|
||||
reload()
|
||||
shouldRestartMain()
|
||||
}
|
||||
) {
|
||||
dependsOnCustom()
|
||||
allowCustomAlpha = true
|
||||
}
|
||||
|
||||
colorPicker(R.string.icon_color, prefs::customIconColor, {
|
||||
prefs.customIconColor = it
|
||||
invalidateOptionsMenu()
|
||||
shouldRestartMain()
|
||||
}) {
|
||||
colorPicker(
|
||||
R.string.icon_color, prefs::customIconColor,
|
||||
{
|
||||
prefs.customIconColor = it
|
||||
invalidateOptionsMenu()
|
||||
shouldRestartMain()
|
||||
}
|
||||
) {
|
||||
dependsOnCustom()
|
||||
allowCustomAlpha = false
|
||||
}
|
||||
@ -134,7 +149,8 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
text(
|
||||
R.string.main_activity_layout,
|
||||
prefs::mainActivityLayoutType,
|
||||
{ prefs.mainActivityLayoutType = it }) {
|
||||
{ prefs.mainActivityLayoutType = it }
|
||||
) {
|
||||
textGetter = { string(prefs.mainActivityLayout.titleRes) }
|
||||
onClick = {
|
||||
materialDialog {
|
||||
@ -158,11 +174,14 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
onClick = { launchTabCustomizerActivity() }
|
||||
}
|
||||
|
||||
checkbox(R.string.tint_nav, prefs::tintNavBar, {
|
||||
prefs.tintNavBar = it
|
||||
frostNavigationBar(prefs, themeProvider)
|
||||
setFrostResult(REQUEST_NAV)
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.tint_nav, prefs::tintNavBar,
|
||||
{
|
||||
prefs.tintNavBar = it
|
||||
frostNavigationBar(prefs, themeProvider)
|
||||
setFrostResult(REQUEST_NAV)
|
||||
}
|
||||
) {
|
||||
descRes = R.string.tint_nav_desc
|
||||
}
|
||||
|
||||
@ -174,12 +193,16 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
) {
|
||||
prefs.webTextScaling = it
|
||||
setFrostResult(REQUEST_TEXT_ZOOM)
|
||||
})
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
checkbox(R.string.enforce_black_media_bg, prefs::blackMediaBg, {
|
||||
prefs.blackMediaBg = it
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.enforce_black_media_bg, prefs::blackMediaBg,
|
||||
{
|
||||
prefs.blackMediaBg = it
|
||||
}
|
||||
) {
|
||||
descRes = R.string.enforce_black_media_bg_desc
|
||||
}
|
||||
}
|
||||
|
@ -36,21 +36,24 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
checkbox(
|
||||
R.string.overlay_swipe,
|
||||
prefs::overlayEnabled,
|
||||
{ prefs.overlayEnabled = it; shouldRefreshMain() }) {
|
||||
{ prefs.overlayEnabled = it; shouldRefreshMain() }
|
||||
) {
|
||||
descRes = R.string.overlay_swipe_desc
|
||||
}
|
||||
|
||||
checkbox(
|
||||
R.string.overlay_full_screen_swipe,
|
||||
prefs::overlayFullScreenSwipe,
|
||||
{ prefs.overlayFullScreenSwipe = it }) {
|
||||
{ prefs.overlayFullScreenSwipe = it }
|
||||
) {
|
||||
descRes = R.string.overlay_full_screen_swipe_desc
|
||||
}
|
||||
|
||||
checkbox(
|
||||
R.string.open_links_in_default,
|
||||
prefs::linksInDefaultApp,
|
||||
{ prefs.linksInDefaultApp = it }) {
|
||||
{ prefs.linksInDefaultApp = it }
|
||||
) {
|
||||
descRes = R.string.open_links_in_default_desc
|
||||
}
|
||||
|
||||
@ -61,14 +64,16 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
checkbox(
|
||||
R.string.force_message_bottom,
|
||||
prefs::messageScrollToBottom,
|
||||
{ prefs.messageScrollToBottom = it }) {
|
||||
{ prefs.messageScrollToBottom = it }
|
||||
) {
|
||||
descRes = R.string.force_message_bottom_desc
|
||||
}
|
||||
|
||||
checkbox(
|
||||
R.string.auto_expand_text_box,
|
||||
prefs::autoExpandTextBox,
|
||||
{ prefs.autoExpandTextBox = it; shouldRefreshMain() }) {
|
||||
{ prefs.autoExpandTextBox = it; shouldRefreshMain() }
|
||||
) {
|
||||
descRes = R.string.auto_expand_text_box_desc
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,11 @@ import com.pitchedapps.frost.facebook.parsers.SearchParser
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.frostUriFromFile
|
||||
import com.pitchedapps.frost.utils.sendFrostEmail
|
||||
import java.io.File
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-30.
|
||||
|
@ -36,10 +36,13 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
// Experimental content ends here --------------------
|
||||
|
||||
checkbox(R.string.verbose_logging, prefs::verboseLogging, {
|
||||
prefs.verboseLogging = it
|
||||
KL.shouldLog = { it != Log.VERBOSE }
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.verbose_logging, prefs::verboseLogging,
|
||||
{
|
||||
prefs.verboseLogging = it
|
||||
KL.shouldLog = { it != Log.VERBOSE }
|
||||
}
|
||||
) {
|
||||
descRes = R.string.verbose_logging_desc
|
||||
}
|
||||
|
||||
|
@ -49,66 +49,93 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
textGetter = { string(FeedSort(it).textRes) }
|
||||
}
|
||||
|
||||
checkbox(R.string.aggressive_recents, prefs::aggressiveRecents, {
|
||||
prefs.aggressiveRecents = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.aggressive_recents, prefs::aggressiveRecents,
|
||||
{
|
||||
prefs.aggressiveRecents = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.aggressive_recents_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.composer, prefs::showComposer, {
|
||||
prefs.showComposer = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.composer, prefs::showComposer,
|
||||
{
|
||||
prefs.showComposer = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.composer_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.create_fab, prefs::showCreateFab, {
|
||||
prefs.showCreateFab = it
|
||||
setFrostResult(REQUEST_FAB)
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.create_fab, prefs::showCreateFab,
|
||||
{
|
||||
prefs.showCreateFab = it
|
||||
setFrostResult(REQUEST_FAB)
|
||||
}
|
||||
) {
|
||||
descRes = R.string.create_fab_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.suggested_friends, prefs::showSuggestedFriends, {
|
||||
prefs.showSuggestedFriends = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.suggested_friends, prefs::showSuggestedFriends,
|
||||
{
|
||||
prefs.showSuggestedFriends = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.suggested_friends_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.suggested_groups, prefs::showSuggestedGroups, {
|
||||
prefs.showSuggestedGroups = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.suggested_groups, prefs::showSuggestedGroups,
|
||||
{
|
||||
prefs.showSuggestedGroups = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.suggested_groups_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.show_stories, prefs::showStories, {
|
||||
prefs.showStories = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.show_stories, prefs::showStories,
|
||||
{
|
||||
prefs.showStories = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.show_stories_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.show_post_actions, prefs::showPostActions, {
|
||||
prefs.showPostActions = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.show_post_actions, prefs::showPostActions,
|
||||
{
|
||||
prefs.showPostActions = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.show_post_actions_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.show_post_reactions, prefs::showPostReactions, {
|
||||
prefs.showPostReactions = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.show_post_reactions, prefs::showPostReactions,
|
||||
{
|
||||
prefs.showPostReactions = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.show_post_reactions_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.full_size_image, prefs::fullSizeImage, {
|
||||
prefs.fullSizeImage = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
checkbox(
|
||||
R.string.full_size_image, prefs::fullSizeImage,
|
||||
{
|
||||
prefs.fullSizeImage = it
|
||||
shouldRefreshMain()
|
||||
}
|
||||
) {
|
||||
descRes = R.string.full_size_image_desc
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ fun SettingsActivity.getNetworkPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
checkbox(
|
||||
R.string.network_media_on_metered,
|
||||
{ !prefs.loadMediaOnMeteredNetwork },
|
||||
{ prefs.loadMediaOnMeteredNetwork = !it }) {
|
||||
{ prefs.loadMediaOnMeteredNetwork = !it }
|
||||
) {
|
||||
descRes = R.string.network_media_on_metered_desc
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,8 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
text(
|
||||
R.string.notification_frequency,
|
||||
prefs::notificationFreq,
|
||||
{ prefs.notificationFreq = it }) {
|
||||
{ prefs.notificationFreq = it }
|
||||
) {
|
||||
val options = longArrayOf(15, 30, 60, 120, 180, 300, 1440, 2880)
|
||||
val texts =
|
||||
options.map { if (it <= 0) string(R.string.no_notifications) else minuteToText(it) }
|
||||
@ -87,34 +88,42 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
}
|
||||
}
|
||||
|
||||
checkbox(R.string.notification_general, prefs::notificationsGeneral,
|
||||
checkbox(
|
||||
R.string.notification_general, prefs::notificationsGeneral,
|
||||
{
|
||||
prefs.notificationsGeneral = it
|
||||
reloadByTitle(R.string.notification_general_all_accounts)
|
||||
if (!prefs.notificationsInstantMessages)
|
||||
reloadByTitle(R.string.notification_frequency)
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
descRes = R.string.notification_general_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.notification_general_all_accounts, prefs::notificationAllAccounts,
|
||||
{ prefs.notificationAllAccounts = it }) {
|
||||
checkbox(
|
||||
R.string.notification_general_all_accounts, prefs::notificationAllAccounts,
|
||||
{ prefs.notificationAllAccounts = it }
|
||||
) {
|
||||
descRes = R.string.notification_general_all_accounts_desc
|
||||
enabler = { prefs.notificationsGeneral }
|
||||
}
|
||||
|
||||
checkbox(R.string.notification_messages, prefs::notificationsInstantMessages,
|
||||
checkbox(
|
||||
R.string.notification_messages, prefs::notificationsInstantMessages,
|
||||
{
|
||||
prefs.notificationsInstantMessages = it
|
||||
reloadByTitle(R.string.notification_messages_all_accounts)
|
||||
if (!prefs.notificationsGeneral)
|
||||
reloadByTitle(R.string.notification_frequency)
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
descRes = R.string.notification_messages_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.notification_messages_all_accounts, prefs::notificationsImAllAccounts,
|
||||
{ prefs.notificationsImAllAccounts = it }) {
|
||||
checkbox(
|
||||
R.string.notification_messages_all_accounts, prefs::notificationsImAllAccounts,
|
||||
{ prefs.notificationsImAllAccounts = it }
|
||||
) {
|
||||
descRes = R.string.notification_messages_all_accounts_desc
|
||||
enabler = { prefs.notificationsInstantMessages }
|
||||
}
|
||||
@ -129,13 +138,16 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
checkbox(R.string.notification_sound, prefs::notificationSound, {
|
||||
prefs.notificationSound = it
|
||||
reloadByTitle(
|
||||
R.string.notification_ringtone,
|
||||
R.string.message_ringtone
|
||||
)
|
||||
})
|
||||
checkbox(
|
||||
R.string.notification_sound, prefs::notificationSound,
|
||||
{
|
||||
prefs.notificationSound = it
|
||||
reloadByTitle(
|
||||
R.string.notification_ringtone,
|
||||
R.string.message_ringtone
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
fun KPrefText.KPrefTextContract<String>.ringtone(code: Int) {
|
||||
enabler = prefs::notificationSound
|
||||
@ -162,21 +174,29 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
}
|
||||
}
|
||||
|
||||
text(R.string.notification_ringtone, prefs::notificationRingtone,
|
||||
{ prefs.notificationRingtone = it }) {
|
||||
text(
|
||||
R.string.notification_ringtone, prefs::notificationRingtone,
|
||||
{ prefs.notificationRingtone = it }
|
||||
) {
|
||||
ringtone(SettingsActivity.REQUEST_NOTIFICATION_RINGTONE)
|
||||
}
|
||||
|
||||
text(R.string.message_ringtone, prefs::messageRingtone,
|
||||
{ prefs.messageRingtone = it }) {
|
||||
text(
|
||||
R.string.message_ringtone, prefs::messageRingtone,
|
||||
{ prefs.messageRingtone = it }
|
||||
) {
|
||||
ringtone(SettingsActivity.REQUEST_MESSAGE_RINGTONE)
|
||||
}
|
||||
|
||||
checkbox(R.string.notification_vibrate, prefs::notificationVibrate,
|
||||
{ prefs.notificationVibrate = it })
|
||||
checkbox(
|
||||
R.string.notification_vibrate, prefs::notificationVibrate,
|
||||
{ prefs.notificationVibrate = it }
|
||||
)
|
||||
|
||||
checkbox(R.string.notification_lights, prefs::notificationLights,
|
||||
{ prefs.notificationLights = it })
|
||||
checkbox(
|
||||
R.string.notification_lights, prefs::notificationLights,
|
||||
{ prefs.notificationLights = it }
|
||||
)
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
|
@ -31,18 +31,21 @@ fun SettingsActivity.getSecurityPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
descRes = R.string.security_disclaimer_info
|
||||
}
|
||||
|
||||
checkbox(R.string.enable_biometrics, prefs::biometricsEnabled, {
|
||||
launch {
|
||||
checkbox(
|
||||
R.string.enable_biometrics, prefs::biometricsEnabled,
|
||||
{
|
||||
launch {
|
||||
/*
|
||||
* For security, we should request authentication when:
|
||||
* - enabling to ensure that it is supported
|
||||
* - disabling to ensure that it is permitted
|
||||
*/
|
||||
BiometricUtils.authenticate(this@getSecurityPrefs, prefs, force = true).await()
|
||||
prefs.biometricsEnabled = it
|
||||
reloadByTitle(R.string.enable_biometrics)
|
||||
BiometricUtils.authenticate(this@getSecurityPrefs, prefs, force = true).await()
|
||||
prefs.biometricsEnabled = it
|
||||
reloadByTitle(R.string.enable_biometrics)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
) {
|
||||
descRes = R.string.enable_biometrics_desc
|
||||
enabler = { BiometricUtils.isSupported(this@getSecurityPrefs) }
|
||||
}
|
||||
|
@ -27,10 +27,10 @@ import androidx.lifecycle.OnLifecycleEvent
|
||||
import ca.allanwang.kau.utils.string
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
|
||||
typealias BiometricDeferred = CompletableDeferred<BiometricPrompt.CryptoObject?>
|
||||
|
||||
|
@ -72,12 +72,6 @@ import com.pitchedapps.frost.facebook.formattedFbUrl
|
||||
import com.pitchedapps.frost.injectors.JsAssets
|
||||
import com.pitchedapps.frost.injectors.ThemeProvider
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.apache.commons.text.StringEscapeUtils
|
||||
@ -86,6 +80,12 @@ import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-03.
|
||||
@ -101,9 +101,12 @@ inline fun <reified T : Activity> Context.launchNewTask(
|
||||
cookieList: ArrayList<CookieEntity> = arrayListOf(),
|
||||
clearStack: Boolean = false
|
||||
) {
|
||||
startActivity<T>(clearStack, intentBuilder = {
|
||||
putParcelableArrayListExtra(EXTRA_COOKIES, cookieList)
|
||||
})
|
||||
startActivity<T>(
|
||||
clearStack,
|
||||
intentBuilder = {
|
||||
putParcelableArrayListExtra(EXTRA_COOKIES, cookieList)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun Context.launchLogin(cookieList: ArrayList<CookieEntity>, clearStack: Boolean = true) {
|
||||
@ -133,9 +136,12 @@ private inline fun <reified T : WebOverlayActivityBase> Context.launchWebOverlay
|
||||
fbCookie.logout(this@launchWebOverlayImpl)
|
||||
}
|
||||
} else if (!(prefs.linksInDefaultApp && resolveActivityForUri(Uri.parse(argUrl)))) {
|
||||
startActivity<T>(false, intentBuilder = {
|
||||
putExtra(ARG_URL, argUrl)
|
||||
})
|
||||
startActivity<T>(
|
||||
false,
|
||||
intentBuilder = {
|
||||
putExtra(ARG_URL, argUrl)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,12 +161,14 @@ private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation(
|
||||
).toBundle()
|
||||
|
||||
fun Context.launchImageActivity(imageUrl: String, text: String? = null, cookie: String? = null) {
|
||||
startActivity<ImageActivity>(intentBuilder = {
|
||||
putExtras(fadeBundle())
|
||||
putExtra(ARG_IMAGE_URL, imageUrl)
|
||||
putExtra(ARG_TEXT, text)
|
||||
putExtra(ARG_COOKIE, cookie)
|
||||
})
|
||||
startActivity<ImageActivity>(
|
||||
intentBuilder = {
|
||||
putExtras(fadeBundle())
|
||||
putExtra(ARG_IMAGE_URL, imageUrl)
|
||||
putExtra(ARG_TEXT, text)
|
||||
putExtra(ARG_COOKIE, cookie)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun Activity.launchTabCustomizerActivity() {
|
||||
@ -168,7 +176,8 @@ fun Activity.launchTabCustomizerActivity() {
|
||||
SettingsActivity.ACTIVITY_REQUEST_TABS,
|
||||
bundleBuilder = {
|
||||
with(fadeBundle())
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun WebOverlayActivity.url(): String {
|
||||
@ -177,9 +186,11 @@ fun WebOverlayActivity.url(): String {
|
||||
|
||||
fun Activity.setFrostTheme(themeProvider: ThemeProvider, forceTransparent: Boolean = false) {
|
||||
val isTransparent =
|
||||
forceTransparent || (Color.alpha(themeProvider.bgColor) != 255) || (Color.alpha(
|
||||
themeProvider.headerColor
|
||||
) != 255)
|
||||
forceTransparent || (Color.alpha(themeProvider.bgColor) != 255) || (
|
||||
Color.alpha(
|
||||
themeProvider.headerColor
|
||||
) != 255
|
||||
)
|
||||
if (themeProvider.bgColor.isColorDark) {
|
||||
setTheme(if (isTransparent) R.style.FrostTheme_Transparent else R.style.FrostTheme)
|
||||
} else {
|
||||
|
@ -72,7 +72,8 @@ enum class WebContextType(
|
||||
OPEN_LINK(
|
||||
R.string.open_link,
|
||||
{ it.hasUrl },
|
||||
{ c, wc, fc -> c.launchWebOverlay(wc.url!!, fc, Prefs.get()) }),
|
||||
{ c, wc, fc -> c.launchWebOverlay(wc.url!!, fc, Prefs.get()) }
|
||||
),
|
||||
COPY_LINK(R.string.copy_link, { it.hasUrl }, { c, wc, _ -> c.copyToClipboard(wc.url) }),
|
||||
COPY_TEXT(R.string.copy_text, { it.hasText }, { c, wc, _ -> c.copyToClipboard(wc.text) }),
|
||||
SHARE_LINK(R.string.share_link, { it.hasUrl }, { c, wc, _ -> c.shareText(wc.url) })
|
||||
|
@ -31,20 +31,25 @@ import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.pitchedapps.frost.databinding.ViewBadgedIconBinding
|
||||
import com.pitchedapps.frost.injectors.ThemeProvider
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-19.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class BadgedIcon @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr), KoinComponent {
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
@Inject
|
||||
lateinit var themeProvider: ThemeProvider
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
private val themeProvider: ThemeProvider by inject()
|
||||
private val binding: ViewBadgedIconBinding =
|
||||
ViewBadgedIconBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
|
||||
@ -54,7 +59,8 @@ class BadgedIcon @JvmOverloads constructor(
|
||||
|
||||
private fun ViewBadgedIconBinding.init() {
|
||||
val badgeColor =
|
||||
prefs.mainActivityLayout.backgroundColor(themeProvider).withAlpha(255).colorToForeground(0.2f)
|
||||
prefs.mainActivityLayout.backgroundColor(themeProvider).withAlpha(255)
|
||||
.colorToForeground(0.2f)
|
||||
val badgeBackground =
|
||||
GradientDrawable(
|
||||
GradientDrawable.Orientation.BOTTOM_TOP,
|
||||
|
@ -77,7 +77,8 @@ abstract class FrostContentView<out T> @JvmOverloads constructor(
|
||||
defStyleAttr: Int = 0,
|
||||
defStyleRes: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr, defStyleRes),
|
||||
FrostContentParent, KoinComponent where T : View, T : FrostContentCore {
|
||||
FrostContentParent,
|
||||
KoinComponent where T : View, T : FrostContentCore {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
private val themeProvider: ThemeProvider by inject()
|
||||
|
@ -29,9 +29,9 @@ import com.pitchedapps.frost.contracts.FrostContentParent
|
||||
import com.pitchedapps.frost.fragments.RecyclerContentContract
|
||||
import com.pitchedapps.frost.prefs.Prefs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-29.
|
||||
|
@ -192,12 +192,12 @@ class FrostVideoViewer @JvmOverloads constructor(
|
||||
fun updateLocation() {
|
||||
with(binding) {
|
||||
viewTreeObserver.addOnGlobalLayoutListener(object :
|
||||
ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
video.updateLocation()
|
||||
viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
}
|
||||
})
|
||||
ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
video.updateLocation()
|
||||
viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +206,8 @@ class FrostVideoViewer @JvmOverloads constructor(
|
||||
if (video.isExpanded)
|
||||
videoToolbar.fadeIn(
|
||||
duration = CONTROL_ANIMATION_DURATION,
|
||||
onStart = { videoToolbar.visible() })
|
||||
onStart = { videoToolbar.visible() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,11 +34,11 @@ import com.pitchedapps.frost.prefs.Prefs
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.createFreshFile
|
||||
import com.pitchedapps.frost.utils.isFacebookUrl
|
||||
import java.io.File
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2018-01-05.
|
||||
|
@ -21,8 +21,8 @@ import android.webkit.WebResourceResponse
|
||||
import android.webkit.WebView
|
||||
import com.pitchedapps.frost.utils.FrostPglAdBlock
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import java.io.ByteArrayInputStream
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import java.io.ByteArrayInputStream
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-13.
|
||||
|
@ -18,6 +18,12 @@ package com.pitchedapps.frost.debugger
|
||||
|
||||
import com.pitchedapps.frost.facebook.FB_URL_BASE
|
||||
import com.pitchedapps.frost.internal.COOKIE
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.mockwebserver.Dispatcher
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import okhttp3.mockwebserver.RecordedRequest
|
||||
import org.junit.Assume.assumeTrue
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.test.AfterTest
|
||||
@ -27,12 +33,6 @@ import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.mockwebserver.Dispatcher
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import okhttp3.mockwebserver.RecordedRequest
|
||||
import org.junit.Assume.assumeTrue
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 05/01/18.
|
||||
@ -247,7 +247,8 @@ class OfflineWebsiteTest {
|
||||
|
||||
assertEquals(5, zip.size(), "2 files expected")
|
||||
zip.assertContentEquals(
|
||||
"index.html", content
|
||||
"index.html",
|
||||
content
|
||||
.replace(css1Url.toString(), "assets/a0_1.css")
|
||||
.replace(css2Url.toString(), "assets/a1_2.css")
|
||||
.replace(js1Url.toString(), "assets/a2_1.js.txt")
|
||||
|
@ -18,9 +18,9 @@ package com.pitchedapps.frost.facebook
|
||||
|
||||
import com.pitchedapps.frost.internal.authDependent
|
||||
import com.pitchedapps.frost.internal.testJsoup
|
||||
import kotlin.test.assertNotNull
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class FbDomTest {
|
||||
|
||||
|
@ -16,9 +16,9 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.facebook
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import org.apache.commons.text.StringEscapeUtils
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 24/12/17.
|
||||
|
@ -18,10 +18,10 @@ package com.pitchedapps.frost.facebook
|
||||
|
||||
import com.pitchedapps.frost.utils.isImageUrl
|
||||
import com.pitchedapps.frost.utils.isIndirectImageUrl
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-07.
|
||||
|
@ -20,12 +20,12 @@ import com.pitchedapps.frost.internal.COOKIE
|
||||
import com.pitchedapps.frost.internal.assertComponentsNotEmpty
|
||||
import com.pitchedapps.frost.internal.assertDescending
|
||||
import com.pitchedapps.frost.internal.authDependent
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.fail
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 24/12/17.
|
||||
|
@ -18,10 +18,10 @@ package com.pitchedapps.frost.facebook.requests
|
||||
|
||||
import com.pitchedapps.frost.internal.COOKIE
|
||||
import com.pitchedapps.frost.internal.authDependent
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 12/04/18.
|
||||
|
@ -20,6 +20,7 @@ import com.pitchedapps.frost.facebook.FB_USER_MATCHER
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.facebook.get
|
||||
import com.pitchedapps.frost.utils.frostJsoup
|
||||
import org.junit.Assume
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.Properties
|
||||
@ -27,7 +28,6 @@ import kotlin.reflect.full.starProjectedType
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.fail
|
||||
import org.junit.Assume
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 21/12/17.
|
||||
|
@ -16,6 +16,11 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.kotlin
|
||||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Rule
|
||||
import org.junit.rules.Timeout
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
@ -23,11 +28,6 @@ import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.fail
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Rule
|
||||
import org.junit.rules.Timeout
|
||||
|
||||
class FlyweightTest {
|
||||
|
||||
|
@ -16,9 +16,9 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.prefs
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-31.
|
||||
|
@ -17,10 +17,10 @@
|
||||
package com.pitchedapps.frost.utils
|
||||
|
||||
import com.pitchedapps.frost.BuildConfig
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import org.junit.Test
|
||||
|
||||
class BuildUtilsTest {
|
||||
|
||||
|
@ -17,13 +17,6 @@
|
||||
package com.pitchedapps.frost.utils
|
||||
|
||||
import com.pitchedapps.frost.kotlin.Flyweight
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
@ -39,6 +32,13 @@ import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Collection of tests around coroutines
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.utils
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-08-10.
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.utils
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 11/03/18.
|
||||
|
@ -17,10 +17,10 @@
|
||||
package com.pitchedapps.frost.utils
|
||||
|
||||
import com.pitchedapps.frost.facebook.FACEBOOK_COM
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-11-15.
|
||||
|
@ -3,7 +3,7 @@ apply plugin: "com.diffplug.spotless"
|
||||
spotless {
|
||||
kotlin {
|
||||
target "**/*.kt"
|
||||
ktlint()
|
||||
ktlint("0.41.0").userData(["disabled_rules": "no-wildcard-imports"])
|
||||
licenseHeaderFile '../spotless.license.kt'
|
||||
trimTrailingWhitespace()
|
||||
endWithNewline()
|
||||
|
Loading…
Reference in New Issue
Block a user