mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-11-08 12:02:33 +01:00
Merge pull request #1647 from AllanWang/kpref
Remove stateful singletons
This commit is contained in:
commit
654cc6b943
@ -48,7 +48,7 @@ android {
|
||||
throw new GradleException("Version name mismatch, expected ${androidGitVersion.name()}, got $versionName")
|
||||
}
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunner "com.pitchedapps.frost.FrostTestRunner"
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments = ["room.schemaLocation": "$projectDir/src/schemas".toString()]
|
||||
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2020 Allan Wang
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.pitchedapps.frost
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.test.runner.AndroidJUnitRunner
|
||||
import ca.allanwang.kau.kpref.KPrefFactory
|
||||
import ca.allanwang.kau.kpref.KPrefFactoryInMemory
|
||||
import com.pitchedapps.frost.db.FrostDatabase
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.Showcase
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
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
|
||||
|
||||
class FrostTestRunner : AndroidJUnitRunner() {
|
||||
override fun newApplication(
|
||||
cl: ClassLoader?,
|
||||
className: String?,
|
||||
context: Context?
|
||||
): Application {
|
||||
return super.newApplication(cl, FrostTestApp::class.java.name, context)
|
||||
}
|
||||
}
|
||||
|
||||
class FrostTestRule : TestRule {
|
||||
override fun apply(base: Statement, description: Description): Statement =
|
||||
object : Statement(), KoinComponent {
|
||||
override fun evaluate() {
|
||||
|
||||
// Reset prefs
|
||||
get<Prefs>().reset()
|
||||
get<Showcase>().reset()
|
||||
|
||||
base.evaluate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FrostTestApp : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
startKoin {
|
||||
androidLogger()
|
||||
androidContext(this@FrostTestApp)
|
||||
modules(
|
||||
listOf(
|
||||
FrostDatabase.module(),
|
||||
prefFactoryModule(),
|
||||
Prefs.module(),
|
||||
Showcase.module(),
|
||||
FbCookie.module()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun prefFactoryModule(): Module = module {
|
||||
single<KPrefFactory> {
|
||||
KPrefFactoryInMemory
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ package com.pitchedapps.frost.activities
|
||||
import android.content.Intent
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import com.pitchedapps.frost.FrostTestRule
|
||||
import com.pitchedapps.frost.helper.getResource
|
||||
import com.pitchedapps.frost.utils.ARG_COOKIE
|
||||
import com.pitchedapps.frost.utils.ARG_IMAGE_URL
|
||||
@ -39,16 +40,20 @@ import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.rules.Timeout
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ImageActivityTest {
|
||||
|
||||
@get:Rule
|
||||
val activity: ActivityTestRule<ImageActivity> =
|
||||
ActivityTestRule(ImageActivity::class.java, true, false)
|
||||
|
||||
@get:Rule
|
||||
val rule: TestRule = RuleChain.outerRule(FrostTestRule()).around(activity)
|
||||
|
||||
@get:Rule
|
||||
val globalTimeout: Timeout = Timeout.seconds(15)
|
||||
|
||||
@ -124,7 +129,6 @@ class ImageActivityTest {
|
||||
fun invalidImageTest() {
|
||||
launchActivity(mockServer.url("text").toString())
|
||||
mockServer.takeRequest()
|
||||
activity.activity.isFinishing
|
||||
with(activity.activity) {
|
||||
assertEquals(1, mockServer.requestCount, "One http request expected")
|
||||
assertEquals(
|
||||
|
@ -19,11 +19,15 @@ package com.pitchedapps.frost
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
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
|
||||
import com.bugsnag.android.Configuration
|
||||
import com.pitchedapps.frost.db.FrostDatabase
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.services.scheduleNotificationsFromPrefs
|
||||
import com.pitchedapps.frost.services.setupNotificationChannels
|
||||
import com.pitchedapps.frost.utils.BuildUtils
|
||||
@ -34,18 +38,42 @@ 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
|
||||
|
||||
/**
|
||||
* 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(),
|
||||
FbCookie.module()
|
||||
)
|
||||
)
|
||||
}
|
||||
if (!buildIsLollipopAndUp) { // not supported
|
||||
super.onCreate()
|
||||
return
|
||||
}
|
||||
prefs = get()
|
||||
showcasePrefs = get()
|
||||
initPrefs()
|
||||
initBugsnag()
|
||||
|
||||
@ -54,9 +82,9 @@ class FrostApp : Application() {
|
||||
|
||||
super.onCreate()
|
||||
|
||||
setupNotificationChannels(applicationContext)
|
||||
setupNotificationChannels(this, prefs)
|
||||
|
||||
scheduleNotificationsFromPrefs()
|
||||
scheduleNotificationsFromPrefs(prefs)
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
||||
@ -77,27 +105,27 @@ 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()
|
||||
L.shouldLog = {
|
||||
when (it) {
|
||||
Log.VERBOSE -> BuildConfig.DEBUG
|
||||
Log.INFO, Log.ERROR -> true
|
||||
else -> BuildConfig.DEBUG || prefs.verboseLogging
|
||||
}
|
||||
}
|
||||
if (Prefs.identifier == -1) {
|
||||
Prefs.identifier = Random().nextInt(Int.MAX_VALUE)
|
||||
prefs.verboseLogging = false
|
||||
if (prefs.installDate == -1L) {
|
||||
prefs.installDate = System.currentTimeMillis()
|
||||
}
|
||||
Prefs.lastLaunch = System.currentTimeMillis()
|
||||
if (prefs.identifier == -1) {
|
||||
prefs.identifier = Random().nextInt(Int.MAX_VALUE)
|
||||
}
|
||||
prefs.lastLaunch = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
private fun initBugsnag() {
|
||||
@ -113,12 +141,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)
|
||||
L.hasAnalytics = { prefs.analytics }
|
||||
Bugsnag.setUserId(prefs.frostId)
|
||||
Bugsnag.addToTab("Build", "Application", BuildConfig.APPLICATION_ID)
|
||||
Bugsnag.addToTab("Build", "Version", BuildConfig.VERSION_NAME)
|
||||
|
||||
@ -129,4 +157,12 @@ class FrostApp : Application() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun prefFactoryModule(): Module = module {
|
||||
single<KPrefFactory> {
|
||||
KPrefFactoryAndroid(get())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ import org.koin.android.ext.android.inject
|
||||
*/
|
||||
class StartActivity : KauBaseActivity() {
|
||||
|
||||
private val fbCookie: FbCookie by inject()
|
||||
private val prefs: Prefs by inject()
|
||||
private val cookieDao: CookieDao by inject()
|
||||
private val genericDao: GenericDao by inject()
|
||||
|
||||
@ -67,13 +69,14 @@ class StartActivity : KauBaseActivity() {
|
||||
// TODO add better descriptions
|
||||
CookieManager.getInstance()
|
||||
} catch (e: Exception) {
|
||||
L.e(e) { "No cookiemanager instance" }
|
||||
showInvalidWebView()
|
||||
}
|
||||
|
||||
launch {
|
||||
try {
|
||||
val authDefer = BiometricUtils.authenticate(this@StartActivity)
|
||||
FbCookie.switchBackUser()
|
||||
val authDefer = BiometricUtils.authenticate(this@StartActivity, prefs)
|
||||
fbCookie.switchBackUser()
|
||||
val cookies = ArrayList(cookieDao.selectAll())
|
||||
L.i { "Cookies loaded at time ${System.currentTimeMillis()}" }
|
||||
L._d {
|
||||
@ -82,12 +85,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
|
||||
cutoutDrawableRes = R.drawable.frost_f_200
|
||||
faqPageTitleRes = R.string.faq_title
|
||||
faqXmlRes = R.xml.frost_faq
|
||||
faqParseNewLine = false
|
||||
}) {
|
||||
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,19 @@ 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.facebook.FbCookie
|
||||
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 fbCookie: FbCookie by inject()
|
||||
val prefs: Prefs by inject()
|
||||
|
||||
/**
|
||||
* Inherited consumer to customize back press
|
||||
*/
|
||||
|
@ -93,7 +93,6 @@ import com.pitchedapps.frost.db.GenericDao
|
||||
import com.pitchedapps.frost.db.currentCookie
|
||||
import com.pitchedapps.frost.db.getTabs
|
||||
import com.pitchedapps.frost.enums.MainActivityLayout
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.facebook.parsers.FrostSearch
|
||||
import com.pitchedapps.frost.facebook.parsers.SearchParser
|
||||
@ -108,7 +107,6 @@ import com.pitchedapps.frost.utils.BiometricUtils
|
||||
import com.pitchedapps.frost.utils.EXTRA_COOKIES
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.MAIN_TIMEOUT_DURATION
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.REQUEST_FAB
|
||||
import com.pitchedapps.frost.utils.REQUEST_NAV
|
||||
import com.pitchedapps.frost.utils.REQUEST_NOTIFICATION
|
||||
@ -177,7 +175,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 {
|
||||
@ -203,7 +201,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
}
|
||||
drawerWrapperBinding.mainContainer.addView(contentBinding.root)
|
||||
with(contentBinding) {
|
||||
setFrostColors {
|
||||
setFrostColors(prefs) {
|
||||
toolbar(toolbar)
|
||||
themeWindow = false
|
||||
header(appbar)
|
||||
@ -211,7 +209,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 +217,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 +287,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 {
|
||||
@ -315,12 +313,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
val item = FbItem.values[it.itemId]
|
||||
frostEvent("Drawer Tab", "name" to item.name)
|
||||
drawer.closeDrawer(navigation)
|
||||
launchWebOverlay(item.url)
|
||||
launchWebOverlay(item.url, fbCookie)
|
||||
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 +330,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 +350,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 +382,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 +447,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
animator.start()
|
||||
}
|
||||
|
||||
val textColor = Prefs.textColor
|
||||
val textColor = prefs.textColor
|
||||
|
||||
fun TextView.setOptionsIcon(iicon: IIcon) {
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
@ -459,7 +457,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
null
|
||||
)
|
||||
setTextColor(textColor)
|
||||
background = createNavDrawable(Prefs.accentColor, optionsBackground)
|
||||
background = createNavDrawable(prefs.accentColor, optionsBackground)
|
||||
}
|
||||
|
||||
with(optionsLogout) {
|
||||
@ -469,7 +467,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
val currentCookie = cookieDao.currentCookie()
|
||||
if (currentCookie == null) {
|
||||
toast(R.string.account_not_found)
|
||||
FbCookie.reset()
|
||||
fbCookie.reset()
|
||||
launchLogin(cookies(), true)
|
||||
} else {
|
||||
materialDialog {
|
||||
@ -478,12 +476,12 @@ 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) {
|
||||
this@BaseMainActivity.launch {
|
||||
FbCookie.logout(this@BaseMainActivity)
|
||||
fbCookie.logout(this@BaseMainActivity)
|
||||
}
|
||||
}
|
||||
negativeButton(R.string.kau_no)
|
||||
@ -507,7 +505,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 +530,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 +567,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)
|
||||
}
|
||||
@ -598,7 +596,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
.into(this)
|
||||
setOnClickListener {
|
||||
if (primary) {
|
||||
launchWebOverlay(FbItem.PROFILE.url)
|
||||
launchWebOverlay(FbItem.PROFILE.url, fbCookie)
|
||||
} else {
|
||||
switchAccount(cookie.id)
|
||||
}
|
||||
@ -608,12 +606,12 @@ 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()
|
||||
launch {
|
||||
FbCookie.switchUser(id)
|
||||
fbCookie.switchUser(id)
|
||||
tabsForEachView { _, view -> view.badgeText = null }
|
||||
refreshAll()
|
||||
}
|
||||
@ -627,9 +625,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,13 +637,13 @@ 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)
|
||||
searchView.results = results
|
||||
else {
|
||||
val data = SearchParser.query(FbCookie.webCookie, query)?.data?.results
|
||||
val data = SearchParser.query(fbCookie.webCookie, query)?.data?.results
|
||||
if (data != null) {
|
||||
val items = data.mapTo(mutableListOf(), FrostSearch::toSearchItem)
|
||||
if (items.isNotEmpty())
|
||||
@ -663,11 +661,11 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
}
|
||||
textDebounceInterval = 300
|
||||
searchCallback =
|
||||
{ query, _ -> launchWebOverlay("${FbItem._SEARCH.url}/?q=$query"); true }
|
||||
{ query, _ -> launchWebOverlay("${FbItem._SEARCH.url}/?q=$query", fbCookie); true }
|
||||
closeListener = { _ -> searchViewCache.clear() }
|
||||
foregroundColor = Prefs.textColor
|
||||
backgroundColor = Prefs.bgColor.withMinAlpha(200)
|
||||
onItemClick = { _, key, _, _ -> launchWebOverlay(key) }
|
||||
foregroundColor = prefs.textColor
|
||||
backgroundColor = prefs.bgColor.withMinAlpha(200)
|
||||
onItemClick = { _, key, _, _ -> launchWebOverlay(key, fbCookie) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -737,7 +735,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
fragmentChannel.offer(lastPosition)
|
||||
}
|
||||
if (hasRequest(REQUEST_NOTIFICATION)) {
|
||||
scheduleNotificationsFromPrefs()
|
||||
scheduleNotificationsFromPrefs(prefs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -758,10 +756,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
lastAccessTime = System.currentTimeMillis() // precaution to avoid loops
|
||||
controlWebview?.resumeTimers()
|
||||
launch {
|
||||
val authDefer = BiometricUtils.authenticate(this@BaseMainActivity)
|
||||
FbCookie.switchBackUser()
|
||||
val authDefer = BiometricUtils.authenticate(this@BaseMainActivity, prefs)
|
||||
fbCookie.switchBackUser()
|
||||
authDefer.await()
|
||||
if (shouldReload && Prefs.autoRefreshFeed) {
|
||||
if (shouldReload && prefs.autoRefreshFeed) {
|
||||
refreshAll()
|
||||
}
|
||||
}
|
||||
@ -794,14 +792,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 +877,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
|
||||
val item = pages[position]
|
||||
return BaseFragment(
|
||||
item.fragmentCreator,
|
||||
prefs,
|
||||
forcedFallbacks.contains(item.name),
|
||||
item,
|
||||
position
|
||||
@ -901,7 +900,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,6 +38,8 @@ import java.io.File
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 05/01/18.
|
||||
@ -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?) {
|
||||
@ -68,7 +72,7 @@ class DebugActivity : KauBaseActivity() {
|
||||
}
|
||||
setTitle(R.string.debug_frost)
|
||||
|
||||
setFrostColors {
|
||||
setFrostColors(prefs) {
|
||||
toolbar(toolbar)
|
||||
}
|
||||
debugWebview.loadUrl(FbItem.FEED.url)
|
||||
@ -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()
|
||||
|
||||
|
@ -81,12 +81,16 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-15.
|
||||
*/
|
||||
class ImageActivity : KauBaseActivity() {
|
||||
|
||||
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() {
|
||||
@ -225,7 +229,7 @@ class ImageActivity : KauBaseActivity() {
|
||||
loadError(e)
|
||||
}
|
||||
})
|
||||
setFrostColors {
|
||||
setFrostColors(prefs) {
|
||||
themeWindow = false
|
||||
}
|
||||
dragHelper = ViewDragHelper.create(imageDrag, ViewDragCallback()).apply {
|
||||
@ -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,7 @@ import com.pitchedapps.frost.utils.setFrostTheme
|
||||
import com.pitchedapps.frost.widgets.NotificationWidget
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-25.
|
||||
@ -62,8 +63,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(), ViewPager.PageTransformer,
|
||||
ViewPager.OnPageChangeListener {
|
||||
|
||||
private val prefs: Prefs by inject()
|
||||
lateinit var binding: ActivityIntroBinding
|
||||
private var barHasNext = true
|
||||
|
||||
@ -97,17 +100,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 +152,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 +178,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 +209,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)
|
||||
|
@ -36,7 +36,6 @@ import com.pitchedapps.frost.db.CookieDao
|
||||
import com.pitchedapps.frost.db.CookieEntity
|
||||
import com.pitchedapps.frost.db.save
|
||||
import com.pitchedapps.frost.db.selectAll
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.facebook.profilePictureUrl
|
||||
import com.pitchedapps.frost.glide.FrostGlide
|
||||
@ -73,6 +72,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)
|
||||
@ -82,7 +82,7 @@ class LoginActivity : BaseActivity() {
|
||||
setContentView(R.layout.activity_login)
|
||||
setSupportActionBar(toolbar)
|
||||
setTitle(R.string.kau_login)
|
||||
setFrostColors {
|
||||
setFrostColors(prefs) {
|
||||
toolbar(toolbar)
|
||||
}
|
||||
profileLoader = GlideApp.with(profile)
|
||||
@ -96,7 +96,7 @@ class LoginActivity : BaseActivity() {
|
||||
launch {
|
||||
val cookie = web.loadLogin { refresh(it != 100) }.await()
|
||||
L.d { "Login found" }
|
||||
FbCookie.save(cookie.id)
|
||||
fbCookie.save(cookie.id)
|
||||
webFadeOut()
|
||||
profile.fadeIn()
|
||||
loadInfo(cookie)
|
||||
@ -138,7 +138,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)
|
||||
|
@ -27,7 +27,6 @@ import com.mikepenz.fastadapter.FastAdapter
|
||||
import com.mikepenz.fastadapter.adapters.FastItemAdapter
|
||||
import com.mikepenz.fastadapter.listeners.ClickEventHook
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.utils.cookies
|
||||
import com.pitchedapps.frost.utils.launchNewTask
|
||||
import com.pitchedapps.frost.utils.setFrostColors
|
||||
@ -63,12 +62,12 @@ class SelectorActivity : BaseActivity() {
|
||||
) {
|
||||
if (item.cookie == null) this@SelectorActivity.launchNewTask<LoginActivity>()
|
||||
else launch {
|
||||
FbCookie.switchUser(item.cookie)
|
||||
fbCookie.switchUser(item.cookie)
|
||||
launchNewTask<MainActivity>(cookies())
|
||||
}
|
||||
}
|
||||
})
|
||||
setFrostColors {
|
||||
setFrostColors(prefs) {
|
||||
text(text)
|
||||
background(container)
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.enums.Support
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.settings.getAppearancePrefs
|
||||
import com.pitchedapps.frost.settings.getBehaviourPrefs
|
||||
import com.pitchedapps.frost.settings.getDebugPrefs
|
||||
@ -61,12 +62,16 @@ 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 fbCookie: FbCookie by inject()
|
||||
val prefs: Prefs by inject()
|
||||
|
||||
private var resultFlag = Activity.RESULT_CANCELED
|
||||
|
||||
companion object {
|
||||
@ -117,11 +122,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 +134,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 +200,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 +220,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 +236,7 @@ class SettingsActivity : KPrefActivity() {
|
||||
if (!super.backPress()) {
|
||||
setResult(resultFlag)
|
||||
launch(NonCancellable) {
|
||||
loadAssets()
|
||||
loadAssets(prefs)
|
||||
finishSlideOut()
|
||||
}
|
||||
}
|
||||
@ -239,9 +244,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,7 +42,6 @@ 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
|
||||
@ -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,10 +104,10 @@ 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 {
|
||||
setFrostColors(prefs) {
|
||||
themeWindow = true
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,6 @@ import com.pitchedapps.frost.contracts.FrostContentContainer
|
||||
import com.pitchedapps.frost.contracts.VideoViewHolder
|
||||
import com.pitchedapps.frost.enums.OverlayContext
|
||||
import com.pitchedapps.frost.facebook.FB_URL_BASE
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.facebook.USER_AGENT
|
||||
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP_CONST
|
||||
@ -67,7 +66,6 @@ import com.pitchedapps.frost.utils.ARG_URL
|
||||
import com.pitchedapps.frost.utils.ARG_USER_ID
|
||||
import com.pitchedapps.frost.utils.BiometricUtils
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.Showcase
|
||||
import com.pitchedapps.frost.utils.frostSnackbar
|
||||
import com.pitchedapps.frost.utils.setFrostColors
|
||||
@ -78,6 +76,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 +169,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 +185,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 +206,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 {
|
||||
setFrostColors(prefs) {
|
||||
toolbar(toolbar)
|
||||
themeWindow = false
|
||||
}
|
||||
coordinator.setBackgroundColor(Prefs.bgColor.withAlpha(255))
|
||||
coordinator.setBackgroundColor(prefs.bgColor.withAlpha(255))
|
||||
|
||||
content.bind(this)
|
||||
|
||||
@ -222,15 +223,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) {
|
||||
FbCookie.switchUser(userId)
|
||||
val authDefer = BiometricUtils.authenticate(this@WebOverlayActivityBase, prefs)
|
||||
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 +241,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 +272,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 +313,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
|
||||
|
@ -33,11 +33,11 @@ const val BLUE_LIGHT = 0xff5d86dd.toInt()
|
||||
enum class Theme(
|
||||
@StringRes val textRes: Int,
|
||||
val injector: InjectorContract,
|
||||
private val textColorGetter: () -> Int,
|
||||
private val accentColorGetter: () -> Int,
|
||||
private val backgroundColorGetter: () -> Int,
|
||||
private val headerColorGetter: () -> Int,
|
||||
private val iconColorGetter: () -> Int
|
||||
val textColorGetter: (Prefs) -> Int,
|
||||
val accentColorGetter: (Prefs) -> Int,
|
||||
val backgroundColorGetter: (Prefs) -> Int,
|
||||
val headerColorGetter: (Prefs) -> Int,
|
||||
val iconColorGetter: (Prefs) -> Int
|
||||
) {
|
||||
|
||||
DEFAULT(R.string.kau_default,
|
||||
@ -82,26 +82,11 @@ enum class Theme(
|
||||
|
||||
CUSTOM(R.string.kau_custom,
|
||||
CssAssets.CUSTOM,
|
||||
{ Prefs.customTextColor },
|
||||
{ Prefs.customAccentColor },
|
||||
{ Prefs.customBackgroundColor },
|
||||
{ Prefs.customHeaderColor },
|
||||
{ Prefs.customIconColor });
|
||||
|
||||
val textColor: Int
|
||||
get() = textColorGetter()
|
||||
|
||||
val accentColor: Int
|
||||
get() = accentColorGetter()
|
||||
|
||||
val bgColor: Int
|
||||
get() = backgroundColorGetter()
|
||||
|
||||
val headerColor: Int
|
||||
get() = headerColorGetter()
|
||||
|
||||
val iconColor: Int
|
||||
get() = iconColorGetter()
|
||||
{ it.customTextColor },
|
||||
{ it.customAccentColor },
|
||||
{ it.customBackgroundColor },
|
||||
{ it.customHeaderColor },
|
||||
{ it.customIconColor });
|
||||
|
||||
companion object {
|
||||
val values = values() // save one instance
|
||||
|
@ -21,7 +21,6 @@ import android.content.Context
|
||||
import android.webkit.CookieManager
|
||||
import com.pitchedapps.frost.db.CookieDao
|
||||
import com.pitchedapps.frost.db.CookieEntity
|
||||
import com.pitchedapps.frost.db.FrostDatabase
|
||||
import com.pitchedapps.frost.db.deleteById
|
||||
import com.pitchedapps.frost.db.save
|
||||
import com.pitchedapps.frost.db.selectById
|
||||
@ -35,27 +34,30 @@ import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.dsl.module
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-30.
|
||||
*
|
||||
* The following component manages all cookie transfers.
|
||||
*/
|
||||
object FbCookie {
|
||||
class FbCookie(private val prefs: Prefs, private val cookieDao: CookieDao) {
|
||||
|
||||
const val COOKIE_DOMAIN = FB_URL_BASE
|
||||
companion object {
|
||||
private const val COOKIE_DOMAIN = FB_URL_BASE
|
||||
|
||||
fun module() = module {
|
||||
single { FbCookie(get(), get()) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the facebook cookie if it exists
|
||||
* Note that this is a synchronized call
|
||||
*/
|
||||
inline val webCookie: String?
|
||||
val webCookie: String?
|
||||
get() = CookieManager.getInstance().getCookie(COOKIE_DOMAIN)
|
||||
|
||||
private val cookieDao: CookieDao by lazy {
|
||||
FrostDatabase.get().cookieDao()
|
||||
}
|
||||
|
||||
private suspend fun CookieManager.suspendSetWebCookie(cookie: String?): Boolean {
|
||||
cookie ?: return true
|
||||
return withContext(NonCancellable) {
|
||||
@ -86,14 +88,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 +114,7 @@ object FbCookie {
|
||||
}
|
||||
withContext(NonCancellable) {
|
||||
L.d { "Switching User" }
|
||||
Prefs.userId = cookie.id
|
||||
prefs.userId = cookie.id
|
||||
CookieManager.getInstance().suspendSetWebCookie(cookie.cookie)
|
||||
}
|
||||
}
|
||||
@ -124,8 +126,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 +147,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" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import com.pitchedapps.frost.contracts.FrostContentParent
|
||||
import com.pitchedapps.frost.contracts.MainActivityContract
|
||||
import com.pitchedapps.frost.contracts.MainFabContract
|
||||
import com.pitchedapps.frost.enums.FeedSort
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.utils.ARG_URL
|
||||
import com.pitchedapps.frost.utils.L
|
||||
@ -47,6 +48,7 @@ import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
/**
|
||||
* 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, 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,8 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
|
||||
}
|
||||
}
|
||||
|
||||
protected val fbCookie: FbCookie by inject()
|
||||
protected val prefs: Prefs by inject()
|
||||
open lateinit var job: Job
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = ContextHelper.dispatcher + job
|
||||
@ -195,10 +201,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() }
|
||||
|
@ -23,7 +23,6 @@ import com.mikepenz.fastadapter.GenericItem
|
||||
import com.mikepenz.fastadapter.adapters.ItemAdapter
|
||||
import com.mikepenz.fastadapter.adapters.ModelAdapter
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.parsers.FrostParser
|
||||
import com.pitchedapps.frost.facebook.parsers.ParseData
|
||||
import com.pitchedapps.frost.facebook.parsers.ParseResponse
|
||||
@ -130,7 +129,7 @@ abstract class FrostParserFragment<T : ParseData, Item : GenericItem> :
|
||||
override suspend fun reloadImpl(progress: (Int) -> Unit): List<Item>? =
|
||||
withContext(Dispatchers.IO) {
|
||||
progress(10)
|
||||
val cookie = FbCookie.webCookie
|
||||
val cookie = fbCookie.webCookie
|
||||
val doc = getDoc(cookie)
|
||||
progress(60)
|
||||
val response = try {
|
||||
|
@ -40,6 +40,6 @@ class NotificationFragment : FrostParserFragment<FrostNotifs, NotificationIItem>
|
||||
response.data.notifs.map { NotificationIItem(it, response.cookie) }
|
||||
|
||||
override fun bindImpl(recyclerView: FrostRecyclerView) {
|
||||
NotificationIItem.bindEvents(adapter)
|
||||
NotificationIItem.bindEvents(adapter, fbCookie)
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import com.pitchedapps.frost.contracts.MainFabContract
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.injectors.JsActions
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.views.FrostWebView
|
||||
import com.pitchedapps.frost.web.FrostWebViewClient
|
||||
import com.pitchedapps.frost.web.FrostWebViewClientMenu
|
||||
@ -52,9 +51,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
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ import com.pitchedapps.frost.facebook.FbCookie
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 28/12/17.
|
||||
@ -63,10 +65,13 @@ class FrostGlideModule : AppGlideModule() {
|
||||
private fun getFrostHttpClient(): OkHttpClient =
|
||||
OkHttpClient.Builder().addInterceptor(FrostCookieInterceptor()).build()
|
||||
|
||||
class FrostCookieInterceptor : Interceptor {
|
||||
class FrostCookieInterceptor : Interceptor, KoinComponent {
|
||||
|
||||
private val fbCookie: FbCookie by inject()
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val origRequest = chain.request()
|
||||
val cookie = FbCookie.webCookie ?: return chain.proceed(origRequest)
|
||||
val cookie = fbCookie.webCookie ?: return chain.proceed(origRequest)
|
||||
val request = origRequest.newBuilder().addHeader("Cookie", cookie).build()
|
||||
return chain.proceed(request)
|
||||
}
|
||||
|
@ -27,8 +27,11 @@ import com.mikepenz.fastadapter.GenericItem
|
||||
import com.mikepenz.fastadapter.IAdapter
|
||||
import com.mikepenz.fastadapter.select.selectExtension
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
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.
|
||||
@ -41,20 +44,20 @@ interface ClickableIItemContract {
|
||||
|
||||
val url: String?
|
||||
|
||||
fun click(context: Context) {
|
||||
fun click(context: Context, fbCookie: FbCookie) {
|
||||
val url = url ?: return
|
||||
context.launchWebOverlay(url)
|
||||
context.launchWebOverlay(url, fbCookie)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun bindEvents(adapter: IAdapter<GenericItem>) {
|
||||
fun bindEvents(adapter: IAdapter<GenericItem>, fbCookie: FbCookie) {
|
||||
adapter.fastAdapter?.apply {
|
||||
selectExtension {
|
||||
isSelectable = false
|
||||
}
|
||||
onClickListener = { v, _, item, _ ->
|
||||
if (item is ClickableIItemContract) {
|
||||
item.click(v!!.context)
|
||||
item.click(v!!.context, fbCookie)
|
||||
true
|
||||
} else
|
||||
false
|
||||
@ -73,14 +76,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 +105,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) {
|
||||
|
@ -31,6 +31,7 @@ import com.mikepenz.fastadapter.adapters.ItemAdapter
|
||||
import com.mikepenz.fastadapter.diff.DiffCallback
|
||||
import com.mikepenz.fastadapter.select.selectExtension
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.facebook.parsers.FrostNotif
|
||||
import com.pitchedapps.frost.glide.FrostGlide
|
||||
@ -38,6 +39,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.
|
||||
@ -48,7 +51,7 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) :
|
||||
) {
|
||||
|
||||
companion object {
|
||||
fun bindEvents(adapter: ItemAdapter<NotificationIItem>) {
|
||||
fun bindEvents(adapter: ItemAdapter<NotificationIItem>, fbCookie: FbCookie) {
|
||||
adapter.fastAdapter?.apply {
|
||||
selectExtension {
|
||||
isSelectable = false
|
||||
@ -62,7 +65,7 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) :
|
||||
)
|
||||
}
|
||||
// TODO temp fix. If url is dependent, we cannot load it directly
|
||||
v!!.context.launchWebOverlay(if (notif.url.isIndependent) notif.url else FbItem.NOTIFICATIONS.url)
|
||||
v!!.context.launchWebOverlay(if (notif.url.isIndependent) notif.url else FbItem.NOTIFICATIONS.url, fbCookie)
|
||||
true
|
||||
}
|
||||
}
|
||||
@ -93,7 +96,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 +112,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
|
||||
@ -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)
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.IntroActivity
|
||||
import com.pitchedapps.frost.databinding.IntroThemeBinding
|
||||
import com.pitchedapps.frost.enums.Theme
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-28.
|
||||
@ -56,7 +55,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 +64,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() }
|
||||
|
@ -29,7 +29,6 @@ import ca.allanwang.kau.utils.visible
|
||||
import ca.allanwang.kau.utils.withAlpha
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.launchTabCustomizerActivity
|
||||
import kotlin.math.abs
|
||||
|
||||
@ -58,10 +57,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 +96,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 +122,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 +141,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
|
||||
|
@ -38,6 +38,7 @@ import com.pitchedapps.frost.activities.IntroActivity
|
||||
import com.pitchedapps.frost.databinding.IntroAnalyticsBinding
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import kotlin.math.abs
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-28.
|
||||
@ -50,6 +51,8 @@ import kotlin.math.abs
|
||||
*/
|
||||
abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
|
||||
|
||||
protected val prefs: Prefs by inject()
|
||||
|
||||
val screenWidth
|
||||
get() = resources.displayMetrics.widthPixels
|
||||
|
||||
@ -105,7 +108,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 +137,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 +156,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 +168,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 +183,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")
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ import com.pitchedapps.frost.activities.SettingsActivity
|
||||
import com.pitchedapps.frost.enums.MainActivityLayout
|
||||
import com.pitchedapps.frost.enums.Theme
|
||||
import com.pitchedapps.frost.injectors.CssAssets
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.REQUEST_NAV
|
||||
import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
|
||||
import com.pitchedapps.frost.utils.frostEvent
|
||||
@ -45,7 +44,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 +70,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 +79,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 +89,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 +99,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 +110,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 +121,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 +134,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 +159,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 +171,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
|
||||
}
|
||||
|
@ -19,54 +19,53 @@ 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-06-30.
|
||||
*/
|
||||
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 +77,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
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ import com.pitchedapps.frost.activities.SettingsActivity
|
||||
import com.pitchedapps.frost.activities.SettingsActivity.Companion.ACTIVITY_REQUEST_DEBUG
|
||||
import com.pitchedapps.frost.debugger.OfflineWebsite
|
||||
import com.pitchedapps.frost.facebook.FB_URL_BASE
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.parsers.FrostParser
|
||||
import com.pitchedapps.frost.facebook.parsers.MessageParser
|
||||
import com.pitchedapps.frost.facebook.parsers.NotifParser
|
||||
@ -87,7 +86,7 @@ fun SettingsActivity.getDebugPrefs(): KPrefAdapterBuilder.() -> Unit = {
|
||||
|
||||
attempt = launch(Dispatchers.IO) {
|
||||
try {
|
||||
val data = parser.parse(FbCookie.webCookie)
|
||||
val data = parser.parse(fbCookie.webCookie)
|
||||
withMainContext {
|
||||
loading.dismiss()
|
||||
createEmail(parser, data?.data)
|
||||
@ -113,7 +112,8 @@ private const val ZIP_NAME = "debug"
|
||||
fun SettingsActivity.sendDebug(url: String, html: String?) {
|
||||
|
||||
val downloader = OfflineWebsite(
|
||||
url, FbCookie.webCookie ?: "",
|
||||
url,
|
||||
cookie = fbCookie.webCookie ?: "",
|
||||
baseUrl = FB_URL_BASE,
|
||||
html = html,
|
||||
baseDir = DebugActivity.baseDir(this)
|
||||
|
@ -21,7 +21,6 @@ import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
|
||||
import ca.allanwang.kau.logging.KL
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.SettingsActivity
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.REQUEST_RESTART_APPLICATION
|
||||
|
||||
/**
|
||||
@ -37,8 +36,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
|
||||
|
@ -23,7 +23,6 @@ import com.afollestad.materialdialogs.list.listItemsSingleChoice
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.SettingsActivity
|
||||
import com.pitchedapps.frost.enums.FeedSort
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.REQUEST_FAB
|
||||
|
||||
/**
|
||||
@ -31,7 +30,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 +49,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) {
|
||||
|
@ -20,7 +20,6 @@ import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.SettingsActivity
|
||||
import com.pitchedapps.frost.utils.BiometricUtils
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
@ -32,15 +31,15 @@ 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:
|
||||
* - enabling to ensure that it is supported
|
||||
* - disabling to ensure that it is permitted
|
||||
*/
|
||||
BiometricUtils.authenticate(this@getSecurityPrefs, force = true).await()
|
||||
Prefs.biometricsEnabled = it
|
||||
BiometricUtils.authenticate(this@getSecurityPrefs, prefs, force = true).await()
|
||||
prefs.biometricsEnabled = it
|
||||
reloadByTitle(R.string.enable_biometrics)
|
||||
}
|
||||
}) {
|
||||
|
@ -64,8 +64,8 @@ object BiometricUtils {
|
||||
private fun getOrCreatePoolSync(): Executor =
|
||||
pool ?: Executors.newSingleThreadExecutor().also { pool = it }
|
||||
|
||||
private fun shouldPrompt(context: Context): Boolean {
|
||||
return Prefs.biometricsEnabled && System.currentTimeMillis() - lastUnlockTime > UNLOCK_TIME_INTERVAL
|
||||
private fun shouldPrompt(context: Context, prefs: Prefs): Boolean {
|
||||
return prefs.biometricsEnabled && System.currentTimeMillis() - lastUnlockTime > UNLOCK_TIME_INTERVAL
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,9 +73,9 @@ object BiometricUtils {
|
||||
* Note that the underlying request will call [androidx.fragment.app.FragmentTransaction.commit],
|
||||
* so this cannot happen after onSaveInstanceState.
|
||||
*/
|
||||
fun authenticate(activity: FragmentActivity, force: Boolean = false): BiometricDeferred {
|
||||
fun authenticate(activity: FragmentActivity, prefs: Prefs, force: Boolean = false): BiometricDeferred {
|
||||
val deferred: BiometricDeferred = CompletableDeferred()
|
||||
if (!force && !shouldPrompt(activity)) {
|
||||
if (!force && !shouldPrompt(activity, prefs)) {
|
||||
deferred.complete(null)
|
||||
return deferred
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.utils
|
||||
|
||||
import android.util.Log
|
||||
import ca.allanwang.kau.logging.KauLogger
|
||||
import ca.allanwang.kau.logging.KauLoggerExtension
|
||||
import com.bugsnag.android.Bugsnag
|
||||
@ -27,13 +26,7 @@ import com.pitchedapps.frost.BuildConfig
|
||||
*
|
||||
* Logging for frost
|
||||
*/
|
||||
object L : KauLogger("Frost", {
|
||||
when (it) {
|
||||
Log.VERBOSE -> BuildConfig.DEBUG
|
||||
Log.INFO, Log.ERROR -> true
|
||||
else -> BuildConfig.DEBUG || Prefs.verboseLogging
|
||||
}
|
||||
}) {
|
||||
object L : KauLogger("Frost") {
|
||||
|
||||
inline fun test(message: () -> Any?) {
|
||||
_d {
|
||||
@ -59,7 +52,7 @@ object L : KauLogger("Frost", {
|
||||
}
|
||||
}
|
||||
|
||||
var bugsnagInit = false
|
||||
var hasAnalytics: () -> Boolean = { false }
|
||||
|
||||
override fun logImpl(priority: Int, message: String?, t: Throwable?) {
|
||||
/*
|
||||
@ -67,7 +60,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 || !hasAnalytics()) {
|
||||
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,15 +72,15 @@ 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
|
||||
|
||||
val textColor: Int
|
||||
get() = t.textColor
|
||||
get() = t.textColorGetter(this)
|
||||
|
||||
val accentColor: Int
|
||||
get() = t.accentColor
|
||||
get() = t.accentColorGetter(this)
|
||||
|
||||
inline val accentColorForWhite: Int
|
||||
get() = when {
|
||||
@ -87,20 +90,20 @@ 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)
|
||||
|
||||
val bgColor: Int
|
||||
get() = t.bgColor
|
||||
get() = t.backgroundColorGetter(this)
|
||||
|
||||
val headerColor: Int
|
||||
get() = t.headerColor
|
||||
get() = t.headerColorGetter(this)
|
||||
|
||||
val iconColor: Int
|
||||
get() = t.iconColor
|
||||
get() = t.iconColorGetter(this)
|
||||
|
||||
val themeInjector: InjectorContract
|
||||
get() = t.injector
|
||||
@ -155,6 +158,10 @@ object Prefs : KPref() {
|
||||
|
||||
var enablePip: Boolean by kpref("enable_pip", true)
|
||||
|
||||
/**
|
||||
* Despite the naming, this toggle currently only enables debug logging.
|
||||
* Verbose is never logged in release builds.
|
||||
*/
|
||||
var verboseLogging: Boolean by kpref("verbose_logging", false)
|
||||
|
||||
var analytics: Boolean by kpref("analytics", false) {
|
||||
@ -194,5 +201,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()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,27 +123,34 @@ fun Activity.cookies(): ArrayList<CookieEntity> {
|
||||
* Note that most requests may need to first check if the url can be launched as an overlay
|
||||
* See [requestWebOverlay] to verify the launch
|
||||
*/
|
||||
private inline fun <reified T : WebOverlayActivityBase> Context.launchWebOverlayImpl(url: String) {
|
||||
private inline fun <reified T : WebOverlayActivityBase> Context.launchWebOverlayImpl(
|
||||
url: String,
|
||||
fbCookie: FbCookie
|
||||
) {
|
||||
val prefs = Prefs.get()
|
||||
val argUrl = url.formattedFbUrl
|
||||
L.v { "Launch received: $url\nLaunch web overlay: $argUrl" }
|
||||
if (argUrl.isFacebookUrl && argUrl.contains("/logout.php")) {
|
||||
L.d { "Logout php found" }
|
||||
ctxCoroutine.launch {
|
||||
FbCookie.logout(this@launchWebOverlayImpl)
|
||||
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)
|
||||
fun Context.launchWebOverlay(url: String, fbCookie: FbCookie) =
|
||||
launchWebOverlayImpl<WebOverlayActivity>(url, fbCookie)
|
||||
|
||||
// TODO Currently, default is overlay. Switch this if default changes
|
||||
fun Context.launchWebOverlayDesktop(url: String) = launchWebOverlay(url)
|
||||
fun Context.launchWebOverlayDesktop(url: String, fbCookie: FbCookie) =
|
||||
launchWebOverlay(url, fbCookie)
|
||||
|
||||
fun Context.launchWebOverlayMobile(url: String) =
|
||||
launchWebOverlayImpl<WebOverlayMobileActivity>(url)
|
||||
fun Context.launchWebOverlayMobile(url: String, fbCookie: FbCookie) =
|
||||
launchWebOverlayImpl<WebOverlayMobileActivity>(url, fbCookie)
|
||||
|
||||
private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation(
|
||||
this,
|
||||
@ -172,16 +179,17 @@ 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(val prefs: Prefs) {
|
||||
|
||||
private var toolbar: Toolbar? = null
|
||||
var themeWindow = true
|
||||
@ -207,21 +215,21 @@ 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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun Activity.setFrostColors(builder: ActivityThemeUtils.() -> Unit) {
|
||||
val themer = ActivityThemeUtils()
|
||||
inline fun Activity.setFrostColors(prefs: Prefs, builder: ActivityThemeUtils.() -> Unit) {
|
||||
val themer = ActivityThemeUtils(prefs)
|
||||
themer.builder()
|
||||
themer.theme(this)
|
||||
}
|
||||
@ -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,15 +403,14 @@ 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)
|
||||
}
|
||||
|
||||
fun frostJsoup(url: String): Document = frostJsoup(FbCookie.webCookie, url)
|
||||
|
||||
fun frostJsoup(cookie: String?, url: String): Document =
|
||||
Jsoup.connect(url).run {
|
||||
if (cookie.isNullOrBlank()) this
|
||||
@ -438,7 +447,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)
|
||||
}
|
||||
|
@ -25,12 +25,13 @@ import com.afollestad.materialdialogs.callbacks.onDismiss
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.MainActivity
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.formattedFbUrl
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-07-07.
|
||||
*/
|
||||
fun Context.showWebContextMenu(wc: WebContext) {
|
||||
fun Context.showWebContextMenu(wc: WebContext, fbCookie: FbCookie) {
|
||||
if (wc.isEmpty) return
|
||||
var title = wc.url ?: string(R.string.menu)
|
||||
title =
|
||||
@ -43,7 +44,7 @@ fun Context.showWebContextMenu(wc: WebContext) {
|
||||
materialDialog {
|
||||
title(text = title)
|
||||
listItems(items = menuItems.map { string(it.textId) }) { _, position, _ ->
|
||||
menuItems[position].onClick(this@showWebContextMenu, wc)
|
||||
menuItems[position].onClick(this@showWebContextMenu, wc, fbCookie)
|
||||
}
|
||||
onDismiss {
|
||||
// showing the dialog interrupts the touch down event, so we must ensure that the viewpager's swipe is enabled
|
||||
@ -65,16 +66,16 @@ class WebContext(val unformattedUrl: String?, val text: String?) {
|
||||
enum class WebContextType(
|
||||
val textId: Int,
|
||||
val constraint: (wc: WebContext) -> Boolean,
|
||||
val onClick: (c: Context, wc: WebContext) -> Unit
|
||||
val onClick: (c: Context, wc: WebContext, fc: FbCookie) -> Unit
|
||||
) {
|
||||
OPEN_LINK(
|
||||
R.string.open_link,
|
||||
{ it.hasUrl },
|
||||
{ c, wc -> c.launchWebOverlay(wc.url!!) }),
|
||||
COPY_LINK(R.string.copy_link, { it.hasUrl }, { c, wc -> c.copyToClipboard(wc.url) }),
|
||||
COPY_TEXT(R.string.copy_text, { it.hasText }, { c, wc -> c.copyToClipboard(wc.text) }),
|
||||
SHARE_LINK(R.string.share_link, { it.hasUrl }, { c, wc -> c.shareText(wc.url) }),
|
||||
DEBUG_LINK(R.string.debug_link, { it.hasUrl }, { c, wc ->
|
||||
{ c, wc, fc -> c.launchWebOverlay(wc.url!!, fc) }),
|
||||
COPY_LINK(R.string.copy_link, { it.hasUrl }, { c, wc, _ -> c.copyToClipboard(wc.url) }),
|
||||
COPY_TEXT(R.string.copy_text, { it.hasText }, { c, wc, _ -> c.copyToClipboard(wc.text) }),
|
||||
SHARE_LINK(R.string.share_link, { it.hasUrl }, { c, wc, _ -> c.shareText(wc.url) }),
|
||||
DEBUG_LINK(R.string.debug_link, { it.hasUrl }, { c, wc, _ ->
|
||||
c.materialDialog {
|
||||
title(R.string.debug_link)
|
||||
message(R.string.debug_link_desc)
|
||||
|
@ -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,9 @@ 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 +52,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 +60,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 +70,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
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import com.pitchedapps.frost.contracts.FrostContentParent
|
||||
import com.pitchedapps.frost.db.FrostDatabase
|
||||
import com.pitchedapps.frost.db.currentCookie
|
||||
import com.pitchedapps.frost.facebook.FB_HOME_URL
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.USER_AGENT
|
||||
import com.pitchedapps.frost.fragments.WebFragment
|
||||
import com.pitchedapps.frost.utils.L
|
||||
@ -44,6 +45,8 @@ import com.pitchedapps.frost.web.NestedWebView
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
|
||||
/**
|
||||
* Created by Allan Wang on 2017-05-29.
|
||||
@ -54,7 +57,11 @@ class FrostWebView @JvmOverloads constructor(
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : NestedWebView(context, attrs, defStyleAttr),
|
||||
FrostContentCore {
|
||||
FrostContentCore,
|
||||
KoinComponent {
|
||||
|
||||
val fbCookie: FbCookie by inject()
|
||||
val prefs: Prefs by inject()
|
||||
|
||||
override fun reload(animate: Boolean) {
|
||||
if (parent.registerTransition(false, animate))
|
||||
@ -75,7 +82,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 +215,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,8 @@ import kotlinx.coroutines.launch
|
||||
*/
|
||||
class FrostJSI(val web: FrostWebView) {
|
||||
|
||||
private val fbCookie: FbCookie get() = web.fbCookie
|
||||
private val prefs: Prefs get() = web.prefs
|
||||
private val context: Context = web.context
|
||||
private val activity: MainActivity? = context as? MainActivity
|
||||
private val header: SendChannel<String>? = activity?.headerBadgeChannel
|
||||
@ -57,7 +59,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" }
|
||||
@ -79,7 +81,7 @@ class FrostJSI(val web: FrostWebView) {
|
||||
@JavascriptInterface
|
||||
fun contextMenu(url: String?, text: String?) {
|
||||
// url will be formatted through webcontext
|
||||
web.post { context.showWebContextMenu(WebContext(url.takeIf { it.isIndependent }, text)) }
|
||||
web.post { context.showWebContextMenu(WebContext(url.takeIf { it.isIndependent }, text), fbCookie) }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,7 +115,7 @@ class FrostJSI(val web: FrostWebView) {
|
||||
fun loadLogin() {
|
||||
L.d { "Sign up button found; load login" }
|
||||
context.ctxCoroutine.launch {
|
||||
FbCookie.logout(context)
|
||||
fbCookie.logout(context)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,10 @@ import ca.allanwang.kau.utils.runOnUiThread
|
||||
import com.pitchedapps.frost.activities.WebOverlayActivity
|
||||
import com.pitchedapps.frost.activities.WebOverlayActivityBase
|
||||
import com.pitchedapps.frost.contracts.VideoViewHolder
|
||||
import com.pitchedapps.frost.facebook.FbCookie
|
||||
import com.pitchedapps.frost.facebook.FbItem
|
||||
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP_CONST
|
||||
import com.pitchedapps.frost.facebook.formattedFbUrl
|
||||
import com.pitchedapps.frost.utils.L
|
||||
import com.pitchedapps.frost.utils.Prefs
|
||||
import com.pitchedapps.frost.utils.isFacebookUrl
|
||||
import com.pitchedapps.frost.utils.isImageUrl
|
||||
import com.pitchedapps.frost.utils.isIndependent
|
||||
@ -69,32 +67,32 @@ fun FrostWebView.requestWebOverlay(url: String): Boolean {
|
||||
}
|
||||
if (url.isIndirectImageUrl) {
|
||||
L.d { "Found indirect fb image" }
|
||||
context.launchImageActivity(url, cookie = FbCookie.webCookie)
|
||||
context.launchImageActivity(url, cookie = fbCookie.webCookie)
|
||||
return true
|
||||
}
|
||||
if (!url.isIndependent) {
|
||||
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
|
||||
if (userAgentString != USER_AGENT_DESKTOP_CONST && shouldUseDesktop) {
|
||||
L._i { "Switch to desktop agent overlay" }
|
||||
context.launchWebOverlayDesktop(url)
|
||||
context.launchWebOverlayDesktop(url, fbCookie)
|
||||
return true
|
||||
}
|
||||
if (userAgentString == USER_AGENT_DESKTOP_CONST && !shouldUseDesktop) {
|
||||
L._i { "Switch from desktop agent" }
|
||||
context.launchWebOverlayMobile(url)
|
||||
context.launchWebOverlayMobile(url, fbCookie)
|
||||
return true
|
||||
}
|
||||
L._i { "return false switch" }
|
||||
return false
|
||||
}
|
||||
L.v { "Request web overlay passed" }
|
||||
context.launchWebOverlay(url)
|
||||
context.launchWebOverlay(url, fbCookie)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,8 @@ open class BaseWebViewClient : WebViewClient() {
|
||||
*/
|
||||
open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
|
||||
private val fbCookie: FbCookie get() = web.fbCookie
|
||||
private val prefs: Prefs get() = web.prefs
|
||||
private val refresh: SendChannel<Boolean> = web.parent.refreshChannel
|
||||
private val isMain = web.parent.baseEnum != null
|
||||
/**
|
||||
@ -102,7 +104,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 +117,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 +150,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 +163,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
|
||||
)
|
||||
}
|
||||
|
||||
@ -202,12 +206,12 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
|
||||
return launchRequest(request)
|
||||
}
|
||||
if (url.isIndirectImageUrl) {
|
||||
return launchImage(url.formattedFbUrl, cookie = FbCookie.webCookie)
|
||||
return launchImage(url.formattedFbUrl, cookie = fbCookie.webCookie)
|
||||
}
|
||||
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 +233,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,10 @@ class LoginWebView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : WebView(context, attrs, defStyleAttr) {
|
||||
) : WebView(context, attrs, defStyleAttr), KoinComponent {
|
||||
|
||||
private val fbCookie: FbCookie by inject()
|
||||
private val prefs: Prefs by inject()
|
||||
private val completable: CompletableDeferred<CookieEntity> = CompletableDeferred()
|
||||
private lateinit var progressCallback: (Int) -> Unit
|
||||
|
||||
@ -69,7 +73,7 @@ class LoginWebView @JvmOverloads constructor(
|
||||
this@LoginWebView.progressCallback = progressCallback
|
||||
L.d { "Begin loading login" }
|
||||
launchMain {
|
||||
FbCookie.reset()
|
||||
fbCookie.reset()
|
||||
setupWebview()
|
||||
loadUrl(FB_LOGIN_URL)
|
||||
}
|
||||
@ -101,7 +105,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