mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-11-08 12:02:33 +01:00
Move prefs to service locator
This commit is contained in:
parent
4d5aaf541d
commit
c8b54fd10a
@ -19,6 +19,8 @@ package com.pitchedapps.frost
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import ca.allanwang.kau.kpref.KPrefFactoryAndroid
|
||||
import ca.allanwang.kau.logging.KL
|
||||
import ca.allanwang.kau.utils.buildIsLollipopAndUp
|
||||
import com.bugsnag.android.Bugsnag
|
||||
@ -31,21 +33,42 @@ import com.pitchedapps.frost.utils.FrostPglAdBlock
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.Showcase
|
||||
import java.util.Random
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.ext.koin.androidLogger
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.get
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.dsl.module
|
||||
import java.util.Random
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-28.
|
||||
*/
|
||||
class FrostApp : Application() {
|
||||
class FrostApp : Application(), KoinComponent {
|
||||
|
||||
private lateinit var showcasePrefs: Showcase
|
||||
private lateinit var prefs: Prefs
|
||||
|
||||
override fun onCreate() {
|
||||
startKoin {
|
||||
if (BuildConfig.DEBUG) {
|
||||
androidLogger()
|
||||
}
|
||||
androidContext(this@FrostApp)
|
||||
modules(listOf(
|
||||
FrostDatabase.module(),
|
||||
prefFactoryModule(),
|
||||
Prefs.module(),
|
||||
Showcase.module()
|
||||
))
|
||||
}
|
||||
if (!buildIsLollipopAndUp) { // not supported
|
||||
super.onCreate()
|
||||
return
|
||||
}
|
||||
prefs = get()
|
||||
showcasePrefs = get()
|
||||
initPrefs()
|
||||
initBugsnag()
|
||||
|
||||
@ -54,9 +77,9 @@ class FrostApp : Application() {
|
||||
|
||||
super.onCreate()
|
||||
|
||||
setupNotificationChannels(applicationContext)
|
||||
setupNotificationChannels(this, prefs)
|
||||
|
||||
scheduleNotificationsFromPrefs()
|
||||
scheduleNotificationsFromPrefs(prefs)
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
||||
@ -77,27 +100,20 @@ class FrostApp : Application() {
|
||||
}
|
||||
})
|
||||
}
|
||||
startKoin {
|
||||
if (BuildConfig.DEBUG) {
|
||||
androidLogger()
|
||||
}
|
||||
androidContext(this@FrostApp)
|
||||
modules(FrostDatabase.module(this@FrostApp))
|
||||
}
|
||||
}
|
||||
|
||||
private fun initPrefs() {
|
||||
Showcase.initialize(this, "${BuildConfig.APPLICATION_ID}.showcase")
|
||||
Prefs.initialize(this, "${BuildConfig.APPLICATION_ID}.prefs")
|
||||
prefs.deleteKeys("search_bar")
|
||||
showcasePrefs.deleteKeys("shown_release", "experimental_by_default")
|
||||
KL.shouldLog = { BuildConfig.DEBUG }
|
||||
Prefs.verboseLogging = false
|
||||
if (Prefs.installDate == -1L) {
|
||||
Prefs.installDate = System.currentTimeMillis()
|
||||
prefs.verboseLogging = false
|
||||
if (prefs.installDate == -1L) {
|
||||
prefs.installDate = System.currentTimeMillis()
|
||||
}
|
||||
if (Prefs.identifier == -1) {
|
||||
Prefs.identifier = Random().nextInt(Int.MAX_VALUE)
|
||||
if (prefs.identifier == -1) {
|
||||
prefs.identifier = Random().nextInt(Int.MAX_VALUE)
|
||||
}
|
||||
Prefs.lastLaunch = System.currentTimeMillis()
|
||||
prefs.lastLaunch = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
private fun initBugsnag() {
|
||||
@ -113,12 +129,12 @@ class FrostApp : Application() {
|
||||
appVersion = version.versionName
|
||||
releaseStage = BuildUtils.getStage(BuildConfig.BUILD_TYPE)
|
||||
notifyReleaseStages = BuildUtils.getAllStages()
|
||||
autoCaptureSessions = Prefs.analytics
|
||||
enableExceptionHandler = Prefs.analytics
|
||||
autoCaptureSessions = prefs.analytics
|
||||
enableExceptionHandler = prefs.analytics
|
||||
}
|
||||
Bugsnag.init(this, config)
|
||||
L.bugsnagInit = true
|
||||
Bugsnag.setUserId(Prefs.frostId)
|
||||
Bugsnag.setUserId(prefs.frostId)
|
||||
Bugsnag.addToTab("Build", "Application", BuildConfig.APPLICATION_ID)
|
||||
Bugsnag.addToTab("Build", "Version", BuildConfig.VERSION_NAME)
|
||||
|
||||
@ -129,4 +145,12 @@ class FrostApp : Application() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun prefFactoryModule(): Module = module {
|
||||
single<KPrefFactory> {
|
||||
KPrefFactoryAndroid(get())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ import org.koin.android.ext.android.inject
|
||||
*/
|
||||
class StartActivity : KauBaseActivity() {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
private val cookieDao: CookieDao by inject()
|
||||
private val genericDao: GenericDao by inject()
|
||||
|
||||
@ -82,12 +83,12 @@ class StartActivity : KauBaseActivity() {
|
||||
transform = CookieEntity::toSensitiveString
|
||||
)}"
|
||||
}
|
||||
loadAssets()
|
||||
loadAssets(prefs)
|
||||
authDefer.await()
|
||||
when {
|
||||
cookies.isEmpty() -> launchNewTask<LoginActivity>()
|
||||
// Has cookies but no selected account
|
||||
Prefs.userId == -1L -> launchNewTask<SelectorActivity>(cookies)
|
||||
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
|
||||
|
@ -49,20 +49,25 @@ import com.pitchedapps.frost.BuildConfig
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-26.
|
||||
*/
|
||||
class AboutActivity : AboutActivityBase(null, {
|
||||
textColor = Prefs.textColor
|
||||
accentColor = Prefs.accentColor
|
||||
backgroundColor = Prefs.bgColor.withMinAlpha(200)
|
||||
cutoutForeground = Prefs.accentColor
|
||||
class AboutActivity : AboutActivityBase(null) {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
override fun Configs.buildConfigs() {
|
||||
textColor = prefs.textColor
|
||||
accentColor = prefs.accentColor
|
||||
backgroundColor = prefs.bgColor.withMinAlpha(200)
|
||||
cutoutForeground = prefs.accentColor
|
||||
cutoutDrawableRes = R.drawable.frost_f_200
|
||||
faqPageTitleRes = R.string.faq_title
|
||||
faqXmlRes = R.xml.frost_faq
|
||||
faqParseNewLine = false
|
||||
}) {
|
||||
}
|
||||
|
||||
override fun getLibraries(libs: Libs): List<Library> {
|
||||
val include = arrayOf(
|
||||
@ -121,8 +126,8 @@ class AboutActivity : AboutActivityBase(null, {
|
||||
clickCount++
|
||||
lastClick = now
|
||||
if (clickCount == 8) {
|
||||
if (!Prefs.debugSettings) {
|
||||
Prefs.debugSettings = true
|
||||
if (!prefs.debugSettings) {
|
||||
prefs.debugSettings = true
|
||||
L.d { "Debugging section enabled" }
|
||||
toast(R.string.debug_toast_enabled)
|
||||
} else {
|
||||
|
@ -21,13 +21,17 @@ import android.os.Bundle
|
||||
import ca.allanwang.kau.internal.KauBaseActivity
|
||||
import ca.allanwang.kau.searchview.SearchViewHolder
|
||||
import com.pitchedapps.frost.contracts.VideoViewHolder
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.setFrostTheme
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-12.
|
||||
*/
|
||||
abstract class BaseActivity : KauBaseActivity() {
|
||||
|
||||
val prefs: Prefs by inject()
|
||||
|
||||
/**
|
||||
* Inherited consumer to customize back press
|
||||
*/
|
||||
|
@ -177,7 +177,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
val start = System.currentTimeMillis()
|
||||
drawerWrapperBinding = ActivityMainDrawerWrapperBinding.inflate(layoutInflater)
|
||||
setContentView(drawerWrapperBinding.root)
|
||||
contentBinding = when (Prefs.mainActivityLayout) {
|
||||
contentBinding = when (prefs.mainActivityLayout) {
|
||||
MainActivityLayout.TOP_BAR -> {
|
||||
val binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
object : ActivityMainContentBinding {
|
||||
@ -211,7 +211,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
}
|
||||
setSupportActionBar(toolbar)
|
||||
viewpager.adapter = adapter
|
||||
tabs.setBackgroundColor(Prefs.mainActivityLayout.backgroundColor())
|
||||
tabs.setBackgroundColor(prefs.mainActivityLayout.backgroundColor(prefs))
|
||||
}
|
||||
onNestedCreate(savedInstanceState)
|
||||
L.i { "Main finished loading UI in ${System.currentTimeMillis() - start} ms" }
|
||||
@ -219,18 +219,18 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
adapter.setPages(genericDao.getTabs())
|
||||
}
|
||||
controlWebview = WebView(this)
|
||||
if (BuildConfig.VERSION_CODE > Prefs.versionCode) {
|
||||
Prefs.prevVersionCode = Prefs.versionCode
|
||||
Prefs.versionCode = BuildConfig.VERSION_CODE
|
||||
if (BuildConfig.VERSION_CODE > prefs.versionCode) {
|
||||
prefs.prevVersionCode = prefs.versionCode
|
||||
prefs.versionCode = BuildConfig.VERSION_CODE
|
||||
if (!BuildConfig.DEBUG) {
|
||||
frostChangelog()
|
||||
frostEvent(
|
||||
"Version",
|
||||
"Version code" to BuildConfig.VERSION_CODE,
|
||||
"Prev version code" to Prefs.prevVersionCode,
|
||||
"Prev version code" to prefs.prevVersionCode,
|
||||
"Version name" to BuildConfig.VERSION_NAME,
|
||||
"Build type" to BuildConfig.BUILD_TYPE,
|
||||
"Frost id" to Prefs.frostId
|
||||
"Frost id" to prefs.frostId
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -289,7 +289,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
drawer.addDrawerListener(toggle)
|
||||
toggle.syncState()
|
||||
|
||||
val foregroundColor = ColorStateList.valueOf(Prefs.textColor)
|
||||
val foregroundColor = ColorStateList.valueOf(prefs.textColor)
|
||||
|
||||
with(navigation) {
|
||||
FrostMenuBuilder(this@BaseMainActivity, menu).apply {
|
||||
@ -318,9 +318,9 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
launchWebOverlay(item.url)
|
||||
false
|
||||
}
|
||||
val navBg = Prefs.bgColor.withMinAlpha(200)
|
||||
val navBg = prefs.bgColor.withMinAlpha(200)
|
||||
setBackgroundColor(navBg)
|
||||
itemBackground = createNavDrawable(Prefs.accentColor, navBg)
|
||||
itemBackground = createNavDrawable(prefs.accentColor, navBg)
|
||||
itemTextColor = foregroundColor
|
||||
itemIconTintList = foregroundColor
|
||||
|
||||
@ -332,7 +332,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
private fun ActivityMainContentBinding.initFab() {
|
||||
hasFab = false
|
||||
shouldShow = false
|
||||
fab.backgroundTintList = ColorStateList.valueOf(Prefs.headerColor.withMinAlpha(200))
|
||||
fab.backgroundTintList = ColorStateList.valueOf(prefs.headerColor.withMinAlpha(200))
|
||||
fab.hide()
|
||||
appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
|
||||
if (!hasFab) return@OnOffsetChangedListener
|
||||
@ -352,12 +352,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
if (shouldShow) {
|
||||
if (fab.isShown) {
|
||||
fab.fadeScaleTransition {
|
||||
setIcon(iicon, color = Prefs.iconColor)
|
||||
setIcon(iicon, color = prefs.iconColor)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
fab.setIcon(iicon, color = Prefs.iconColor)
|
||||
fab.setIcon(iicon, color = prefs.iconColor)
|
||||
fab.showIf(shouldShow)
|
||||
}
|
||||
}
|
||||
@ -384,12 +384,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
private var pendingUpdate: Boolean = false
|
||||
private val binding = ViewNavHeaderBinding.inflate(layoutInflater)
|
||||
val root: View get() = binding.root
|
||||
private val optionsBackground = Prefs.bgColor.withMinAlpha(200).colorToForeground(
|
||||
private val optionsBackground = prefs.bgColor.withMinAlpha(200).colorToForeground(
|
||||
0.1f
|
||||
)
|
||||
|
||||
init {
|
||||
setPrimary(Prefs.userId)
|
||||
setPrimary(prefs.userId)
|
||||
binding.updateAccounts()
|
||||
with(drawerWrapperBinding) {
|
||||
drawer.addDrawerListener(object : DrawerLayout.SimpleDrawerListener() {
|
||||
@ -449,7 +449,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
animator.start()
|
||||
}
|
||||
|
||||
val textColor = Prefs.textColor
|
||||
val textColor = prefs.textColor
|
||||
|
||||
fun TextView.setOptionsIcon(iicon: IIcon) {
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
@ -459,7 +459,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
null
|
||||
)
|
||||
setTextColor(textColor)
|
||||
background = createNavDrawable(Prefs.accentColor, optionsBackground)
|
||||
background = createNavDrawable(prefs.accentColor, optionsBackground)
|
||||
}
|
||||
|
||||
with(optionsLogout) {
|
||||
@ -478,7 +478,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
text =
|
||||
String.format(
|
||||
string(R.string.kau_logout_confirm_as_x),
|
||||
currentCookie.name ?: Prefs.userId.toString()
|
||||
currentCookie.name ?: prefs.userId.toString()
|
||||
)
|
||||
)
|
||||
positiveButton(R.string.kau_yes) {
|
||||
@ -507,7 +507,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
arrow.setImageDrawable(
|
||||
GoogleMaterial.Icon.gmd_arrow_drop_down.toDrawable(
|
||||
this@BaseMainActivity,
|
||||
color = Prefs.textColor
|
||||
color = prefs.textColor
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -532,10 +532,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
avatarTertiary.setAccount(orderedAccounts.getOrNull(2), false)
|
||||
optionsAccountsContainer.removeAllViews()
|
||||
name.text = orderedAccounts.getOrNull(0)?.name
|
||||
name.setTextColor(Prefs.textColor)
|
||||
name.setTextColor(prefs.textColor)
|
||||
val glide = Glide.with(root)
|
||||
val accountSize = dimenPixelSize(R.dimen.drawer_account_avatar_size)
|
||||
val textColor = Prefs.textColor
|
||||
val textColor = prefs.textColor
|
||||
orderedAccounts.forEach { cookie ->
|
||||
val tv =
|
||||
TextView(
|
||||
@ -569,7 +569,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
})
|
||||
tv.text = cookie.name
|
||||
tv.setTextColor(textColor)
|
||||
tv.background = createNavDrawable(Prefs.accentColor, optionsBackground)
|
||||
tv.background = createNavDrawable(prefs.accentColor, optionsBackground)
|
||||
tv.setOnClickListener {
|
||||
switchAccount(cookie.id)
|
||||
}
|
||||
@ -608,7 +608,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
}
|
||||
|
||||
private fun switchAccount(id: Long) {
|
||||
if (Prefs.userId == id) return
|
||||
if (prefs.userId == id) return
|
||||
setPrimary(id)
|
||||
pendingUpdate = true
|
||||
closeDrawer()
|
||||
@ -627,9 +627,9 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_main, menu)
|
||||
contentBinding.toolbar.tint(Prefs.iconColor)
|
||||
contentBinding.toolbar.tint(prefs.iconColor)
|
||||
setMenuIcons(
|
||||
menu, Prefs.iconColor,
|
||||
menu, prefs.iconColor,
|
||||
R.id.action_settings to GoogleMaterial.Icon.gmd_settings,
|
||||
R.id.action_search to GoogleMaterial.Icon.gmd_search
|
||||
)
|
||||
@ -639,7 +639,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
|
||||
private fun bindSearchView(menu: Menu) {
|
||||
searchViewBindIfNull {
|
||||
bindSearchView(menu, R.id.action_search, Prefs.iconColor) {
|
||||
bindSearchView(menu, R.id.action_search, prefs.iconColor) {
|
||||
textCallback = { query, searchView ->
|
||||
val results = searchViewCache[query]
|
||||
if (results != null)
|
||||
@ -665,8 +665,8 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
searchCallback =
|
||||
{ query, _ -> launchWebOverlay("${FbItem._SEARCH.url}/?q=$query"); true }
|
||||
closeListener = { _ -> searchViewCache.clear() }
|
||||
foregroundColor = Prefs.textColor
|
||||
backgroundColor = Prefs.bgColor.withMinAlpha(200)
|
||||
foregroundColor = prefs.textColor
|
||||
backgroundColor = prefs.bgColor.withMinAlpha(200)
|
||||
onItemClick = { _, key, _, _ -> launchWebOverlay(key) }
|
||||
}
|
||||
}
|
||||
@ -737,7 +737,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
fragmentChannel.offer(lastPosition)
|
||||
}
|
||||
if (hasRequest(REQUEST_NOTIFICATION)) {
|
||||
scheduleNotificationsFromPrefs()
|
||||
scheduleNotificationsFromPrefs(prefs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -761,7 +761,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
val authDefer = BiometricUtils.authenticate(this@BaseMainActivity)
|
||||
FbCookie.switchBackUser()
|
||||
authDefer.await()
|
||||
if (shouldReload && Prefs.autoRefreshFeed) {
|
||||
if (shouldReload && prefs.autoRefreshFeed) {
|
||||
refreshAll()
|
||||
}
|
||||
}
|
||||
@ -794,14 +794,14 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
}
|
||||
}
|
||||
if (currentFragment.onBackPressed()) return true
|
||||
if (Prefs.exitConfirmation) {
|
||||
if (prefs.exitConfirmation) {
|
||||
materialDialog {
|
||||
title(R.string.kau_exit)
|
||||
message(R.string.kau_exit_confirmation)
|
||||
positiveButton(R.string.kau_yes) { finish() }
|
||||
negativeButton(R.string.kau_no)
|
||||
checkBoxPrompt(R.string.kau_do_not_show_again, isCheckedDefault = false) {
|
||||
Prefs.exitConfirmation = !it
|
||||
prefs.exitConfirmation = !it
|
||||
}
|
||||
}
|
||||
return true
|
||||
@ -879,6 +879,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
val item = pages[position]
|
||||
return BaseFragment(
|
||||
item.fragmentCreator,
|
||||
prefs,
|
||||
forcedFallbacks.contains(item.name),
|
||||
item,
|
||||
position
|
||||
@ -901,7 +902,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
|
||||
override val lowerVideoPadding: PointF
|
||||
get() {
|
||||
if (Prefs.mainActivityLayout == MainActivityLayout.BOTTOM_BAR)
|
||||
if (prefs.mainActivityLayout == MainActivityLayout.BOTTOM_BAR)
|
||||
lowerVideoPaddingPointF.set(0f, contentBinding.toolbar.height.toFloat())
|
||||
else
|
||||
lowerVideoPaddingPointF.set(0f, 0f)
|
||||
|
@ -38,11 +38,13 @@ import java.io.File
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 05/01/18.
|
||||
*/
|
||||
class DebugActivity : KauBaseActivity() {
|
||||
class DebugActivity : KauBaseActivity(), KoinComponent {
|
||||
|
||||
companion object {
|
||||
const val RESULT_URL = "extra_result_url"
|
||||
@ -51,6 +53,8 @@ class DebugActivity : KauBaseActivity() {
|
||||
fun baseDir(context: Context) = File(context.externalCacheDir, "offline_debug")
|
||||
}
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
lateinit var binding: ActivityDebugBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -76,8 +80,8 @@ class DebugActivity : KauBaseActivity() {
|
||||
|
||||
swipeRefresh.setOnRefreshListener(debugWebview::reload)
|
||||
|
||||
fab.visible().setIcon(GoogleMaterial.Icon.gmd_bug_report, Prefs.iconColor)
|
||||
fab.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
|
||||
fab.visible().setIcon(GoogleMaterial.Icon.gmd_bug_report, prefs.iconColor)
|
||||
fab.backgroundTintList = ColorStateList.valueOf(prefs.accentColor)
|
||||
fab.setOnClickListener { _ ->
|
||||
fab.hide()
|
||||
|
||||
|
@ -67,6 +67,14 @@ import com.pitchedapps.frost.utils.isIndirectImageUrl
|
||||
import com.pitchedapps.frost.utils.logFrostEvent
|
||||
import com.pitchedapps.frost.utils.sendFrostEmail
|
||||
import com.pitchedapps.frost.utils.setFrostColors
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
@ -75,17 +83,13 @@ import java.util.Date
|
||||
import java.util.Locale
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-15.
|
||||
*/
|
||||
class ImageActivity : KauBaseActivity() {
|
||||
class ImageActivity : KauBaseActivity(), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
@Volatile
|
||||
internal var errorRef: Throwable? = null
|
||||
@ -106,7 +110,7 @@ class ImageActivity : KauBaseActivity() {
|
||||
set(value) {
|
||||
if (field == value) return
|
||||
field = value
|
||||
value.update(binding.imageFab)
|
||||
value.update(binding.imageFab, prefs)
|
||||
}
|
||||
|
||||
private lateinit var dragHelper: ViewDragHelper
|
||||
@ -144,8 +148,8 @@ class ImageActivity : KauBaseActivity() {
|
||||
private lateinit var binding: ActivityImageBinding
|
||||
private var bottomBehavior: BottomSheetBehavior<View>? = null
|
||||
|
||||
private val baseBackgroundColor = if (Prefs.blackMediaBg) Color.BLACK
|
||||
else Prefs.bgColor.withMinAlpha(235)
|
||||
private val baseBackgroundColor = if (prefs.blackMediaBg) Color.BLACK
|
||||
else prefs.bgColor.withMinAlpha(235)
|
||||
|
||||
private fun loadError(e: Throwable) {
|
||||
if (e.message?.contains("<!DOCTYPE html>") == true) {
|
||||
@ -195,9 +199,9 @@ class ImageActivity : KauBaseActivity() {
|
||||
if (text.isNullOrBlank()) {
|
||||
imageText.gone()
|
||||
} else {
|
||||
imageText.setTextColor(if (Prefs.blackMediaBg) Color.WHITE else Prefs.textColor)
|
||||
imageText.setTextColor(if (prefs.blackMediaBg) Color.WHITE else prefs.textColor)
|
||||
imageText.setBackgroundColor(
|
||||
(if (Prefs.blackMediaBg) Color.BLACK else Prefs.bgColor)
|
||||
(if (prefs.blackMediaBg) Color.BLACK else prefs.bgColor)
|
||||
.colorToForeground(0.2f).withAlpha(255)
|
||||
)
|
||||
imageText.text = text
|
||||
@ -217,7 +221,7 @@ class ImageActivity : KauBaseActivity() {
|
||||
imageText.bringToFront()
|
||||
}
|
||||
}
|
||||
imageProgress.tint(if (Prefs.blackMediaBg) Color.WHITE else Prefs.accentColor)
|
||||
imageProgress.tint(if (prefs.blackMediaBg) Color.WHITE else prefs.accentColor)
|
||||
imageFab.setOnClickListener { fabAction.onClick(this@ImageActivity) }
|
||||
imagePhoto.setOnImageEventListener(object :
|
||||
SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
@ -405,10 +409,10 @@ class ImageActivity : KauBaseActivity() {
|
||||
|
||||
internal enum class FabStates(
|
||||
val iicon: IIcon,
|
||||
val iconColor: Int = Prefs.iconColor,
|
||||
val iconColorProvider: (Prefs) -> Int = { it.iconColor },
|
||||
val backgroundTint: Int = Int.MAX_VALUE
|
||||
) {
|
||||
ERROR(GoogleMaterial.Icon.gmd_error, Color.WHITE, Color.RED) {
|
||||
ERROR(GoogleMaterial.Icon.gmd_error, { Color.WHITE }, Color.RED) {
|
||||
override fun onClick(activity: ImageActivity) {
|
||||
val err =
|
||||
activity.errorRef?.takeIf { it !is FileNotFoundException && it.message != "Image failed to decode using JPEG decoder" }
|
||||
@ -460,8 +464,9 @@ internal enum class FabStates(
|
||||
* https://github.com/AllanWang/KAU/issues/184
|
||||
*
|
||||
*/
|
||||
fun update(fab: FloatingActionButton) {
|
||||
val tint = if (backgroundTint != Int.MAX_VALUE) backgroundTint else Prefs.accentColor
|
||||
fun update(fab: FloatingActionButton, prefs: Prefs) {
|
||||
val tint = if (backgroundTint != Int.MAX_VALUE) backgroundTint else prefs.accentColor
|
||||
val iconColor = iconColorProvider(prefs)
|
||||
if (fab.isHidden) {
|
||||
fab.setIcon(iicon, color = iconColor)
|
||||
fab.backgroundTintList = ColorStateList.valueOf(tint)
|
||||
|
@ -55,6 +55,8 @@ import com.pitchedapps.frost.utils.setFrostTheme
|
||||
import com.pitchedapps.frost.widgets.NotificationWidget
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-25.
|
||||
@ -62,8 +64,10 @@ import kotlinx.coroutines.launch
|
||||
* A beautiful intro activity
|
||||
* Phone showcases are drawn via layers
|
||||
*/
|
||||
class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.OnPageChangeListener {
|
||||
class IntroActivity : KauBaseActivity(), KoinComponent, ViewPager.PageTransformer,
|
||||
ViewPager.OnPageChangeListener {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
lateinit var binding: ActivityIntroBinding
|
||||
private var barHasNext = true
|
||||
|
||||
@ -97,17 +101,17 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
|
||||
else finish(next.x + next.pivotX, next.y + next.pivotY)
|
||||
}
|
||||
skip.setOnClickListener { finish() }
|
||||
ripple.set(Prefs.bgColor)
|
||||
ripple.set(prefs.bgColor)
|
||||
theme()
|
||||
}
|
||||
|
||||
fun theme() {
|
||||
statusBarColor = Prefs.headerColor
|
||||
navigationBarColor = Prefs.headerColor
|
||||
statusBarColor = prefs.headerColor
|
||||
navigationBarColor = prefs.headerColor
|
||||
with(binding) {
|
||||
skip.setTextColor(Prefs.textColor)
|
||||
next.imageTintList = ColorStateList.valueOf(Prefs.textColor)
|
||||
indicator.setColour(Prefs.textColor)
|
||||
skip.setTextColor(prefs.textColor)
|
||||
next.imageTintList = ColorStateList.valueOf(prefs.textColor)
|
||||
indicator.setColour(prefs.textColor)
|
||||
indicator.invalidate()
|
||||
}
|
||||
fragments.forEach { it.themeFragment() }
|
||||
@ -149,21 +153,21 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
|
||||
).forEach {
|
||||
it?.animate()?.alpha(0f)?.setDuration(600)?.start()
|
||||
}
|
||||
if (Prefs.textColor != Color.WHITE) {
|
||||
if (prefs.textColor != Color.WHITE) {
|
||||
val f = lastView?.findViewById<ImageView>(R.id.intro_image)?.drawable
|
||||
if (f != null)
|
||||
ValueAnimator.ofFloat(0f, 1f).apply {
|
||||
addUpdateListener {
|
||||
f.setTint(Prefs.textColor.blendWith(Color.WHITE, it.animatedValue as Float))
|
||||
f.setTint(prefs.textColor.blendWith(Color.WHITE, it.animatedValue as Float))
|
||||
}
|
||||
duration = 600
|
||||
start()
|
||||
}
|
||||
}
|
||||
if (Prefs.headerColor != blue) {
|
||||
if (prefs.headerColor != blue) {
|
||||
ValueAnimator.ofFloat(0f, 1f).apply {
|
||||
addUpdateListener {
|
||||
val c = Prefs.headerColor.blendWith(blue, it.animatedValue as Float)
|
||||
val c = prefs.headerColor.blendWith(blue, it.animatedValue as Float)
|
||||
statusBarColor = c
|
||||
navigationBarColor = c
|
||||
}
|
||||
@ -175,7 +179,7 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
|
||||
|
||||
override fun finish() {
|
||||
launch(NonCancellable) {
|
||||
loadAssets()
|
||||
loadAssets(prefs)
|
||||
NotificationWidget.forceUpdate(this@IntroActivity)
|
||||
launchNewTask<MainActivity>(cookies(), false)
|
||||
super.finish()
|
||||
@ -206,7 +210,7 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
|
||||
binding.next.fadeScaleTransition {
|
||||
setIcon(
|
||||
if (barHasNext) GoogleMaterial.Icon.gmd_navigate_next else GoogleMaterial.Icon.gmd_done,
|
||||
color = Prefs.textColor
|
||||
color = prefs.textColor
|
||||
)
|
||||
}
|
||||
binding.skip.animate().scaleXY(if (barHasNext) 1f else 0f)
|
||||
|
@ -73,6 +73,7 @@ class LoginActivity : BaseActivity() {
|
||||
private val textview: AppCompatTextView by bindView(R.id.textview)
|
||||
private val profile: ImageView by bindView(R.id.profile)
|
||||
private val cookieDao: CookieDao by inject()
|
||||
private val showcasePrefs: Showcase by inject()
|
||||
|
||||
private lateinit var profileLoader: RequestManager
|
||||
private val refreshChannel = Channel<Boolean>(10)
|
||||
@ -138,7 +139,7 @@ class LoginActivity : BaseActivity() {
|
||||
*/
|
||||
val cookies = ArrayList(cookieDao.selectAll())
|
||||
delay(1000)
|
||||
if (Showcase.intro)
|
||||
if (showcasePrefs.intro)
|
||||
launchNewTask<IntroActivity>(cookies, true)
|
||||
else
|
||||
launchNewTask<MainActivity>(cookies, true)
|
||||
|
@ -61,12 +61,15 @@ import com.pitchedapps.frost.utils.loadAssets
|
||||
import com.pitchedapps.frost.utils.setFrostTheme
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-06.
|
||||
*/
|
||||
class SettingsActivity : KPrefActivity() {
|
||||
|
||||
val prefs: Prefs by inject()
|
||||
|
||||
private var resultFlag = Activity.RESULT_CANCELED
|
||||
|
||||
companion object {
|
||||
@ -117,11 +120,11 @@ class SettingsActivity : KPrefActivity() {
|
||||
}
|
||||
when (requestCode) {
|
||||
REQUEST_NOTIFICATION_RINGTONE -> {
|
||||
Prefs.notificationRingtone = uriString
|
||||
prefs.notificationRingtone = uriString
|
||||
reloadByTitle(R.string.notification_ringtone)
|
||||
}
|
||||
REQUEST_MESSAGE_RINGTONE -> {
|
||||
Prefs.messageRingtone = uriString
|
||||
prefs.messageRingtone = uriString
|
||||
reloadByTitle(R.string.message_ringtone)
|
||||
}
|
||||
}
|
||||
@ -129,8 +132,8 @@ class SettingsActivity : KPrefActivity() {
|
||||
}
|
||||
|
||||
override fun kPrefCoreAttributes(): CoreAttributeContract.() -> Unit = {
|
||||
textColor = { Prefs.textColor }
|
||||
accentColor = { Prefs.accentColor }
|
||||
textColor = { prefs.textColor }
|
||||
accentColor = { prefs.accentColor }
|
||||
}
|
||||
|
||||
override fun onCreateKPrefs(savedInstanceState: Bundle?): KPrefAdapterBuilder.() -> Unit = {
|
||||
@ -195,7 +198,7 @@ class SettingsActivity : KPrefActivity() {
|
||||
subItems(R.string.debug_frost, getDebugPrefs()) {
|
||||
descRes = R.string.debug_frost_desc
|
||||
iicon = CommunityMaterial.Icon.cmd_android_debug_bridge
|
||||
visible = { Prefs.debugSettings }
|
||||
visible = { prefs.debugSettings }
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,15 +218,15 @@ class SettingsActivity : KPrefActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setFrostTheme(true)
|
||||
super.onCreate(savedInstanceState)
|
||||
animate = Prefs.animate
|
||||
animate = prefs.animate
|
||||
themeExterior(false)
|
||||
}
|
||||
|
||||
fun themeExterior(animate: Boolean = true) {
|
||||
if (animate) bgCanvas.fade(Prefs.bgColor)
|
||||
else bgCanvas.set(Prefs.bgColor)
|
||||
if (animate) toolbarCanvas.ripple(Prefs.headerColor, RippleCanvas.MIDDLE, RippleCanvas.END)
|
||||
else toolbarCanvas.set(Prefs.headerColor)
|
||||
if (animate) bgCanvas.fade(prefs.bgColor)
|
||||
else bgCanvas.set(prefs.bgColor)
|
||||
if (animate) toolbarCanvas.ripple(prefs.headerColor, RippleCanvas.MIDDLE, RippleCanvas.END)
|
||||
else toolbarCanvas.set(prefs.headerColor)
|
||||
frostNavigationBar()
|
||||
}
|
||||
|
||||
@ -231,7 +234,7 @@ class SettingsActivity : KPrefActivity() {
|
||||
if (!super.backPress()) {
|
||||
setResult(resultFlag)
|
||||
launch(NonCancellable) {
|
||||
loadAssets()
|
||||
loadAssets(prefs)
|
||||
finishSlideOut()
|
||||
}
|
||||
}
|
||||
@ -239,9 +242,9 @@ class SettingsActivity : KPrefActivity() {
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_settings, menu)
|
||||
toolbar.tint(Prefs.iconColor)
|
||||
toolbar.tint(prefs.iconColor)
|
||||
setMenuIcons(
|
||||
menu, Prefs.iconColor,
|
||||
menu, prefs.iconColor,
|
||||
R.id.action_email to GoogleMaterial.Icon.gmd_email,
|
||||
R.id.action_changelog to GoogleMaterial.Icon.gmd_info
|
||||
)
|
||||
|
@ -42,12 +42,11 @@ import com.pitchedapps.frost.db.saveTabs
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.iitems.TabIItem
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
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.
|
||||
@ -70,15 +69,15 @@ class TabCustomizerActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
fun ActivityTabCustomizerBinding.init() {
|
||||
pseudoToolbar.setBackgroundColor(Prefs.headerColor)
|
||||
pseudoToolbar.setBackgroundColor(prefs.headerColor)
|
||||
|
||||
tabRecycler.layoutManager =
|
||||
GridLayoutManager(this@TabCustomizerActivity, TAB_COUNT, RecyclerView.VERTICAL, false)
|
||||
tabRecycler.adapter = adapter
|
||||
tabRecycler.setHasFixedSize(true)
|
||||
|
||||
divider.setBackgroundColor(Prefs.textColor.withAlpha(30))
|
||||
instructions.setTextColor(Prefs.textColor)
|
||||
divider.setBackgroundColor(prefs.textColor.withAlpha(30))
|
||||
instructions.setTextColor(prefs.textColor)
|
||||
|
||||
launch {
|
||||
val tabs = genericDao.getTabs().toMutableList()
|
||||
@ -95,8 +94,8 @@ class TabCustomizerActivity : BaseActivity() {
|
||||
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
|
||||
fabSave.setIcon(GoogleMaterial.Icon.gmd_check, Prefs.iconColor)
|
||||
fabSave.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
|
||||
fabSave.setIcon(GoogleMaterial.Icon.gmd_check, prefs.iconColor)
|
||||
fabSave.backgroundTintList = ColorStateList.valueOf(prefs.accentColor)
|
||||
fabSave.setOnClickListener {
|
||||
launchMain(NonCancellable) {
|
||||
val tabs = adapter.adapterItems.subList(0, TAB_COUNT).map(TabIItem::item)
|
||||
@ -105,8 +104,8 @@ class TabCustomizerActivity : BaseActivity() {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
fabCancel.setIcon(GoogleMaterial.Icon.gmd_close, Prefs.iconColor)
|
||||
fabCancel.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
|
||||
fabCancel.setIcon(GoogleMaterial.Icon.gmd_close, prefs.iconColor)
|
||||
fabCancel.backgroundTintList = ColorStateList.valueOf(prefs.accentColor)
|
||||
fabCancel.setOnClickListener { finish() }
|
||||
setFrostColors {
|
||||
themeWindow = true
|
||||
|
@ -78,6 +78,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-01.
|
||||
@ -170,6 +171,8 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
|
||||
get() = content.coreView
|
||||
private val coordinator: CoordinatorLayout by bindView(R.id.overlay_main_content)
|
||||
|
||||
private val showcasePrefs: Showcase by inject()
|
||||
|
||||
private inline val urlTest: String?
|
||||
get() = intent.getStringExtra(ARG_URL) ?: intent.dataString
|
||||
|
||||
@ -184,7 +187,7 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
|
||||
override val baseEnum: FbItem? = null
|
||||
|
||||
private inline val userId: Long
|
||||
get() = intent.getLongExtra(ARG_USER_ID, Prefs.userId)
|
||||
get() = intent.getLongExtra(ARG_USER_ID, prefs.userId)
|
||||
|
||||
private val overlayContext: OverlayContext?
|
||||
get() = OverlayContext[intent.extras]
|
||||
@ -205,14 +208,14 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
toolbar.navigationIcon = GoogleMaterial.Icon.gmd_close.toDrawable(this, 16, Prefs.iconColor)
|
||||
toolbar.navigationIcon = GoogleMaterial.Icon.gmd_close.toDrawable(this, 16, prefs.iconColor)
|
||||
toolbar.setNavigationOnClickListener { finishSlideOut() }
|
||||
|
||||
setFrostColors {
|
||||
toolbar(toolbar)
|
||||
themeWindow = false
|
||||
}
|
||||
coordinator.setBackgroundColor(Prefs.bgColor.withAlpha(255))
|
||||
coordinator.setBackgroundColor(prefs.bgColor.withAlpha(255))
|
||||
|
||||
content.bind(this)
|
||||
|
||||
@ -222,15 +225,15 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
|
||||
|
||||
with(web) {
|
||||
userAgentString = userAgent
|
||||
Prefs.prevId = Prefs.userId
|
||||
prefs.prevId = prefs.userId
|
||||
launch {
|
||||
val authDefer = BiometricUtils.authenticate(this@WebOverlayActivityBase)
|
||||
if (userId != Prefs.userId) {
|
||||
if (userId != prefs.userId) {
|
||||
FbCookie.switchUser(userId)
|
||||
}
|
||||
authDefer.await()
|
||||
reloadBase(true)
|
||||
if (Showcase.firstWebOverlay) {
|
||||
if (showcasePrefs.firstWebOverlay) {
|
||||
coordinator.frostSnackbar(R.string.web_overlay_swipe_hint) {
|
||||
duration = BaseTransientBottomBar.LENGTH_INDEFINITE
|
||||
setAction(R.string.kau_got_it) { dismiss() }
|
||||
@ -240,7 +243,7 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
|
||||
}
|
||||
|
||||
swipeBack = kauSwipeOnCreate {
|
||||
if (!Prefs.overlayFullScreenSwipe) edgeSize = 20.dpToPx
|
||||
if (!prefs.overlayFullScreenSwipe) edgeSize = 20.dpToPx
|
||||
transitionSystemBars = false
|
||||
}
|
||||
}
|
||||
@ -271,13 +274,13 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
|
||||
* Our theme for the overlay should be fully opaque
|
||||
*/
|
||||
fun theme() {
|
||||
val opaqueAccent = Prefs.headerColor.withAlpha(255)
|
||||
val opaqueAccent = prefs.headerColor.withAlpha(255)
|
||||
statusBarColor = opaqueAccent.darken()
|
||||
navigationBarColor = opaqueAccent
|
||||
toolbar.setBackgroundColor(opaqueAccent)
|
||||
toolbar.setTitleTextColor(Prefs.iconColor)
|
||||
coordinator.setBackgroundColor(Prefs.bgColor.withAlpha(255))
|
||||
toolbar.overflowIcon?.setTint(Prefs.iconColor)
|
||||
toolbar.setTitleTextColor(prefs.iconColor)
|
||||
coordinator.setBackgroundColor(prefs.bgColor.withAlpha(255))
|
||||
toolbar.overflowIcon?.setTint(prefs.iconColor)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@ -312,7 +315,7 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_web, menu)
|
||||
overlayContext?.onMenuCreate(this, menu)
|
||||
toolbar.tint(Prefs.iconColor)
|
||||
toolbar.tint(prefs.iconColor)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -68,4 +68,4 @@ suspend fun CookieDao.selectById(id: Long) = dao { _selectById(id) }
|
||||
suspend fun CookieDao.save(cookie: CookieEntity) = dao { _save(cookie) }
|
||||
suspend fun CookieDao.save(cookies: List<CookieEntity>) = dao { _save(cookies) }
|
||||
suspend fun CookieDao.deleteById(id: Long) = dao { _deleteById(id) }
|
||||
suspend fun CookieDao.currentCookie() = selectById(Prefs.userId)
|
||||
suspend fun CookieDao.currentCookie() = selectById(Prefs.get().userId)
|
||||
|
@ -93,8 +93,8 @@ class FrostDatabase(
|
||||
return FrostDatabase(privateDb, publicDb)
|
||||
}
|
||||
|
||||
fun module(context: Context) = module {
|
||||
single { create(context) }
|
||||
fun module() = module {
|
||||
single { create(get()) }
|
||||
single { get<FrostDatabase>().cookieDao() }
|
||||
single { get<FrostDatabase>().cacheDao() }
|
||||
single { get<FrostDatabase>().notifDao() }
|
||||
|
@ -24,17 +24,17 @@ import com.pitchedapps.frost.utils.Prefs
|
||||
*/
|
||||
enum class MainActivityLayout(
|
||||
val titleRes: Int,
|
||||
val backgroundColor: () -> Int,
|
||||
val iconColor: () -> Int
|
||||
val backgroundColor: (Prefs) -> Int,
|
||||
val iconColor: (Prefs) -> Int
|
||||
) {
|
||||
|
||||
TOP_BAR(R.string.top_bar,
|
||||
{ Prefs.headerColor },
|
||||
{ Prefs.iconColor }),
|
||||
{ it.headerColor },
|
||||
{ it.iconColor }),
|
||||
|
||||
BOTTOM_BAR(R.string.bottom_bar,
|
||||
{ Prefs.bgColor },
|
||||
{ Prefs.textColor });
|
||||
{ it.bgColor },
|
||||
{ it.textColor });
|
||||
|
||||
companion object {
|
||||
val values = values() // save one instance
|
||||
|
@ -23,6 +23,8 @@ import com.pitchedapps.frost.injectors.CssAssets
|
||||
import com.pitchedapps.frost.injectors.InjectorContract
|
||||
import com.pitchedapps.frost.injectors.JsActions
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-14.
|
||||
@ -82,11 +84,11 @@ enum class Theme(
|
||||
|
||||
CUSTOM(R.string.kau_custom,
|
||||
CssAssets.CUSTOM,
|
||||
{ Prefs.customTextColor },
|
||||
{ Prefs.customAccentColor },
|
||||
{ Prefs.customBackgroundColor },
|
||||
{ Prefs.customHeaderColor },
|
||||
{ Prefs.customIconColor });
|
||||
{ prefs.customTextColor },
|
||||
{ prefs.customAccentColor },
|
||||
{ prefs.customBackgroundColor },
|
||||
{ prefs.customHeaderColor },
|
||||
{ prefs.customIconColor });
|
||||
|
||||
val textColor: Int
|
||||
get() = textColorGetter()
|
||||
@ -103,7 +105,8 @@ enum class Theme(
|
||||
val iconColor: Int
|
||||
get() = iconColorGetter()
|
||||
|
||||
companion object {
|
||||
companion object:KoinComponent {
|
||||
private val prefs: Prefs by inject()
|
||||
val values = values() // save one instance
|
||||
operator fun invoke(index: Int) = values[index]
|
||||
}
|
||||
|
@ -35,13 +35,15 @@ import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-30.
|
||||
*
|
||||
* The following component manages all cookie transfers.
|
||||
*/
|
||||
object FbCookie {
|
||||
object FbCookie :KoinComponent {
|
||||
|
||||
const val COOKIE_DOMAIN = FB_URL_BASE
|
||||
|
||||
@ -52,9 +54,8 @@ object FbCookie {
|
||||
inline val webCookie: String?
|
||||
get() = CookieManager.getInstance().getCookie(COOKIE_DOMAIN)
|
||||
|
||||
private val cookieDao: CookieDao by lazy {
|
||||
FrostDatabase.get().cookieDao()
|
||||
}
|
||||
private val prefs: Prefs by inject()
|
||||
private val cookieDao: CookieDao by inject()
|
||||
|
||||
private suspend fun CookieManager.suspendSetWebCookie(cookie: String?): Boolean {
|
||||
cookie ?: return true
|
||||
@ -86,14 +87,14 @@ object FbCookie {
|
||||
|
||||
suspend fun save(id: Long) {
|
||||
L.d { "New cookie found" }
|
||||
Prefs.userId = id
|
||||
prefs.userId = id
|
||||
CookieManager.getInstance().flush()
|
||||
val cookie = CookieEntity(Prefs.userId, null, webCookie)
|
||||
val cookie = CookieEntity(prefs.userId, null, webCookie)
|
||||
cookieDao.save(cookie)
|
||||
}
|
||||
|
||||
suspend fun reset() {
|
||||
Prefs.userId = -1L
|
||||
prefs.userId = -1L
|
||||
with(CookieManager.getInstance()) {
|
||||
removeAllCookies()
|
||||
flush()
|
||||
@ -112,7 +113,7 @@ object FbCookie {
|
||||
}
|
||||
withContext(NonCancellable) {
|
||||
L.d { "Switching User" }
|
||||
Prefs.userId = cookie.id
|
||||
prefs.userId = cookie.id
|
||||
CookieManager.getInstance().suspendSetWebCookie(cookie.cookie)
|
||||
}
|
||||
}
|
||||
@ -124,8 +125,8 @@ object FbCookie {
|
||||
suspend fun logout(context: Context) {
|
||||
val cookies = arrayListOf<CookieEntity>()
|
||||
if (context is Activity)
|
||||
cookies.addAll(context.cookies().filter { it.id != Prefs.userId })
|
||||
logout(Prefs.userId)
|
||||
cookies.addAll(context.cookies().filter { it.id != prefs.userId })
|
||||
logout(prefs.userId)
|
||||
context.launchLogin(cookies, true)
|
||||
}
|
||||
|
||||
@ -145,13 +146,13 @@ object FbCookie {
|
||||
* When coming back to the main app, switch back to our original account before continuing
|
||||
*/
|
||||
suspend fun switchBackUser() {
|
||||
if (Prefs.prevId == -1L) return
|
||||
val prevId = Prefs.prevId
|
||||
Prefs.prevId = -1L
|
||||
if (prevId != Prefs.userId) {
|
||||
if (prefs.prevId == -1L) return
|
||||
val prevId = prefs.prevId
|
||||
prefs.prevId = -1L
|
||||
if (prevId != prefs.userId) {
|
||||
switchUser(prevId)
|
||||
L.d { "Switch back user" }
|
||||
L._d { "${Prefs.userId} to $prevId" }
|
||||
L._d { "${prefs.userId} to $prevId" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ import com.pitchedapps.frost.utils.Prefs
|
||||
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
|
||||
@ -47,6 +46,9 @@ import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-11-07.
|
||||
@ -55,7 +57,8 @@ import kotlinx.coroutines.launch
|
||||
* Must be attached to activities implementing [MainActivityContract]
|
||||
*/
|
||||
@UseExperimental(ExperimentalCoroutinesApi::class)
|
||||
abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, DynamicUiContract {
|
||||
abstract class BaseFragment : Fragment(), CoroutineScope, KoinComponent, FragmentContract,
|
||||
DynamicUiContract {
|
||||
|
||||
companion object {
|
||||
private const val ARG_POSITION = "arg_position"
|
||||
@ -63,12 +66,13 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
|
||||
|
||||
internal operator fun invoke(
|
||||
base: () -> BaseFragment,
|
||||
prefs: Prefs,
|
||||
useFallback: Boolean,
|
||||
data: FbItem,
|
||||
position: Int
|
||||
): BaseFragment {
|
||||
val fragment = if (useFallback) WebFragment() else base()
|
||||
val d = if (data == FbItem.FEED) FeedSort(Prefs.feedSort).item else data
|
||||
val d = if (data == FbItem.FEED) FeedSort(prefs.feedSort).item else data
|
||||
fragment.withArguments(
|
||||
ARG_URL to d.url,
|
||||
ARG_POSITION to position
|
||||
@ -78,6 +82,7 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
|
||||
}
|
||||
}
|
||||
|
||||
protected val prefs: Prefs by inject()
|
||||
open lateinit var job: Job
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = ContextHelper.dispatcher + job
|
||||
@ -195,10 +200,10 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
|
||||
protected fun FloatingActionButton.update(iicon: IIcon, click: () -> Unit) {
|
||||
if (isShown) {
|
||||
fadeScaleTransition {
|
||||
setIcon(iicon, Prefs.iconColor)
|
||||
setIcon(iicon, prefs.iconColor)
|
||||
}
|
||||
} else {
|
||||
setIcon(iicon, Prefs.iconColor)
|
||||
setIcon(iicon, prefs.iconColor)
|
||||
show()
|
||||
}
|
||||
setOnClickListener { click() }
|
||||
|
@ -52,9 +52,9 @@ class WebFragment : BaseFragment() {
|
||||
L.e { "Webview not found in fragment $baseEnum" }
|
||||
return super.updateFab(contract)
|
||||
}
|
||||
if (baseEnum.isFeed && Prefs.showCreateFab) {
|
||||
if (baseEnum.isFeed && prefs.showCreateFab) {
|
||||
contract.showFab(GoogleMaterial.Icon.gmd_edit) {
|
||||
JsActions.CREATE_POST.inject(web)
|
||||
JsActions.CREATE_POST.inject(web, prefs)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ import com.mikepenz.fastadapter.select.selectExtension
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.launchWebOverlay
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 30/12/17.
|
||||
@ -73,14 +75,16 @@ 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 prefs: Prefs by inject()
|
||||
|
||||
val text: TextView by bindView(R.id.item_header_text)
|
||||
|
||||
override fun bindView(item: HeaderIItem, payloads: MutableList<Any>) {
|
||||
text.setTextColor(Prefs.accentColor)
|
||||
text.setTextColor(prefs.accentColor)
|
||||
text.text = item.text
|
||||
text.setBackgroundColor(Prefs.nativeBgColor)
|
||||
text.setBackgroundColor(prefs.nativeBgColor)
|
||||
}
|
||||
|
||||
override fun unbindView(item: HeaderIItem) {
|
||||
@ -100,14 +104,16 @@ open class TextIItem(
|
||||
) : KauIItem<TextIItem.ViewHolder>(R.layout.iitem_text, ::ViewHolder, itemId),
|
||||
ClickableIItemContract {
|
||||
|
||||
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<TextIItem>(itemView) {
|
||||
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<TextIItem>(itemView),KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
val text: TextView by bindView(R.id.item_text_view)
|
||||
|
||||
override fun bindView(item: TextIItem, payloads: MutableList<Any>) {
|
||||
text.setTextColor(Prefs.textColor)
|
||||
text.setTextColor(prefs.textColor)
|
||||
text.text = item.text
|
||||
text.background = createSimpleRippleDrawable(Prefs.bgColor, Prefs.nativeBgColor)
|
||||
text.background = createSimpleRippleDrawable(prefs.bgColor, prefs.nativeBgColor)
|
||||
}
|
||||
|
||||
override fun unbindView(item: TextIItem) {
|
||||
|
@ -38,6 +38,8 @@ import com.pitchedapps.frost.glide.GlideApp
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.isIndependent
|
||||
import com.pitchedapps.frost.utils.launchWebOverlay
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 27/12/17.
|
||||
@ -93,7 +95,9 @@ 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 prefs: Prefs by inject()
|
||||
|
||||
private val frame: ViewGroup by bindView(R.id.item_frame)
|
||||
private val avatar: ImageView by bindView(R.id.item_avatar)
|
||||
@ -107,11 +111,11 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) :
|
||||
override fun bindView(item: NotificationIItem, payloads: MutableList<Any>) {
|
||||
val notif = item.notification
|
||||
frame.background = createSimpleRippleDrawable(
|
||||
Prefs.textColor,
|
||||
Prefs.nativeBgColor(notif.unread)
|
||||
prefs.textColor,
|
||||
prefs.nativeBgColor(notif.unread)
|
||||
)
|
||||
content.setTextColor(Prefs.textColor)
|
||||
date.setTextColor(Prefs.textColor.withAlpha(150))
|
||||
content.setTextColor(prefs.textColor)
|
||||
date.setTextColor(prefs.textColor.withAlpha(150))
|
||||
|
||||
val glide = glide
|
||||
glide.load(notif.img)
|
||||
|
@ -30,6 +30,8 @@ import com.mikepenz.fastadapter.drag.IDraggable
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 26/11/17.
|
||||
@ -41,14 +43,16 @@ class TabIItem(val item: FbItem) : KauIItem<TabIItem.ViewHolder>(
|
||||
|
||||
override val isDraggable: Boolean = true
|
||||
|
||||
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<TabIItem>(itemView) {
|
||||
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<TabIItem>(itemView), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
val image: ImageView by bindView(R.id.image)
|
||||
val text: TextView by bindView(R.id.text)
|
||||
|
||||
override fun bindView(item: TabIItem, payloads: MutableList<Any>) {
|
||||
val isInToolbar = adapterPosition < 4
|
||||
val color = if (isInToolbar) Prefs.iconColor else Prefs.textColor
|
||||
val color = if (isInToolbar) prefs.iconColor else prefs.textColor
|
||||
image.setIcon(item.item.icon, 20, color)
|
||||
if (isInToolbar)
|
||||
text.invisible()
|
||||
|
@ -20,7 +20,6 @@ import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.webkit.WebView
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import ca.allanwang.kau.kotlin.lazyContext
|
||||
import ca.allanwang.kau.utils.adjustAlpha
|
||||
import ca.allanwang.kau.utils.colorToBackground
|
||||
import ca.allanwang.kau.utils.colorToForeground
|
||||
@ -29,11 +28,11 @@ import ca.allanwang.kau.utils.use
|
||||
import ca.allanwang.kau.utils.withAlpha
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
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.
|
||||
@ -50,29 +49,38 @@ enum class CssAssets(val folder: String = THEME_FOLDER) : InjectorContract {
|
||||
/**
|
||||
* Note that while this can be loaded from any thread, it is typically done through [load]
|
||||
*/
|
||||
private val injector = lazyContext {
|
||||
private var injector: JsInjector? = null
|
||||
|
||||
private fun injector(context: Context, prefs: Prefs): JsInjector =
|
||||
injector ?: createInjector(context, prefs).also { injector = it }
|
||||
|
||||
/**
|
||||
* Note that while this can be loaded from any thread, it is typically done through [load]
|
||||
*/
|
||||
private fun createInjector(context: Context, prefs: Prefs): JsInjector =
|
||||
try {
|
||||
var content =
|
||||
it.assets.open("css/$folder/$file").bufferedReader().use(BufferedReader::readText)
|
||||
context.assets.open("css/$folder/$file").bufferedReader()
|
||||
.use(BufferedReader::readText)
|
||||
if (this == CUSTOM) {
|
||||
val bt = if (Color.alpha(Prefs.bgColor) == 255)
|
||||
Prefs.bgColor.toRgbaString()
|
||||
val bt = if (Color.alpha(prefs.bgColor) == 255)
|
||||
prefs.bgColor.toRgbaString()
|
||||
else
|
||||
"transparent"
|
||||
|
||||
val bb = Prefs.bgColor.colorToForeground(0.35f)
|
||||
val bb = prefs.bgColor.colorToForeground(0.35f)
|
||||
|
||||
content = content
|
||||
.replace("\$T\$", Prefs.textColor.toRgbaString())
|
||||
.replace("\$TT\$", Prefs.textColor.colorToBackground(0.05f).toRgbaString())
|
||||
.replace("\$A\$", Prefs.accentColor.toRgbaString())
|
||||
.replace("\$AT\$", Prefs.iconColor.toRgbaString())
|
||||
.replace("\$B\$", Prefs.bgColor.toRgbaString())
|
||||
.replace("\$T\$", prefs.textColor.toRgbaString())
|
||||
.replace("\$TT\$", prefs.textColor.colorToBackground(0.05f).toRgbaString())
|
||||
.replace("\$A\$", prefs.accentColor.toRgbaString())
|
||||
.replace("\$AT\$", prefs.iconColor.toRgbaString())
|
||||
.replace("\$B\$", prefs.bgColor.toRgbaString())
|
||||
.replace("\$BT\$", bt)
|
||||
.replace("\$BBT\$", bb.withAlpha(51).toRgbaString())
|
||||
.replace("\$O\$", Prefs.bgColor.withAlpha(255).toRgbaString())
|
||||
.replace("\$O\$", prefs.bgColor.withAlpha(255).toRgbaString())
|
||||
.replace("\$OO\$", bb.withAlpha(255).toRgbaString())
|
||||
.replace("\$D\$", Prefs.textColor.adjustAlpha(0.3f).toRgbaString())
|
||||
.replace("\$D\$", prefs.textColor.adjustAlpha(0.3f).toRgbaString())
|
||||
.replace("\$TI\$", bb.withAlpha(60).toRgbaString())
|
||||
.replace("\$C\$", bt)
|
||||
}
|
||||
@ -81,24 +89,24 @@ enum class CssAssets(val folder: String = THEME_FOLDER) : InjectorContract {
|
||||
L.e(e) { "CssAssets file not found" }
|
||||
JsInjector(JsActions.EMPTY.function)
|
||||
}
|
||||
}
|
||||
|
||||
override fun inject(webView: WebView) =
|
||||
injector(webView.context).inject(webView)
|
||||
override fun inject(webView: WebView, prefs: Prefs) =
|
||||
injector(webView.context, prefs).inject(webView, prefs)
|
||||
|
||||
fun reset() {
|
||||
injector.invalidate()
|
||||
injector = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
// Ensures that all non themes and the selected theme are loaded
|
||||
suspend fun load(context: Context) {
|
||||
suspend fun load(context: Context, prefs: Prefs) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val currentTheme = Prefs.t.injector as? CssAssets
|
||||
val currentTheme = prefs.t.injector as? CssAssets
|
||||
val (themes, others) = CssAssets.values().partition { it.folder == THEME_FOLDER }
|
||||
themes.filter { it != currentTheme }.forEach { it.reset() }
|
||||
currentTheme?.injector?.invoke(context)
|
||||
others.forEach { it.injector.invoke(context) }
|
||||
currentTheme?.injector(context, prefs)
|
||||
others.forEach { it.injector(context, prefs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.pitchedapps.frost.injectors
|
||||
|
||||
import android.webkit.WebView
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-31.
|
||||
@ -53,6 +54,6 @@ enum class CssHider(vararg val items: String) : InjectorContract {
|
||||
.single(name).build()
|
||||
}
|
||||
|
||||
override fun inject(webView: WebView) =
|
||||
injector.inject(webView)
|
||||
override fun inject(webView: WebView, prefs: Prefs) =
|
||||
injector.inject(webView, prefs)
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package com.pitchedapps.frost.injectors
|
||||
|
||||
import android.webkit.WebView
|
||||
import com.pitchedapps.frost.facebook.FB_URL_BASE
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-31.
|
||||
@ -42,8 +43,8 @@ enum class JsActions(body: String) : InjectorContract {
|
||||
|
||||
val function = "(function(){$body})();"
|
||||
|
||||
override fun inject(webView: WebView) =
|
||||
JsInjector(function).inject(webView)
|
||||
override fun inject(webView: WebView, prefs: Prefs) =
|
||||
JsInjector(function).inject(webView, prefs)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
@ -21,6 +21,7 @@ import android.webkit.WebView
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import ca.allanwang.kau.kotlin.lazyContext
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileNotFoundException
|
||||
import java.util.Locale
|
||||
@ -49,14 +50,14 @@ enum class JsAssets : InjectorContract {
|
||||
}
|
||||
}
|
||||
|
||||
override fun inject(webView: WebView) =
|
||||
injector(webView.context).inject(webView)
|
||||
override fun inject(webView: WebView, prefs: Prefs) =
|
||||
injector(webView.context).inject(webView, prefs)
|
||||
|
||||
companion object {
|
||||
// Ensures that all non themes and the selected theme are loaded
|
||||
suspend fun load(context: Context) {
|
||||
withContext(Dispatchers.IO) {
|
||||
JsAssets.values().forEach { it.injector.invoke(context) }
|
||||
values().forEach { it.injector.invoke(context) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package com.pitchedapps.frost.injectors
|
||||
import android.webkit.WebView
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.web.FrostWebViewClient
|
||||
import kotlin.random.Random
|
||||
import org.apache.commons.text.StringEscapeUtils
|
||||
@ -83,7 +84,7 @@ class JsBuilder {
|
||||
* Contract for all injectors to allow it to interact properly with a webview
|
||||
*/
|
||||
interface InjectorContract {
|
||||
fun inject(webView: WebView)
|
||||
fun inject(webView: WebView, prefs: Prefs)
|
||||
/**
|
||||
* Toggle the injector (usually through Prefs
|
||||
* If false, will fallback to an empty action
|
||||
@ -94,19 +95,19 @@ interface InjectorContract {
|
||||
/**
|
||||
* Helper method to inject multiple functions simultaneously with a single callback
|
||||
*/
|
||||
fun WebView.jsInject(vararg injectors: InjectorContract) {
|
||||
fun WebView.jsInject(vararg injectors: InjectorContract, prefs: Prefs) {
|
||||
injectors.filter { it != JsActions.EMPTY }.forEach {
|
||||
it.inject(this)
|
||||
it.inject(this,prefs)
|
||||
}
|
||||
}
|
||||
|
||||
fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract) = web.jsInject(*injectors)
|
||||
fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract, prefs: Prefs) = web.jsInject(*injectors, prefs = prefs)
|
||||
|
||||
/**
|
||||
* Wrapper class to convert a function into an injector
|
||||
*/
|
||||
class JsInjector(val function: String) : InjectorContract {
|
||||
override fun inject(webView: WebView) =
|
||||
override fun inject(webView: WebView, prefs: Prefs) =
|
||||
webView.evaluateJavascript(function, null)
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) {
|
||||
introThemeDark.setThemeClick(Theme.DARK)
|
||||
introThemeAmoled.setThemeClick(Theme.AMOLED)
|
||||
introThemeGlass.setThemeClick(Theme.GLASS)
|
||||
val currentTheme = Prefs.theme - 1
|
||||
val currentTheme = prefs.theme - 1
|
||||
if (currentTheme in 0..3)
|
||||
themeList.forEachIndexed { index, v ->
|
||||
v.scaleXY = if (index == currentTheme) 1.6f else 0.8f
|
||||
@ -65,9 +65,9 @@ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) {
|
||||
|
||||
private fun View.setThemeClick(theme: Theme) {
|
||||
setOnClickListener { v ->
|
||||
Prefs.theme = theme.ordinal
|
||||
prefs.theme = theme.ordinal
|
||||
(activity as IntroActivity).apply {
|
||||
binding.ripple.ripple(Prefs.bgColor, v.x + v.pivotX, v.y + v.pivotY)
|
||||
binding.ripple.ripple(prefs.bgColor, v.x + v.pivotX, v.y + v.pivotY)
|
||||
theme()
|
||||
}
|
||||
themeList.forEach { it.animate().scaleXY(if (it == this) 1.6f else 0.8f).start() }
|
||||
|
@ -58,10 +58,10 @@ abstract class BaseImageIntroFragment(
|
||||
|
||||
override fun themeFragmentImpl() {
|
||||
super.themeFragmentImpl()
|
||||
title.setTextColor(Prefs.textColor)
|
||||
desc.setTextColor(Prefs.textColor)
|
||||
phone.tint(Prefs.textColor)
|
||||
screen.tint(Prefs.bgColor)
|
||||
title.setTextColor(prefs.textColor)
|
||||
desc.setTextColor(prefs.textColor)
|
||||
phone.tint(prefs.textColor)
|
||||
screen.tint(prefs.bgColor)
|
||||
}
|
||||
|
||||
fun themeImageComponent(color: Int, vararg id: Int) {
|
||||
@ -97,9 +97,9 @@ class IntroAccountFragment : BaseImageIntroFragment(
|
||||
|
||||
override fun themeFragmentImpl() {
|
||||
super.themeFragmentImpl()
|
||||
themeImageComponent(Prefs.iconColor, R.id.intro_phone_avatar_1, R.id.intro_phone_avatar_2)
|
||||
themeImageComponent(Prefs.bgColor.colorToForeground(), R.id.intro_phone_nav)
|
||||
themeImageComponent(Prefs.headerColor, R.id.intro_phone_header)
|
||||
themeImageComponent(prefs.iconColor, R.id.intro_phone_avatar_1, R.id.intro_phone_avatar_2)
|
||||
themeImageComponent(prefs.bgColor.colorToForeground(), R.id.intro_phone_nav)
|
||||
themeImageComponent(prefs.headerColor, R.id.intro_phone_header)
|
||||
}
|
||||
|
||||
override fun onPageScrolledImpl(positionOffset: Float) {
|
||||
@ -123,14 +123,14 @@ class IntroTabTouchFragment : BaseImageIntroFragment(
|
||||
override fun themeFragmentImpl() {
|
||||
super.themeFragmentImpl()
|
||||
themeImageComponent(
|
||||
Prefs.iconColor,
|
||||
prefs.iconColor,
|
||||
R.id.intro_phone_icon_1,
|
||||
R.id.intro_phone_icon_2,
|
||||
R.id.intro_phone_icon_3,
|
||||
R.id.intro_phone_icon_4
|
||||
)
|
||||
themeImageComponent(Prefs.headerColor, R.id.intro_phone_tab)
|
||||
themeImageComponent(Prefs.textColor.withAlpha(80), R.id.intro_phone_icon_ripple)
|
||||
themeImageComponent(prefs.headerColor, R.id.intro_phone_tab)
|
||||
themeImageComponent(prefs.textColor.withAlpha(80), R.id.intro_phone_icon_ripple)
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,21 +142,21 @@ class IntroTabContextFragment : BaseImageIntroFragment(
|
||||
|
||||
override fun themeFragmentImpl() {
|
||||
super.themeFragmentImpl()
|
||||
themeImageComponent(Prefs.headerColor, R.id.intro_phone_toolbar)
|
||||
themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_image)
|
||||
themeImageComponent(prefs.headerColor, R.id.intro_phone_toolbar)
|
||||
themeImageComponent(prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_image)
|
||||
themeImageComponent(
|
||||
Prefs.bgColor.colorToForeground(0.2f),
|
||||
prefs.bgColor.colorToForeground(0.2f),
|
||||
R.id.intro_phone_like,
|
||||
R.id.intro_phone_share
|
||||
)
|
||||
themeImageComponent(Prefs.bgColor.colorToForeground(0.3f), R.id.intro_phone_comment)
|
||||
themeImageComponent(prefs.bgColor.colorToForeground(0.3f), R.id.intro_phone_comment)
|
||||
themeImageComponent(
|
||||
Prefs.bgColor.colorToForeground(0.1f),
|
||||
prefs.bgColor.colorToForeground(0.1f),
|
||||
R.id.intro_phone_card_1,
|
||||
R.id.intro_phone_card_2
|
||||
)
|
||||
themeImageComponent(
|
||||
Prefs.textColor,
|
||||
prefs.textColor,
|
||||
R.id.intro_phone_image_indicator,
|
||||
R.id.intro_phone_comment_indicator,
|
||||
R.id.intro_phone_card_indicator
|
||||
|
@ -37,6 +37,8 @@ import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.IntroActivity
|
||||
import com.pitchedapps.frost.databinding.IntroAnalyticsBinding
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
@ -48,7 +50,9 @@ import kotlin.math.abs
|
||||
/**
|
||||
* The core intro fragment for all other fragments
|
||||
*/
|
||||
abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
|
||||
abstract class BaseIntroFragment(val layoutRes: Int) : Fragment(), KoinComponent {
|
||||
|
||||
protected val prefs: Prefs by inject()
|
||||
|
||||
val screenWidth
|
||||
get() = resources.displayMetrics.widthPixels
|
||||
@ -105,7 +109,7 @@ abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
|
||||
}
|
||||
|
||||
protected open fun themeFragmentImpl() {
|
||||
(view as? ViewGroup)?.children?.forEach { (it as? TextView)?.setTextColor(Prefs.textColor) }
|
||||
(view as? ViewGroup)?.children?.forEach { (it as? TextView)?.setTextColor(prefs.textColor) }
|
||||
}
|
||||
|
||||
protected val viewArray: Array<Array<out View>> by lazyResettableRegistered { viewArray() }
|
||||
@ -134,7 +138,7 @@ class IntroFragmentWelcome : BaseIntroFragment(R.layout.intro_welcome) {
|
||||
|
||||
override fun themeFragmentImpl() {
|
||||
super.themeFragmentImpl()
|
||||
image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
|
||||
image.imageTintList = ColorStateList.valueOf(prefs.textColor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +157,7 @@ class IntroFragmentAnalytics : BaseIntroFragment(R.layout.intro_analytics) {
|
||||
|
||||
override fun themeFragmentImpl() {
|
||||
super.themeFragmentImpl()
|
||||
image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
|
||||
image.imageTintList = ColorStateList.valueOf(prefs.textColor)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@ -165,9 +169,9 @@ class IntroFragmentAnalytics : BaseIntroFragment(R.layout.intro_analytics) {
|
||||
|
||||
private fun IntroAnalyticsBinding.init() {
|
||||
image.setIcon(GoogleMaterial.Icon.gmd_bug_report, 120)
|
||||
introSwitch.isSelected = Prefs.analytics
|
||||
introSwitch.isSelected = prefs.analytics
|
||||
introSwitch.setOnCheckedChangeListener { _, isChecked ->
|
||||
Prefs.analytics = isChecked
|
||||
prefs.analytics = isChecked
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,7 +184,7 @@ class IntroFragmentEnd : BaseIntroFragment(R.layout.intro_end) {
|
||||
|
||||
override fun themeFragmentImpl() {
|
||||
super.themeFragmentImpl()
|
||||
image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
|
||||
image.imageTintList = ColorStateList.valueOf(prefs.textColor)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -67,7 +67,7 @@ enum class NotificationType(
|
||||
private val overlayContext: OverlayContext,
|
||||
private val fbItem: FbItem,
|
||||
private val parser: FrostParser<ParseNotification>,
|
||||
private val ringtone: () -> String
|
||||
private val ringtoneProvider: (Prefs) -> String
|
||||
) {
|
||||
|
||||
GENERAL(
|
||||
@ -75,7 +75,7 @@ enum class NotificationType(
|
||||
OverlayContext.NOTIFICATION,
|
||||
FbItem.NOTIFICATIONS,
|
||||
NotifParser,
|
||||
Prefs::notificationRingtone
|
||||
{ it.notificationRingtone }
|
||||
),
|
||||
|
||||
MESSAGE(
|
||||
@ -83,7 +83,7 @@ enum class NotificationType(
|
||||
OverlayContext.MESSAGE,
|
||||
FbItem.MESSAGES,
|
||||
MessageParser,
|
||||
Prefs::messageRingtone
|
||||
{ it.messageRingtone }
|
||||
);
|
||||
|
||||
private val groupPrefix = "frost_${name.toLowerCase(Locale.CANADA)}"
|
||||
@ -112,7 +112,7 @@ enum class NotificationType(
|
||||
* Returns the number of notifications generated,
|
||||
* or -1 if an error occurred
|
||||
*/
|
||||
suspend fun fetch(context: Context, data: CookieEntity): Int {
|
||||
suspend fun fetch(context: Context, data: CookieEntity, prefs: Prefs): Int {
|
||||
val notifDao = FrostDatabase.get().notifDao()
|
||||
val response = try {
|
||||
parser.parse(data.cookie)
|
||||
@ -129,7 +129,7 @@ enum class NotificationType(
|
||||
*/
|
||||
fun validText(text: String?): Boolean {
|
||||
val t = text ?: return true
|
||||
return Prefs.notificationKeywords.none {
|
||||
return prefs.notificationKeywords.none {
|
||||
t.contains(it, true)
|
||||
}
|
||||
}
|
||||
@ -167,7 +167,7 @@ enum class NotificationType(
|
||||
frostEvent("Notifications", "Type" to name, "Count" to notifs.size)
|
||||
if (notifs.size > 1)
|
||||
summaryNotification(context, userId, notifs.size).notify(context)
|
||||
val ringtone = ringtone()
|
||||
val ringtone = ringtoneProvider(prefs)
|
||||
notifs.forEachIndexed { i, notif ->
|
||||
// Ring at most twice
|
||||
notif.withAlert(context, i < 2, ringtone).notify(context)
|
||||
@ -316,9 +316,9 @@ data class FrostNotification(
|
||||
NotificationManagerCompat.from(context).notify(tag, id, notif.build())
|
||||
}
|
||||
|
||||
fun Context.scheduleNotificationsFromPrefs(): Boolean {
|
||||
val shouldSchedule = Prefs.hasNotifications
|
||||
return if (shouldSchedule) scheduleNotifications(Prefs.notificationFreq)
|
||||
fun Context.scheduleNotificationsFromPrefs(prefs: Prefs): Boolean {
|
||||
val shouldSchedule = prefs.hasNotifications
|
||||
return if (shouldSchedule) scheduleNotifications(prefs.notificationFreq)
|
||||
else scheduleNotifications(-1)
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.yield
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-14.
|
||||
@ -45,7 +46,8 @@ import org.koin.android.ext.android.inject
|
||||
*/
|
||||
class NotificationService : BaseJobService() {
|
||||
|
||||
val cookieDao: CookieDao by inject()
|
||||
private val prefs: Prefs by inject()
|
||||
private val cookieDao: CookieDao by inject()
|
||||
|
||||
override fun onStopJob(params: JobParameters?): Boolean {
|
||||
super.onStopJob(params)
|
||||
@ -64,7 +66,7 @@ class NotificationService : BaseJobService() {
|
||||
frostEvent(
|
||||
"NotificationTime",
|
||||
"Type" to (if (abrupt) "Service force stop" else "Service"),
|
||||
"IM Included" to Prefs.notificationsInstantMessages,
|
||||
"IM Included" to prefs.notificationsInstantMessages,
|
||||
"Duration" to time
|
||||
)
|
||||
}
|
||||
@ -86,7 +88,7 @@ class NotificationService : BaseJobService() {
|
||||
|
||||
private suspend fun sendNotifications(params: JobParameters?): Unit =
|
||||
withContext(Dispatchers.Default) {
|
||||
val currentId = Prefs.userId
|
||||
val currentId = prefs.userId
|
||||
val cookies = cookieDao.selectAll()
|
||||
yield()
|
||||
val jobId = params?.extras?.getInt(NOTIFICATION_PARAM_ID, -1) ?: -1
|
||||
@ -94,12 +96,12 @@ class NotificationService : BaseJobService() {
|
||||
for (cookie in cookies) {
|
||||
yield()
|
||||
val current = cookie.id == currentId
|
||||
if (Prefs.notificationsGeneral &&
|
||||
(current || Prefs.notificationAllAccounts)
|
||||
if (prefs.notificationsGeneral &&
|
||||
(current || prefs.notificationAllAccounts)
|
||||
)
|
||||
notifCount += fetch(jobId, NotificationType.GENERAL, cookie)
|
||||
if (Prefs.notificationsInstantMessages &&
|
||||
(current || Prefs.notificationsImAllAccounts)
|
||||
if (prefs.notificationsInstantMessages &&
|
||||
(current || prefs.notificationsImAllAccounts)
|
||||
)
|
||||
notifCount += fetch(jobId, NotificationType.MESSAGE, cookie)
|
||||
}
|
||||
@ -117,7 +119,7 @@ class NotificationService : BaseJobService() {
|
||||
* Also normalized the output to return the number of notifications received
|
||||
*/
|
||||
private suspend fun fetch(jobId: Int, type: NotificationType, cookie: CookieEntity): Int {
|
||||
val count = type.fetch(this, cookie)
|
||||
val count = type.fetch(this, cookie, prefs)
|
||||
if (count < 0) {
|
||||
if (jobId == NOTIFICATION_JOB_NOW)
|
||||
generalNotification(666, R.string.error_notification, BuildConfig.DEBUG)
|
||||
@ -133,7 +135,7 @@ class NotificationService : BaseJobService() {
|
||||
|
||||
private fun generalNotification(id: Int, textRes: Int, withDefaults: Boolean) {
|
||||
val notifBuilder = frostNotification(NOTIF_CHANNEL_GENERAL)
|
||||
.setFrostAlert(this, withDefaults, Prefs.notificationRingtone)
|
||||
.setFrostAlert(this, withDefaults, prefs.notificationRingtone)
|
||||
.setContentTitle(string(R.string.frost_name))
|
||||
.setContentText(string(textRes))
|
||||
NotificationManagerCompat.from(this).notify(id, notifBuilder.build())
|
||||
|
@ -41,13 +41,13 @@ import com.pitchedapps.frost.utils.frostUri
|
||||
const val NOTIF_CHANNEL_GENERAL = "general"
|
||||
const val NOTIF_CHANNEL_MESSAGES = "messages"
|
||||
|
||||
fun setupNotificationChannels(c: Context) {
|
||||
fun setupNotificationChannels(c: Context, prefs: Prefs) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
|
||||
val manager = c.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
val appName = c.string(R.string.frost_name)
|
||||
val msg = c.string(R.string.messages)
|
||||
manager.createNotificationChannel(NOTIF_CHANNEL_GENERAL, appName)
|
||||
manager.createNotificationChannel(NOTIF_CHANNEL_MESSAGES, "$appName: $msg")
|
||||
manager.createNotificationChannel(NOTIF_CHANNEL_GENERAL, appName, prefs)
|
||||
manager.createNotificationChannel(NOTIF_CHANNEL_MESSAGES, "$appName: $msg", prefs)
|
||||
manager.notificationChannels
|
||||
.filter {
|
||||
it.id != NOTIF_CHANNEL_GENERAL &&
|
||||
@ -60,14 +60,15 @@ fun setupNotificationChannels(c: Context) {
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun NotificationManager.createNotificationChannel(
|
||||
id: String,
|
||||
name: String
|
||||
name: String,
|
||||
prefs: Prefs
|
||||
): NotificationChannel {
|
||||
val channel = NotificationChannel(
|
||||
id,
|
||||
name, NotificationManager.IMPORTANCE_DEFAULT
|
||||
)
|
||||
channel.enableLights(true)
|
||||
channel.lightColor = Prefs.accentColor
|
||||
channel.lightColor = prefs.accentColor
|
||||
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||
createNotificationChannel(channel)
|
||||
return channel
|
||||
@ -93,6 +94,8 @@ fun NotificationCompat.Builder.setFrostAlert(
|
||||
enable: Boolean,
|
||||
ringtone: String
|
||||
): NotificationCompat.Builder {
|
||||
val prefs = Prefs.get()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
setGroupAlertBehavior(
|
||||
if (enable) NotificationCompat.GROUP_ALERT_CHILDREN
|
||||
@ -102,12 +105,12 @@ fun NotificationCompat.Builder.setFrostAlert(
|
||||
setDefaults(0)
|
||||
} else {
|
||||
var defaults = 0
|
||||
if (Prefs.notificationVibrate) defaults = defaults or Notification.DEFAULT_VIBRATE
|
||||
if (Prefs.notificationSound) {
|
||||
if (prefs.notificationVibrate) defaults = defaults or Notification.DEFAULT_VIBRATE
|
||||
if (prefs.notificationSound) {
|
||||
if (ringtone.isNotBlank()) setSound(context.frostUri(ringtone))
|
||||
else defaults = defaults or Notification.DEFAULT_SOUND
|
||||
}
|
||||
if (Prefs.notificationLights) defaults = defaults or Notification.DEFAULT_LIGHTS
|
||||
if (prefs.notificationLights) defaults = defaults or Notification.DEFAULT_LIGHTS
|
||||
setDefaults(defaults)
|
||||
}
|
||||
return this
|
||||
|
@ -21,17 +21,21 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-31.
|
||||
*
|
||||
* Receiver that is triggered whenever the app updates so it can bind the notifications again
|
||||
*/
|
||||
class UpdateReceiver : BroadcastReceiver() {
|
||||
class UpdateReceiver : BroadcastReceiver(), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action != Intent.ACTION_MY_PACKAGE_REPLACED) return
|
||||
L.d { "Frost has updated" }
|
||||
context.scheduleNotifications(Prefs.notificationFreq) // Update notifications
|
||||
context.scheduleNotifications(prefs.notificationFreq) // Update notifications
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,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, { prefs.theme = it }) {
|
||||
onClick = {
|
||||
materialDialog {
|
||||
title(R.string.theme)
|
||||
@ -71,7 +71,7 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
}
|
||||
|
||||
fun KPrefColorPicker.KPrefColorContract.dependsOnCustom() {
|
||||
enabler = Prefs::isCustomTheme
|
||||
enabler = prefs::isCustomTheme
|
||||
onDisabledClick = { frostSnackbar(R.string.requires_custom_theme) }
|
||||
allowCustom = true
|
||||
}
|
||||
@ -80,8 +80,8 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
CssAssets.CUSTOM.reset()
|
||||
}
|
||||
|
||||
colorPicker(R.string.text_color, Prefs::customTextColor, {
|
||||
Prefs.customTextColor = it
|
||||
colorPicker(R.string.text_color, prefs::customTextColor, {
|
||||
prefs.customTextColor = it
|
||||
reload()
|
||||
invalidateCustomTheme()
|
||||
shouldRestartMain()
|
||||
@ -90,8 +90,8 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
allowCustomAlpha = false
|
||||
}
|
||||
|
||||
colorPicker(R.string.accent_color, Prefs::customAccentColor, {
|
||||
Prefs.customAccentColor = it
|
||||
colorPicker(R.string.accent_color, prefs::customAccentColor, {
|
||||
prefs.customAccentColor = it
|
||||
reload()
|
||||
invalidateCustomTheme()
|
||||
shouldRestartMain()
|
||||
@ -100,8 +100,8 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
allowCustomAlpha = false
|
||||
}
|
||||
|
||||
colorPicker(R.string.background_color, Prefs::customBackgroundColor, {
|
||||
Prefs.customBackgroundColor = it
|
||||
colorPicker(R.string.background_color, prefs::customBackgroundColor, {
|
||||
prefs.customBackgroundColor = it
|
||||
bgCanvas.ripple(it, duration = 500L)
|
||||
invalidateCustomTheme()
|
||||
setFrostTheme(true)
|
||||
@ -111,8 +111,8 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
allowCustomAlpha = true
|
||||
}
|
||||
|
||||
colorPicker(R.string.header_color, Prefs::customHeaderColor, {
|
||||
Prefs.customHeaderColor = it
|
||||
colorPicker(R.string.header_color, prefs::customHeaderColor, {
|
||||
prefs.customHeaderColor = it
|
||||
frostNavigationBar()
|
||||
toolbarCanvas.ripple(it, RippleCanvas.MIDDLE, RippleCanvas.END, duration = 500L)
|
||||
reload()
|
||||
@ -122,8 +122,8 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
allowCustomAlpha = true
|
||||
}
|
||||
|
||||
colorPicker(R.string.icon_color, Prefs::customIconColor, {
|
||||
Prefs.customIconColor = it
|
||||
colorPicker(R.string.icon_color, prefs::customIconColor, {
|
||||
prefs.customIconColor = it
|
||||
invalidateOptionsMenu()
|
||||
shouldRestartMain()
|
||||
}) {
|
||||
@ -135,9 +135,9 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
text(
|
||||
R.string.main_activity_layout,
|
||||
Prefs::mainActivityLayoutType,
|
||||
{ Prefs.mainActivityLayoutType = it }) {
|
||||
textGetter = { string(Prefs.mainActivityLayout.titleRes) }
|
||||
prefs::mainActivityLayoutType,
|
||||
{ prefs.mainActivityLayoutType = it }) {
|
||||
textGetter = { string(prefs.mainActivityLayout.titleRes) }
|
||||
onClick = {
|
||||
materialDialog {
|
||||
title(R.string.main_activity_layout_desc)
|
||||
@ -160,8 +160,8 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
onClick = { launchTabCustomizerActivity() }
|
||||
}
|
||||
|
||||
checkbox(R.string.tint_nav, Prefs::tintNavBar, {
|
||||
Prefs.tintNavBar = it
|
||||
checkbox(R.string.tint_nav, prefs::tintNavBar, {
|
||||
prefs.tintNavBar = it
|
||||
frostNavigationBar()
|
||||
setFrostResult(REQUEST_NAV)
|
||||
}) {
|
||||
@ -172,15 +172,15 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
KPrefTextSeekbar(
|
||||
KPrefSeekbar.KPrefSeekbarBuilder(
|
||||
globalOptions,
|
||||
R.string.web_text_scaling, Prefs::webTextScaling
|
||||
R.string.web_text_scaling, prefs::webTextScaling
|
||||
) {
|
||||
Prefs.webTextScaling = it
|
||||
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
|
||||
}
|
||||
|
@ -26,47 +26,47 @@ import com.pitchedapps.frost.utils.Prefs
|
||||
*/
|
||||
fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
checkbox(R.string.auto_refresh_feed, Prefs::autoRefreshFeed, { Prefs.autoRefreshFeed = it }) {
|
||||
checkbox(R.string.auto_refresh_feed, prefs::autoRefreshFeed, { prefs.autoRefreshFeed = it }) {
|
||||
descRes = R.string.auto_refresh_feed_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.fancy_animations, Prefs::animate, { Prefs.animate = it; animate = it }) {
|
||||
checkbox(R.string.fancy_animations, prefs::animate, { prefs.animate = it; animate = it }) {
|
||||
descRes = R.string.fancy_animations_desc
|
||||
}
|
||||
|
||||
checkbox(
|
||||
R.string.overlay_swipe,
|
||||
Prefs::overlayEnabled,
|
||||
{ Prefs.overlayEnabled = it; shouldRefreshMain() }) {
|
||||
prefs::overlayEnabled,
|
||||
{ prefs.overlayEnabled = it; shouldRefreshMain() }) {
|
||||
descRes = R.string.overlay_swipe_desc
|
||||
}
|
||||
|
||||
checkbox(
|
||||
R.string.overlay_full_screen_swipe,
|
||||
Prefs::overlayFullScreenSwipe,
|
||||
{ Prefs.overlayFullScreenSwipe = it }) {
|
||||
prefs::overlayFullScreenSwipe,
|
||||
{ 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,
|
||||
{ prefs.linksInDefaultApp = it }) {
|
||||
descRes = R.string.open_links_in_default_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.viewpager_swipe, Prefs::viewpagerSwipe, { Prefs.viewpagerSwipe = it }) {
|
||||
checkbox(R.string.viewpager_swipe, prefs::viewpagerSwipe, { prefs.viewpagerSwipe = it }) {
|
||||
descRes = R.string.viewpager_swipe_desc
|
||||
}
|
||||
|
||||
checkbox(
|
||||
R.string.force_message_bottom,
|
||||
Prefs::messageScrollToBottom,
|
||||
{ Prefs.messageScrollToBottom = it }) {
|
||||
prefs::messageScrollToBottom,
|
||||
{ prefs.messageScrollToBottom = it }) {
|
||||
descRes = R.string.force_message_bottom_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.enable_pip, Prefs::enablePip, { Prefs.enablePip = it }) {
|
||||
checkbox(R.string.enable_pip, prefs::enablePip, { prefs.enablePip = it }) {
|
||||
descRes = R.string.enable_pip_desc
|
||||
}
|
||||
|
||||
@ -78,11 +78,11 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
// }
|
||||
// }
|
||||
|
||||
checkbox(R.string.exit_confirmation, Prefs::exitConfirmation, { Prefs.exitConfirmation = it }) {
|
||||
checkbox(R.string.exit_confirmation, prefs::exitConfirmation, { prefs.exitConfirmation = it }) {
|
||||
descRes = R.string.exit_confirmation_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.analytics, Prefs::analytics, { Prefs.analytics = it }) {
|
||||
checkbox(R.string.analytics, prefs::analytics, { prefs.analytics = it }) {
|
||||
descRes = R.string.analytics_desc
|
||||
}
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
// Experimental content ends here --------------------
|
||||
|
||||
checkbox(R.string.verbose_logging, Prefs::verboseLogging, {
|
||||
Prefs.verboseLogging = it
|
||||
checkbox(R.string.verbose_logging, prefs::verboseLogging, {
|
||||
prefs.verboseLogging = it
|
||||
KL.shouldLog = { it != Log.VERBOSE }
|
||||
}) {
|
||||
descRes = R.string.verbose_logging_desc
|
||||
|
@ -31,7 +31,7 @@ import com.pitchedapps.frost.utils.REQUEST_FAB
|
||||
*/
|
||||
fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
text(R.string.newsfeed_sort, Prefs::feedSort, { Prefs.feedSort = it }) {
|
||||
text(R.string.newsfeed_sort, prefs::feedSort, { prefs.feedSort = it }) {
|
||||
descRes = R.string.newsfeed_sort_desc
|
||||
onClick = {
|
||||
materialDialog {
|
||||
@ -50,50 +50,50 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
textGetter = { string(FeedSort(it).textRes) }
|
||||
}
|
||||
|
||||
checkbox(R.string.aggressive_recents, Prefs::aggressiveRecents, {
|
||||
Prefs.aggressiveRecents = it
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
checkbox(R.string.show_stories, prefs::showStories, {
|
||||
prefs.showStories = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
descRes = R.string.show_stories_desc
|
||||
}
|
||||
|
||||
checkbox(R.string.facebook_ads, Prefs::showFacebookAds, {
|
||||
Prefs.showFacebookAds = it
|
||||
checkbox(R.string.facebook_ads, prefs::showFacebookAds, {
|
||||
prefs.showFacebookAds = it
|
||||
shouldRefreshMain()
|
||||
}) {
|
||||
descRes = R.string.facebook_ads_desc
|
||||
|
@ -19,7 +19,6 @@ package com.pitchedapps.frost.settings
|
||||
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.SettingsActivity
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-08-08.
|
||||
@ -28,8 +27,8 @@ fun SettingsActivity.getNetworkPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
checkbox(
|
||||
R.string.network_media_on_metered,
|
||||
{ !Prefs.loadMediaOnMeteredNetwork },
|
||||
{ Prefs.loadMediaOnMeteredNetwork = !it }) {
|
||||
{ !prefs.loadMediaOnMeteredNetwork },
|
||||
{ prefs.loadMediaOnMeteredNetwork = !it }) {
|
||||
descRes = R.string.network_media_on_metered_desc
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import com.pitchedapps.frost.utils.frostSnackbar
|
||||
import com.pitchedapps.frost.utils.frostUri
|
||||
import com.pitchedapps.frost.views.Keywords
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.get
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-29.
|
||||
@ -54,8 +55,8 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
text(
|
||||
R.string.notification_frequency,
|
||||
Prefs::notificationFreq,
|
||||
{ Prefs.notificationFreq = it }) {
|
||||
prefs::notificationFreq,
|
||||
{ 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) }
|
||||
@ -71,7 +72,7 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
}
|
||||
}
|
||||
}
|
||||
enabler = { Prefs.hasNotifications }
|
||||
enabler = { prefs.hasNotifications }
|
||||
textGetter = { minuteToText(it) }
|
||||
}
|
||||
|
||||
@ -88,36 +89,36 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
}
|
||||
}
|
||||
|
||||
checkbox(R.string.notification_general, Prefs::notificationsGeneral,
|
||||
checkbox(R.string.notification_general, prefs::notificationsGeneral,
|
||||
{
|
||||
Prefs.notificationsGeneral = it
|
||||
prefs.notificationsGeneral = it
|
||||
reloadByTitle(R.string.notification_general_all_accounts)
|
||||
if (!Prefs.notificationsInstantMessages)
|
||||
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 }
|
||||
enabler = { prefs.notificationsGeneral }
|
||||
}
|
||||
|
||||
checkbox(R.string.notification_messages, Prefs::notificationsInstantMessages,
|
||||
checkbox(R.string.notification_messages, prefs::notificationsInstantMessages,
|
||||
{
|
||||
Prefs.notificationsInstantMessages = it
|
||||
prefs.notificationsInstantMessages = it
|
||||
reloadByTitle(R.string.notification_messages_all_accounts)
|
||||
if (!Prefs.notificationsGeneral)
|
||||
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 }
|
||||
enabler = { prefs.notificationsInstantMessages }
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
@ -130,8 +131,8 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
checkbox(R.string.notification_sound, Prefs::notificationSound, {
|
||||
Prefs.notificationSound = it
|
||||
checkbox(R.string.notification_sound, prefs::notificationSound, {
|
||||
prefs.notificationSound = it
|
||||
reloadByTitle(
|
||||
R.string.notification_ringtone,
|
||||
R.string.message_ringtone
|
||||
@ -139,7 +140,7 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
})
|
||||
|
||||
fun KPrefText.KPrefTextContract<String>.ringtone(code: Int) {
|
||||
enabler = Prefs::notificationSound
|
||||
enabler = prefs::notificationSound
|
||||
textGetter = {
|
||||
if (it.isBlank()) string(R.string.kau_default)
|
||||
else RingtoneManager.getRingtone(this@getNotificationPrefs, frostUri(it))
|
||||
@ -163,21 +164,21 @@ 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) {
|
||||
|
@ -32,7 +32,7 @@ fun SettingsActivity.getSecurityPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
descRes = R.string.security_disclaimer_info
|
||||
}
|
||||
|
||||
checkbox(R.string.enable_biometrics, Prefs::biometricsEnabled, {
|
||||
checkbox(R.string.enable_biometrics, prefs::biometricsEnabled, {
|
||||
launch {
|
||||
/*
|
||||
* For security, we should request authentication when:
|
||||
@ -40,7 +40,7 @@ fun SettingsActivity.getSecurityPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
* - disabling to ensure that it is permitted
|
||||
*/
|
||||
BiometricUtils.authenticate(this@getSecurityPrefs, force = true).await()
|
||||
Prefs.biometricsEnabled = it
|
||||
prefs.biometricsEnabled = it
|
||||
reloadByTitle(R.string.enable_biometrics)
|
||||
}
|
||||
}) {
|
||||
|
@ -30,6 +30,8 @@ import java.util.concurrent.Executor
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
typealias BiometricDeferred = CompletableDeferred<BiometricPrompt.CryptoObject?>
|
||||
|
||||
@ -37,11 +39,13 @@ typealias BiometricDeferred = CompletableDeferred<BiometricPrompt.CryptoObject?>
|
||||
* Container for [BiometricPrompt]
|
||||
* Inspired by coroutine's CommonPool
|
||||
*/
|
||||
object BiometricUtils {
|
||||
object BiometricUtils : KoinComponent {
|
||||
|
||||
private val executor: Executor
|
||||
get() = pool ?: getOrCreatePoolSync()
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
@Volatile
|
||||
private var pool: ExecutorService? = null
|
||||
|
||||
@ -65,7 +69,7 @@ object BiometricUtils {
|
||||
pool ?: Executors.newSingleThreadExecutor().also { pool = it }
|
||||
|
||||
private fun shouldPrompt(context: Context): Boolean {
|
||||
return Prefs.biometricsEnabled && System.currentTimeMillis() - lastUnlockTime > UNLOCK_TIME_INTERVAL
|
||||
return prefs.biometricsEnabled && System.currentTimeMillis() - lastUnlockTime > UNLOCK_TIME_INTERVAL
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,8 @@ import ca.allanwang.kau.logging.KauLogger
|
||||
import ca.allanwang.kau.logging.KauLoggerExtension
|
||||
import com.bugsnag.android.Bugsnag
|
||||
import com.pitchedapps.frost.BuildConfig
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-28.
|
||||
@ -31,9 +33,11 @@ object L : KauLogger("Frost", {
|
||||
when (it) {
|
||||
Log.VERBOSE -> BuildConfig.DEBUG
|
||||
Log.INFO, Log.ERROR -> true
|
||||
else -> BuildConfig.DEBUG || Prefs.verboseLogging
|
||||
else -> BuildConfig.DEBUG || L.prefs.verboseLogging
|
||||
}
|
||||
}) {
|
||||
}), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
inline fun test(message: () -> Any?) {
|
||||
_d {
|
||||
@ -67,7 +71,7 @@ object L : KauLogger("Frost", {
|
||||
* bugsnagInit is changed per application and helps prevent crashes (if calling pre init)
|
||||
* analytics is changed by the user, and may be toggled throughout the app
|
||||
*/
|
||||
if (BuildConfig.DEBUG || !bugsnagInit || !Prefs.analytics) {
|
||||
if (BuildConfig.DEBUG || !bugsnagInit || !prefs.analytics) {
|
||||
super.logImpl(priority, message, t)
|
||||
} else {
|
||||
if (message != null) {
|
||||
|
@ -19,6 +19,7 @@ package com.pitchedapps.frost.utils
|
||||
import android.graphics.Color
|
||||
import ca.allanwang.kau.kotlin.lazyResettable
|
||||
import ca.allanwang.kau.kpref.KPref
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import ca.allanwang.kau.utils.colorToForeground
|
||||
import ca.allanwang.kau.utils.isColorVisibleOn
|
||||
import ca.allanwang.kau.utils.withAlpha
|
||||
@ -29,13 +30,15 @@ import com.pitchedapps.frost.enums.FeedSort
|
||||
import com.pitchedapps.frost.enums.MainActivityLayout
|
||||
import com.pitchedapps.frost.enums.Theme
|
||||
import com.pitchedapps.frost.injectors.InjectorContract
|
||||
import org.koin.core.context.GlobalContext
|
||||
import org.koin.dsl.module
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-28.
|
||||
*
|
||||
* Shared Preference object with lazy cached retrievals
|
||||
*/
|
||||
object Prefs : KPref() {
|
||||
class Prefs(factory: KPrefFactory) : KPref("${BuildConfig.APPLICATION_ID}.prefs", factory) {
|
||||
|
||||
var lastLaunch: Long by kpref("last_launch", -1L)
|
||||
|
||||
@ -69,7 +72,7 @@ object Prefs : KPref() {
|
||||
|
||||
var identifier: Int by kpref("identifier", -1)
|
||||
|
||||
private val loader = lazyResettable { Theme.values[Prefs.theme] }
|
||||
private val loader = lazyResettable { Theme.values[theme] }
|
||||
|
||||
val t: Theme by loader
|
||||
|
||||
@ -87,9 +90,9 @@ object Prefs : KPref() {
|
||||
}
|
||||
|
||||
inline val nativeBgColor: Int
|
||||
get() = Prefs.bgColor.withAlpha(30)
|
||||
get() = bgColor.withAlpha(30)
|
||||
|
||||
fun nativeBgColor(unread: Boolean) = Prefs.bgColor
|
||||
fun nativeBgColor(unread: Boolean) = bgColor
|
||||
.colorToForeground(if (unread) 0.7f else 0.0f)
|
||||
.withAlpha(30)
|
||||
|
||||
@ -194,5 +197,11 @@ object Prefs : KPref() {
|
||||
inline val mainActivityLayout: MainActivityLayout
|
||||
get() = MainActivityLayout(mainActivityLayoutType)
|
||||
|
||||
override fun deleteKeys() = arrayOf("search_bar")
|
||||
companion object {
|
||||
fun get(): Prefs = GlobalContext.get().koin.get()
|
||||
|
||||
fun module() = module {
|
||||
single { Prefs(get()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,18 +17,25 @@
|
||||
package com.pitchedapps.frost.utils
|
||||
|
||||
import ca.allanwang.kau.kpref.KPref
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import com.pitchedapps.frost.BuildConfig
|
||||
import org.koin.dsl.module
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-03.
|
||||
*
|
||||
* Showcase prefs that offer one time helpers to guide new users
|
||||
*/
|
||||
object Showcase : KPref() {
|
||||
class Showcase(factory: KPrefFactory) : KPref("${BuildConfig.APPLICATION_ID}.showcase", factory) {
|
||||
|
||||
// check if this is the first time launching the web overlay; show snackbar if true
|
||||
val firstWebOverlay: Boolean by kprefSingle("first_web_overlay")
|
||||
|
||||
val intro: Boolean by kprefSingle("intro_pages")
|
||||
|
||||
override fun deleteKeys() = arrayOf("shown_release", "experimental_by_default")
|
||||
companion object {
|
||||
fun module() = module {
|
||||
single { Showcase(get()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.snackbar.SnackbarContentLayout
|
||||
import com.pitchedapps.frost.BuildConfig
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.BaseActivity
|
||||
import com.pitchedapps.frost.activities.ImageActivity
|
||||
import com.pitchedapps.frost.activities.LoginActivity
|
||||
import com.pitchedapps.frost.activities.SelectorActivity
|
||||
@ -69,10 +70,6 @@ import com.pitchedapps.frost.facebook.formattedFbUri
|
||||
import com.pitchedapps.frost.facebook.formattedFbUrl
|
||||
import com.pitchedapps.frost.injectors.CssAssets
|
||||
import com.pitchedapps.frost.injectors.JsAssets
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
@ -81,6 +78,13 @@ import org.apache.commons.text.StringEscapeUtils
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.context.GlobalContext
|
||||
import org.koin.core.inject
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-03.
|
||||
@ -124,6 +128,7 @@ fun Activity.cookies(): ArrayList<CookieEntity> {
|
||||
* See [requestWebOverlay] to verify the launch
|
||||
*/
|
||||
private inline fun <reified T : WebOverlayActivityBase> Context.launchWebOverlayImpl(url: String) {
|
||||
val prefs = Prefs.get()
|
||||
val argUrl = url.formattedFbUrl
|
||||
L.v { "Launch received: $url\nLaunch web overlay: $argUrl" }
|
||||
if (argUrl.isFacebookUrl && argUrl.contains("/logout.php")) {
|
||||
@ -131,10 +136,11 @@ private inline fun <reified T : WebOverlayActivityBase> Context.launchWebOverlay
|
||||
ctxCoroutine.launch {
|
||||
FbCookie.logout(this@launchWebOverlayImpl)
|
||||
}
|
||||
} else if (!(Prefs.linksInDefaultApp && resolveActivityForUri(Uri.parse(argUrl))))
|
||||
} else if (!(prefs.linksInDefaultApp && resolveActivityForUri(Uri.parse(argUrl)))) {
|
||||
startActivity<T>(false, intentBuilder = {
|
||||
putExtra(ARG_URL, argUrl)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.launchWebOverlay(url: String) = launchWebOverlayImpl<WebOverlayActivity>(url)
|
||||
@ -172,22 +178,24 @@ fun WebOverlayActivity.url(): String {
|
||||
}
|
||||
|
||||
fun Activity.setFrostTheme(forceTransparent: Boolean = false) {
|
||||
val prefs = Prefs.get()
|
||||
val isTransparent =
|
||||
forceTransparent || (Color.alpha(Prefs.bgColor) != 255) || (Color.alpha(Prefs.headerColor) != 255)
|
||||
if (Prefs.bgColor.isColorDark) {
|
||||
forceTransparent || (Color.alpha(prefs.bgColor) != 255) || (Color.alpha(prefs.headerColor) != 255)
|
||||
if (prefs.bgColor.isColorDark) {
|
||||
setTheme(if (isTransparent) R.style.FrostTheme_Transparent else R.style.FrostTheme)
|
||||
} else {
|
||||
setTheme(if (isTransparent) R.style.FrostTheme_Light_Transparent else R.style.FrostTheme_Light)
|
||||
}
|
||||
}
|
||||
|
||||
class ActivityThemeUtils {
|
||||
class ActivityThemeUtils : KoinComponent {
|
||||
|
||||
private var toolbar: Toolbar? = null
|
||||
var themeWindow = true
|
||||
private var texts = mutableListOf<TextView>()
|
||||
private var headers = mutableListOf<View>()
|
||||
private var backgrounds = mutableListOf<View>()
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
fun toolbar(toolbar: Toolbar) {
|
||||
this.toolbar = toolbar
|
||||
@ -207,15 +215,15 @@ class ActivityThemeUtils {
|
||||
|
||||
fun theme(activity: Activity) {
|
||||
with(activity) {
|
||||
statusBarColor = Prefs.headerColor.darken(0.1f).withAlpha(255)
|
||||
if (Prefs.tintNavBar) navigationBarColor = Prefs.headerColor
|
||||
if (themeWindow) window.setBackgroundDrawable(ColorDrawable(Prefs.bgColor))
|
||||
toolbar?.setBackgroundColor(Prefs.headerColor)
|
||||
toolbar?.setTitleTextColor(Prefs.iconColor)
|
||||
toolbar?.overflowIcon?.setTint(Prefs.iconColor)
|
||||
texts.forEach { it.setTextColor(Prefs.textColor) }
|
||||
headers.forEach { it.setBackgroundColor(Prefs.headerColor) }
|
||||
backgrounds.forEach { it.setBackgroundColor(Prefs.bgColor) }
|
||||
statusBarColor = prefs.headerColor.darken(0.1f).withAlpha(255)
|
||||
if (prefs.tintNavBar) navigationBarColor = prefs.headerColor
|
||||
if (themeWindow) window.setBackgroundDrawable(ColorDrawable(prefs.bgColor))
|
||||
toolbar?.setBackgroundColor(prefs.headerColor)
|
||||
toolbar?.setTitleTextColor(prefs.iconColor)
|
||||
toolbar?.overflowIcon?.setTint(prefs.iconColor)
|
||||
texts.forEach { it.setTextColor(prefs.textColor) }
|
||||
headers.forEach { it.setBackgroundColor(prefs.headerColor) }
|
||||
backgrounds.forEach { it.setBackgroundColor(prefs.bgColor) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -248,18 +256,20 @@ fun View.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {})
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
private inline fun frostSnackbar(crossinline builder: Snackbar.() -> Unit): Snackbar.() -> Unit = {
|
||||
val prefs = Prefs.get()
|
||||
builder()
|
||||
// hacky workaround, but it has proper checks and shouldn't crash
|
||||
((view as? FrameLayout)?.getChildAt(0) as? SnackbarContentLayout)?.apply {
|
||||
messageView.setTextColor(Prefs.textColor)
|
||||
actionView.setTextColor(Prefs.accentColor)
|
||||
messageView.setTextColor(prefs.textColor)
|
||||
actionView.setTextColor(prefs.accentColor)
|
||||
// only set if previous text colors are set
|
||||
view.setBackgroundColor(Prefs.bgColor.withAlpha(255).colorToForeground(0.1f))
|
||||
view.setBackgroundColor(prefs.bgColor.withAlpha(255).colorToForeground(0.1f))
|
||||
}
|
||||
}
|
||||
|
||||
fun Activity.frostNavigationBar() {
|
||||
navigationBarColor = if (Prefs.tintNavBar) Prefs.headerColor else Color.BLACK
|
||||
val prefs = Prefs.get()
|
||||
navigationBarColor = if (prefs.tintNavBar) prefs.headerColor else Color.BLACK
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
@ -393,10 +403,11 @@ inline fun Context.sendFrostEmail(subjectId: String, crossinline builder: EmailB
|
||||
}
|
||||
|
||||
fun EmailBuilder.addFrostDetails() {
|
||||
addItem("Prev version", Prefs.prevVersionCode.toString())
|
||||
val prefs = Prefs.get()
|
||||
addItem("Prev version", prefs.prevVersionCode.toString())
|
||||
val proTag = "FO"
|
||||
// if (IS_FROST_PRO) "TY" else "FP"
|
||||
addItem("Random Frost ID", "${Prefs.frostId}-$proTag")
|
||||
addItem("Random Frost ID", "${prefs.frostId}-$proTag")
|
||||
addItem("Locale", Locale.getDefault().displayName)
|
||||
}
|
||||
|
||||
@ -438,7 +449,7 @@ fun String.unescapeHtml(): String =
|
||||
.replace("\\u003C", "<")
|
||||
.replace("\\\"", "\"")
|
||||
|
||||
suspend fun Context.loadAssets(): Unit = coroutineScope {
|
||||
CssAssets.load(this@loadAssets)
|
||||
suspend fun Context.loadAssets(prefs: Prefs): Unit = coroutineScope {
|
||||
CssAssets.load(this@loadAssets, prefs)
|
||||
JsAssets.load(this@loadAssets)
|
||||
}
|
||||
|
@ -38,18 +38,23 @@ import com.pitchedapps.frost.facebook.profilePictureUrl
|
||||
import com.pitchedapps.frost.glide.FrostGlide
|
||||
import com.pitchedapps.frost.glide.GlideApp
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-05.
|
||||
*/
|
||||
class AccountItem(val cookie: CookieEntity?) : KauIItem<AccountItem.ViewHolder>
|
||||
(R.layout.view_account, { ViewHolder(it) }, R.id.item_account) {
|
||||
class AccountItem(val cookie: CookieEntity?) :
|
||||
KauIItem<AccountItem.ViewHolder>(R.layout.view_account, { ViewHolder(it) }, R.id.item_account) ,
|
||||
KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) {
|
||||
super.bindView(holder, payloads)
|
||||
with(holder) {
|
||||
text.invisible()
|
||||
text.setTextColor(Prefs.textColor)
|
||||
text.setTextColor(prefs.textColor)
|
||||
if (cookie != null) {
|
||||
text.text = cookie.name
|
||||
GlideApp.with(itemView).load(profilePictureUrl(cookie.id))
|
||||
@ -81,7 +86,7 @@ class AccountItem(val cookie: CookieEntity?) : KauIItem<AccountItem.ViewHolder>
|
||||
GoogleMaterial.Icon.gmd_add_circle_outline.toDrawable(
|
||||
itemView.context,
|
||||
100,
|
||||
Prefs.textColor
|
||||
prefs.textColor
|
||||
)
|
||||
)
|
||||
text.text = itemView.context.getString(R.string.kau_add_account)
|
||||
|
@ -30,6 +30,8 @@ import ca.allanwang.kau.utils.withAlpha
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.pitchedapps.frost.databinding.ViewBadgedIconBinding
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-19.
|
||||
@ -38,8 +40,10 @@ class BadgedIcon @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr), KoinComponent {
|
||||
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
private val binding: ViewBadgedIconBinding =
|
||||
ViewBadgedIconBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
|
||||
@ -49,7 +53,7 @@ class BadgedIcon @JvmOverloads constructor(
|
||||
|
||||
fun ViewBadgedIconBinding.init() {
|
||||
val badgeColor =
|
||||
Prefs.mainActivityLayout.backgroundColor().withAlpha(255).colorToForeground(0.2f)
|
||||
prefs.mainActivityLayout.backgroundColor(prefs).withAlpha(255).colorToForeground(0.2f)
|
||||
val badgeBackground =
|
||||
GradientDrawable(
|
||||
GradientDrawable.Orientation.BOTTOM_TOP,
|
||||
@ -57,7 +61,7 @@ class BadgedIcon @JvmOverloads constructor(
|
||||
)
|
||||
badgeBackground.cornerRadius = 13.dpToPx.toFloat()
|
||||
badgeText.background = badgeBackground
|
||||
badgeText.setTextColor(Prefs.mainActivityLayout.iconColor())
|
||||
badgeText.setTextColor(prefs.mainActivityLayout.iconColor(prefs))
|
||||
}
|
||||
|
||||
var iicon: IIcon? = null
|
||||
@ -67,13 +71,13 @@ class BadgedIcon @JvmOverloads constructor(
|
||||
value?.toDrawable(
|
||||
context,
|
||||
sizeDp = 20,
|
||||
color = Prefs.mainActivityLayout.iconColor()
|
||||
color = prefs.mainActivityLayout.iconColor(prefs)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun setAllAlpha(alpha: Float) {
|
||||
// badgeTextView.setTextColor(Prefs.textColor.withAlpha(alpha.toInt()))
|
||||
// badgeTextView.setTextColor(prefs.textColor.withAlpha(alpha.toInt()))
|
||||
binding.badgeImage.drawable.alpha = alpha.toInt()
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.BroadcastChannel
|
||||
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
class FrostContentWeb @JvmOverloads constructor(
|
||||
context: Context,
|
||||
@ -75,8 +77,9 @@ abstract class FrostContentView<out T> @JvmOverloads constructor(
|
||||
defStyleAttr: Int = 0,
|
||||
defStyleRes: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr, defStyleRes),
|
||||
FrostContentParent where T : View, T : FrostContentCore {
|
||||
FrostContentParent, KoinComponent where T : View, T : FrostContentCore {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
private val refresh: SwipeRefreshLayout by bindView(R.id.content_refresh)
|
||||
private val progress: ProgressBar by bindView(R.id.content_progress)
|
||||
val coreView: T by bindView(R.id.content_core)
|
||||
@ -153,9 +156,9 @@ abstract class FrostContentView<out T> @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun reloadThemeSelf() {
|
||||
progress.tint(Prefs.textColor.withAlpha(180))
|
||||
refresh.setColorSchemeColors(Prefs.iconColor)
|
||||
refresh.setProgressBackgroundColorSchemeColor(Prefs.headerColor.withAlpha(255))
|
||||
progress.tint(prefs.textColor.withAlpha(180))
|
||||
refresh.setColorSchemeColors(prefs.iconColor)
|
||||
refresh.setProgressBackgroundColorSchemeColor(prefs.headerColor.withAlpha(255))
|
||||
}
|
||||
|
||||
override fun reloadTextSizeSelf() {
|
||||
@ -192,7 +195,7 @@ abstract class FrostContentView<out T> @JvmOverloads constructor(
|
||||
if (isVisible)
|
||||
fadeOut(duration = 200L)
|
||||
} else if (loading) {
|
||||
if (animate && Prefs.animate) circularReveal(offset = WEB_LOAD_DELAY)
|
||||
if (animate && prefs.animate) circularReveal(offset = WEB_LOAD_DELAY)
|
||||
else fadeIn(duration = 200L, offset = WEB_LOAD_DELAY)
|
||||
L.v { "Transition loaded in ${System.currentTimeMillis() - transitionStart} ms" }
|
||||
receiver.cancel()
|
||||
|
@ -30,6 +30,8 @@ import com.pitchedapps.frost.fragments.RecyclerContentContract
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-29.
|
||||
@ -41,8 +43,11 @@ class FrostRecyclerView @JvmOverloads constructor(
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : RecyclerView(context, attrs, defStyleAttr),
|
||||
KoinComponent,
|
||||
FrostContentCore {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
override fun reload(animate: Boolean) = reloadBase(animate)
|
||||
|
||||
override lateinit var parent: FrostContentParent
|
||||
@ -71,13 +76,13 @@ class FrostRecyclerView @JvmOverloads constructor(
|
||||
var onReloadClear: () -> Unit = {}
|
||||
|
||||
override fun reloadBase(animate: Boolean) {
|
||||
if (Prefs.animate) fadeOut(onFinish = onReloadClear)
|
||||
if (prefs.animate) fadeOut(onFinish = onReloadClear)
|
||||
scope.launch {
|
||||
parent.refreshChannel.offer(true)
|
||||
recyclerContract.reload { parent.progressChannel.offer(it) }
|
||||
parent.progressChannel.offer(100)
|
||||
parent.refreshChannel.offer(false)
|
||||
if (Prefs.animate) circularReveal()
|
||||
if (prefs.animate) circularReveal()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,8 @@ import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.ctxCoroutine
|
||||
import com.pitchedapps.frost.utils.frostDownload
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-10-13.
|
||||
@ -55,7 +57,7 @@ class FrostVideoViewer @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr), FrostVideoViewerContract {
|
||||
) : FrameLayout(context, attrs, defStyleAttr), FrostVideoViewerContract , KoinComponent {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
@ -85,6 +87,8 @@ class FrostVideoViewer @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
private val binding: ViewVideoBinding =
|
||||
ViewVideoBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
|
||||
@ -95,8 +99,8 @@ class FrostVideoViewer @JvmOverloads constructor(
|
||||
fun ViewVideoBinding.init() {
|
||||
alpha = 0f
|
||||
videoBackground.setBackgroundColor(
|
||||
if (!Prefs.blackMediaBg && Prefs.bgColor.isColorDark)
|
||||
Prefs.bgColor.withMinAlpha(200)
|
||||
if (!prefs.blackMediaBg && prefs.bgColor.isColorDark)
|
||||
prefs.bgColor.withMinAlpha(200)
|
||||
else
|
||||
Color.BLACK
|
||||
)
|
||||
@ -104,7 +108,7 @@ class FrostVideoViewer @JvmOverloads constructor(
|
||||
video.pause()
|
||||
videoToolbar.inflateMenu(R.menu.menu_video)
|
||||
context.setMenuIcons(
|
||||
videoToolbar.menu, Prefs.iconColor,
|
||||
videoToolbar.menu, prefs.iconColor,
|
||||
R.id.action_pip to GoogleMaterial.Icon.gmd_picture_in_picture_alt,
|
||||
R.id.action_download to GoogleMaterial.Icon.gmd_file_download
|
||||
)
|
||||
|
@ -22,6 +22,8 @@ import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-07.
|
||||
@ -29,12 +31,14 @@ import com.pitchedapps.frost.utils.Prefs
|
||||
* Basic override to allow us to control swiping
|
||||
*/
|
||||
class FrostViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
ViewPager(context, attrs) {
|
||||
ViewPager(context, attrs), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
var enableSwipe = true
|
||||
|
||||
override fun onInterceptTouchEvent(ev: MotionEvent?) =
|
||||
try {
|
||||
Prefs.viewpagerSwipe && enableSwipe && super.onInterceptTouchEvent(ev)
|
||||
prefs.viewpagerSwipe && enableSwipe && super.onInterceptTouchEvent(ev)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
false
|
||||
}
|
||||
@ -42,7 +46,7 @@ class FrostViewPager @JvmOverloads constructor(context: Context, attrs: Attribut
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onTouchEvent(ev: MotionEvent?): Boolean =
|
||||
try {
|
||||
Prefs.viewpagerSwipe && enableSwipe && super.onTouchEvent(ev)
|
||||
prefs.viewpagerSwipe && enableSwipe && super.onTouchEvent(ev)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
false
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ import com.pitchedapps.frost.web.FrostChromeClient
|
||||
import com.pitchedapps.frost.web.FrostJSI
|
||||
import com.pitchedapps.frost.web.FrostWebViewClient
|
||||
import com.pitchedapps.frost.web.NestedWebView
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
@ -54,7 +56,10 @@ class FrostWebView @JvmOverloads constructor(
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : NestedWebView(context, attrs, defStyleAttr),
|
||||
FrostContentCore {
|
||||
FrostContentCore,
|
||||
KoinComponent {
|
||||
|
||||
val prefs: Prefs by inject()
|
||||
|
||||
override fun reload(animate: Boolean) {
|
||||
if (parent.registerTransition(false, animate))
|
||||
@ -75,7 +80,7 @@ class FrostWebView @JvmOverloads constructor(
|
||||
javaScriptEnabled = true
|
||||
mediaPlaybackRequiresUserGesture = false // TODO check if we need this
|
||||
allowFileAccess = true
|
||||
textZoom = Prefs.webTextScaling
|
||||
textZoom = prefs.webTextScaling
|
||||
domStorageEnabled = true
|
||||
}
|
||||
setLayerType(LAYER_TYPE_HARDWARE, null)
|
||||
@ -208,7 +213,7 @@ class FrostWebView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun reloadTextSizeSelf() {
|
||||
settings.textZoom = Prefs.webTextScaling
|
||||
settings.textZoom = prefs.webTextScaling
|
||||
}
|
||||
|
||||
override fun destroy() {
|
||||
|
@ -38,6 +38,8 @@ import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-06-19.
|
||||
@ -46,8 +48,9 @@ class Keywords @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
val editText: AppCompatEditText by bindView(R.id.edit_text)
|
||||
val addIcon: ImageView by bindView(R.id.add_icon)
|
||||
val recycler: RecyclerView by bindView(R.id.recycler)
|
||||
@ -55,8 +58,8 @@ class Keywords @JvmOverloads constructor(
|
||||
|
||||
init {
|
||||
inflate(context, R.layout.view_keywords, this)
|
||||
editText.tint(Prefs.textColor)
|
||||
addIcon.setImageDrawable(GoogleMaterial.Icon.gmd_add.keywordDrawable(context))
|
||||
editText.tint(prefs.textColor)
|
||||
addIcon.setImageDrawable(GoogleMaterial.Icon.gmd_add.keywordDrawable(context, prefs))
|
||||
addIcon.setOnClickListener {
|
||||
if (editText.text.isNullOrEmpty()) editText.error =
|
||||
context.string(R.string.empty_keyword)
|
||||
@ -65,7 +68,7 @@ class Keywords @JvmOverloads constructor(
|
||||
editText.text?.clear()
|
||||
}
|
||||
}
|
||||
adapter.add(Prefs.notificationKeywords.map { KeywordItem(it) })
|
||||
adapter.add(prefs.notificationKeywords.map { KeywordItem(it) })
|
||||
recycler.layoutManager = LinearLayoutManager(context)
|
||||
recycler.adapter = adapter
|
||||
adapter.addEventHook(object : ClickEventHook<KeywordItem>() {
|
||||
@ -84,12 +87,12 @@ class Keywords @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
fun save() {
|
||||
Prefs.notificationKeywords = adapter.adapterItems.mapTo(mutableSetOf()) { it.keyword }
|
||||
prefs.notificationKeywords = adapter.adapterItems.mapTo(mutableSetOf()) { it.keyword }
|
||||
}
|
||||
}
|
||||
|
||||
private fun IIcon.keywordDrawable(context: Context): Drawable =
|
||||
toDrawable(context, 20, Prefs.textColor)
|
||||
private fun IIcon.keywordDrawable(context: Context, prefs: Prefs): Drawable =
|
||||
toDrawable(context, 20, prefs.textColor)
|
||||
|
||||
class KeywordItem(val keyword: String) : AbstractItem<KeywordItem.ViewHolder>() {
|
||||
|
||||
@ -111,13 +114,15 @@ class KeywordItem(val keyword: String) : AbstractItem<KeywordItem.ViewHolder>()
|
||||
holder.text.text = null
|
||||
}
|
||||
|
||||
class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
|
||||
class ViewHolder(v: View) : RecyclerView.ViewHolder(v), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
val text: AppCompatTextView by bindView(R.id.keyword_text)
|
||||
val delete: ImageView by bindView(R.id.keyword_delete)
|
||||
|
||||
init {
|
||||
text.setTextColor(Prefs.textColor)
|
||||
delete.setImageDrawable(GoogleMaterial.Icon.gmd_delete.keywordDrawable(itemView.context))
|
||||
text.setTextColor(prefs.textColor)
|
||||
delete.setImageDrawable(GoogleMaterial.Icon.gmd_delete.keywordDrawable(itemView.context, prefs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ import com.pitchedapps.frost.utils.isFacebookUrl
|
||||
import java.io.File
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2018-01-05.
|
||||
@ -44,8 +46,9 @@ class DebugWebView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : WebView(context, attrs, defStyleAttr) {
|
||||
) : WebView(context, attrs, defStyleAttr), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
var onPageFinished: (String?) -> Unit = {}
|
||||
|
||||
init {
|
||||
@ -93,7 +96,7 @@ class DebugWebView @JvmOverloads constructor(
|
||||
|
||||
private fun injectBackgroundColor() {
|
||||
setBackgroundColor(
|
||||
if (url.isFacebookUrl) Prefs.bgColor.withAlpha(255)
|
||||
if (url.isFacebookUrl) prefs.bgColor.withAlpha(255)
|
||||
else Color.WHITE
|
||||
)
|
||||
}
|
||||
@ -104,15 +107,16 @@ class DebugWebView @JvmOverloads constructor(
|
||||
if (url.isFacebookUrl)
|
||||
view.jsInject(
|
||||
// CssHider.CORE,
|
||||
CssHider.COMPOSER.maybe(!Prefs.showComposer),
|
||||
CssHider.STORIES.maybe(!Prefs.showStories),
|
||||
CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
|
||||
CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
|
||||
Prefs.themeInjector,
|
||||
CssHider.COMPOSER.maybe(!prefs.showComposer),
|
||||
CssHider.STORIES.maybe(!prefs.showStories),
|
||||
CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!prefs.showSuggestedFriends),
|
||||
CssHider.SUGGESTED_GROUPS.maybe(!prefs.showSuggestedGroups),
|
||||
prefs.themeInjector,
|
||||
CssHider.NON_RECENT.maybe(
|
||||
(url?.contains("?sk=h_chr") ?: false) &&
|
||||
Prefs.aggressiveRecents
|
||||
)
|
||||
prefs.aggressiveRecents
|
||||
),
|
||||
prefs= prefs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import kotlinx.coroutines.launch
|
||||
*/
|
||||
class FrostJSI(val web: FrostWebView) {
|
||||
|
||||
private val prefs: Prefs = web.prefs
|
||||
private val context: Context = web.context
|
||||
private val activity: MainActivity? = context as? MainActivity
|
||||
private val header: SendChannel<String>? = activity?.headerBadgeChannel
|
||||
@ -57,7 +58,7 @@ class FrostJSI(val web: FrostWebView) {
|
||||
|
||||
@JavascriptInterface
|
||||
fun loadVideo(url: String?, isGif: Boolean): Boolean =
|
||||
if (url != null && Prefs.enablePip) {
|
||||
if (url != null && prefs.enablePip) {
|
||||
web.post {
|
||||
(context as? VideoViewHolder)?.showVideo(url, isGif)
|
||||
?: L.e { "Could not load video; contract not implemented" }
|
||||
|
@ -76,7 +76,7 @@ fun FrostWebView.requestWebOverlay(url: String): Boolean {
|
||||
L.d { "Forbid overlay switch" }
|
||||
return false
|
||||
}
|
||||
if (!Prefs.overlayEnabled) return false
|
||||
if (!prefs.overlayEnabled) return false
|
||||
if (context is WebOverlayActivityBase) {
|
||||
val shouldUseDesktop = url.isFacebookUrl
|
||||
// already overlay; manage user agent
|
||||
|
@ -42,6 +42,8 @@ import com.pitchedapps.frost.utils.launchImageActivity
|
||||
import com.pitchedapps.frost.utils.resolveActivityForUri
|
||||
import com.pitchedapps.frost.views.FrostWebView
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-31.
|
||||
@ -67,6 +69,7 @@ open class BaseWebViewClient : WebViewClient() {
|
||||
*/
|
||||
open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
|
||||
private val prefs: Prefs get() = web.prefs
|
||||
private val refresh: SendChannel<Boolean> = web.parent.refreshChannel
|
||||
private val isMain = web.parent.baseEnum != null
|
||||
/**
|
||||
@ -102,7 +105,7 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
web.setBackgroundColor(
|
||||
when {
|
||||
isMain -> Color.TRANSPARENT
|
||||
web.url.isFacebookUrl -> Prefs.bgColor.withAlpha(255)
|
||||
web.url.isFacebookUrl -> prefs.bgColor.withAlpha(255)
|
||||
else -> Color.WHITE
|
||||
}
|
||||
)
|
||||
@ -115,21 +118,22 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
view.jsInject(
|
||||
// CssHider.CORE,
|
||||
CssHider.HEADER,
|
||||
CssHider.COMPOSER.maybe(!Prefs.showComposer),
|
||||
CssHider.STORIES.maybe(!Prefs.showStories),
|
||||
CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
|
||||
CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
|
||||
Prefs.themeInjector,
|
||||
CssHider.COMPOSER.maybe(!prefs.showComposer),
|
||||
CssHider.STORIES.maybe(!prefs.showStories),
|
||||
CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!prefs.showSuggestedFriends),
|
||||
CssHider.SUGGESTED_GROUPS.maybe(!prefs.showSuggestedGroups),
|
||||
prefs.themeInjector,
|
||||
CssHider.NON_RECENT.maybe(
|
||||
(web.url?.contains("?sk=h_chr") ?: false) &&
|
||||
Prefs.aggressiveRecents
|
||||
prefs.aggressiveRecents
|
||||
),
|
||||
JsAssets.DOCUMENT_WATCHER,
|
||||
JsAssets.HORIZONTAL_SCROLLING,
|
||||
JsAssets.CLICK_A,
|
||||
CssHider.ADS.maybe(!Prefs.showFacebookAds),
|
||||
CssHider.ADS.maybe(!prefs.showFacebookAds),
|
||||
JsAssets.CONTEXT_A,
|
||||
JsAssets.MEDIA
|
||||
JsAssets.MEDIA,
|
||||
prefs = prefs
|
||||
)
|
||||
} else {
|
||||
refresh.offer(false)
|
||||
@ -147,7 +151,7 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
}
|
||||
|
||||
internal open fun onPageFinishedActions(url: String) {
|
||||
if (url.startsWith("${FbItem.MESSAGES.url}/read/") && Prefs.messageScrollToBottom) {
|
||||
if (url.startsWith("${FbItem.MESSAGES.url}/read/") && prefs.messageScrollToBottom) {
|
||||
web.pageDown(true)
|
||||
}
|
||||
injectAndFinish()
|
||||
@ -160,7 +164,8 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
web.jsInject(
|
||||
JsActions.LOGIN_CHECK,
|
||||
JsAssets.TEXTAREA_LISTENER,
|
||||
JsAssets.HEADER_BADGES.maybe(isMain)
|
||||
JsAssets.HEADER_BADGES.maybe(isMain),
|
||||
prefs = prefs
|
||||
)
|
||||
}
|
||||
|
||||
@ -207,7 +212,7 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
if (url.isImageUrl) {
|
||||
return launchImage(url.formattedFbUrl)
|
||||
}
|
||||
if (Prefs.linksInDefaultApp && view.context.resolveActivityForUri(request.url)) {
|
||||
if (prefs.linksInDefaultApp && view.context.resolveActivityForUri(request.url)) {
|
||||
return true
|
||||
}
|
||||
// Convert desktop urls to mobile ones
|
||||
@ -229,12 +234,14 @@ private const val EMIT_FINISH = 0
|
||||
*/
|
||||
class FrostWebViewClientMenu(web: FrostWebView) : FrostWebViewClient(web) {
|
||||
|
||||
private val prefs: Prefs get() = web.prefs
|
||||
|
||||
override fun onPageFinished(view: WebView, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
if (url == null) {
|
||||
return
|
||||
}
|
||||
jsInject(JsAssets.MENU)
|
||||
jsInject(JsAssets.MENU, prefs = prefs)
|
||||
}
|
||||
|
||||
override fun emit(flag: Int) {
|
||||
|
@ -42,6 +42,8 @@ import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.isFacebookUrl
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-29.
|
||||
@ -50,8 +52,9 @@ class LoginWebView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : WebView(context, attrs, defStyleAttr) {
|
||||
) : WebView(context, attrs, defStyleAttr), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
private val completable: CompletableDeferred<CookieEntity> = CompletableDeferred()
|
||||
private lateinit var progressCallback: (Int) -> Unit
|
||||
|
||||
@ -101,7 +104,8 @@ class LoginWebView @JvmOverloads constructor(
|
||||
if (url.isFacebookUrl)
|
||||
view.jsInject(
|
||||
CssHider.CORE,
|
||||
Prefs.themeInjector
|
||||
prefs.themeInjector,
|
||||
prefs = prefs
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,9 @@ import com.pitchedapps.frost.utils.toReadableTime
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
class NotificationWidget : AppWidgetProvider() {
|
||||
class NotificationWidget : AppWidgetProvider(), KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
override fun onUpdate(
|
||||
context: Context,
|
||||
@ -59,19 +61,19 @@ class NotificationWidget : AppWidgetProvider() {
|
||||
) {
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
||||
val type = NotificationType.GENERAL
|
||||
val userId = Prefs.userId
|
||||
val userId = prefs.userId
|
||||
val intent = NotificationWidgetService.createIntent(context, type, userId)
|
||||
for (id in appWidgetIds) {
|
||||
val views = RemoteViews(context.packageName, R.layout.widget_notifications)
|
||||
|
||||
views.setBackgroundColor(R.id.widget_layout_toolbar, Prefs.headerColor)
|
||||
views.setIcon(R.id.img_frost, context, R.drawable.frost_f_24, Prefs.iconColor)
|
||||
views.setBackgroundColor(R.id.widget_layout_toolbar, prefs.headerColor)
|
||||
views.setIcon(R.id.img_frost, context, R.drawable.frost_f_24, prefs.iconColor)
|
||||
views.setOnClickPendingIntent(
|
||||
R.id.img_frost,
|
||||
PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), 0)
|
||||
)
|
||||
|
||||
views.setBackgroundColor(R.id.widget_notification_list, Prefs.bgColor)
|
||||
views.setBackgroundColor(R.id.widget_notification_list, prefs.bgColor)
|
||||
views.setRemoteAdapter(R.id.widget_notification_list, intent)
|
||||
|
||||
val pendingIntentTemplate = PendingIntent.getActivity(
|
||||
@ -149,6 +151,8 @@ class NotificationWidgetDataProvider(val context: Context, val intent: Intent) :
|
||||
RemoteViewsService.RemoteViewsFactory,
|
||||
KoinComponent {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
|
||||
private val notifDao: NotificationDao by inject()
|
||||
@Volatile
|
||||
private var content: List<NotificationContent> = emptyList()
|
||||
@ -182,10 +186,10 @@ class NotificationWidgetDataProvider(val context: Context, val intent: Intent) :
|
||||
val views = RemoteViews(context.packageName, R.layout.widget_notification_item)
|
||||
try {
|
||||
val notif = content[position]
|
||||
views.setBackgroundColor(R.id.item_frame, Prefs.nativeBgColor(notif.unread))
|
||||
views.setTextColor(R.id.item_content, Prefs.textColor)
|
||||
views.setBackgroundColor(R.id.item_frame, prefs.nativeBgColor(notif.unread))
|
||||
views.setTextColor(R.id.item_content, prefs.textColor)
|
||||
views.setTextViewText(R.id.item_content, notif.text)
|
||||
views.setTextColor(R.id.item_date, Prefs.textColor.withAlpha(150))
|
||||
views.setTextColor(R.id.item_date, prefs.textColor.withAlpha(150))
|
||||
views.setTextViewText(R.id.item_date, notif.timestamp.toReadableTime(context))
|
||||
|
||||
val avatar = glide.load(notif.profileUrl).transform(FrostGlide.circleCrop)
|
||||
|
@ -16,7 +16,7 @@ org.gradle.daemon = true
|
||||
APP_ID=Frost
|
||||
APP_GROUP=com.pitchedapps
|
||||
|
||||
KAU=e4bba6f
|
||||
KAU=5038b93
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
Loading…
Reference in New Issue
Block a user