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