aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt72
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt20
-rw-r--r--app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json189
-rw-r--r--app/src/schemas/com.pitchedapps.frost.db.FrostPublicDatabase/1.json40
4 files changed, 291 insertions, 30 deletions
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 4669418d..ca30401a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
@@ -123,7 +123,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
FileChooserContract by FileChooserDelegate(),
VideoViewHolder, SearchViewHolder {
- protected lateinit var adapter: SectionsPagerAdapter
+ /**
+ * Note that tabs themselves are initialized through a coroutine during onCreate
+ */
+ protected val adapter: SectionsPagerAdapter = SectionsPagerAdapter()
override val frameWrapper: FrameLayout get() = frame_wrapper
val viewPager: FrostViewPager get() = container
val cookieDao: CookieDao by inject()
@@ -136,6 +139,8 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
val appBar: AppBarLayout by bindView(R.id.appbar)
val coordinator: CoordinatorLayout by bindView(R.id.main_content)
+ protected var lastPosition = -1
+
override var videoViewer: FrostVideoViewer? = null
private lateinit var drawer: Drawer
private lateinit var drawerHeader: AccountHeader
@@ -156,14 +161,14 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
background(viewPager)
}
setSupportActionBar(toolbar)
- launch {
- adapter = SectionsPagerAdapter(tabDao.selectAll())
- viewPager.adapter = adapter
- viewPager.offscreenPageLimit = TAB_COUNT
- }
+ viewPager.adapter = adapter
+ viewPager.offscreenPageLimit = TAB_COUNT
tabs.setBackgroundColor(Prefs.mainActivityLayout.backgroundColor())
onNestedCreate(savedInstanceState)
L.i { "Main finished loading UI in ${System.currentTimeMillis() - start} ms" }
+ launch {
+ adapter.setPages(tabDao.selectAll())
+ }
controlWebview = WebView(this)
if (BuildConfig.VERSION_CODE > Prefs.versionCode) {
Prefs.prevVersionCode = Prefs.versionCode
@@ -462,16 +467,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
- outState.putStringArrayList(STATE_FORCE_FALLBACK, ArrayList(adapter.forcedFallbacks))
+ adapter.saveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
- adapter.forcedFallbacks.clear()
- adapter.forcedFallbacks.addAll(
- savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK)
- ?: emptyList()
- )
+ adapter.restoreInstanceState(savedInstanceState)
}
override fun onResume() {
@@ -526,9 +527,47 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
runOnUiThread { adapter.reloadFragment(fragment) }
}
- inner class SectionsPagerAdapter(val pages: List<FbItem>) : FragmentPagerAdapter(supportFragmentManager) {
+ inner class SectionsPagerAdapter : FragmentPagerAdapter(supportFragmentManager) {
+
+ private val pages: MutableList<FbItem> = mutableListOf()
- val forcedFallbacks = mutableSetOf<String>()
+ private val forcedFallbacks = mutableSetOf<String>()
+
+ /**
+ * Update page list and prompt reload
+ */
+ fun setPages(pages: List<FbItem>) {
+ this.pages.clear()
+ this.pages.addAll(pages)
+ notifyDataSetChanged()
+ tabs.removeAllTabs()
+ this.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)
+ })
+ )
+ }
+ lastPosition = 0
+ viewPager.setCurrentItem(0, false)
+ viewPager.post {
+ if (!fragmentChannel.isClosedForSend)
+ fragmentChannel.offer(0)
+ } //trigger hook so title is set
+ }
+
+ fun saveInstanceState(outState: Bundle) {
+ outState.putStringArrayList(STATE_FORCE_FALLBACK, ArrayList(forcedFallbacks))
+ }
+
+ fun restoreInstanceState(savedInstanceState: Bundle) {
+ forcedFallbacks.clear()
+ forcedFallbacks.addAll(
+ savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK)
+ ?: emptyList()
+ )
+ }
fun reloadFragment(fragment: BaseFragment) {
if (fragment is WebFragment) return
@@ -567,4 +606,9 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
PointF(0f, toolbar.height.toFloat())
else
PointF(0f, 0f)
+
+ companion object {
+ const val SELECTED_TAB_ALPHA = 255f
+ const val UNSELECTED_TAB_ALPHA = 128f
+ }
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
index 75c9537b..34674cb0 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
@@ -35,7 +35,6 @@ class MainActivity : BaseMainActivity() {
override val fragmentChannel = BroadcastChannel<Int>(10)
override val headerBadgeChannel = BroadcastChannel<String>(Channel.CONFLATED)
- var lastPosition = -1
override fun onNestedCreate(savedInstanceState: Bundle?) {
setupTabs()
@@ -54,23 +53,18 @@ class MainActivity : BaseMainActivity() {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
- val delta = positionOffset * (255 - 128).toFloat()
+ val delta = positionOffset * (SELECTED_TAB_ALPHA - UNSELECTED_TAB_ALPHA)
tabsForEachView { tabPosition, view ->
view.setAllAlpha(
when (tabPosition) {
- position -> 255.0f - delta
- position + 1 -> 128.0f + delta
- else -> 128f
+ position -> SELECTED_TAB_ALPHA - delta
+ position + 1 -> UNSELECTED_TAB_ALPHA + delta
+ else -> UNSELECTED_TAB_ALPHA
}
)
}
}
})
- viewPager.post {
- if (!fragmentChannel.isClosedForSend)
- fragmentChannel.offer(0)
- lastPosition = 0
- } //trigger hook so title is set
}
private fun setupTabs() {
@@ -115,11 +109,5 @@ class MainActivity : BaseMainActivity() {
L.e(e) { "Header badge error" }
}
}
- adapter.pages.forEach {
- tabs.addTab(
- tabs.newTab()
- .setCustomView(BadgedIcon(this).apply { iicon = it.icon })
- )
- }
}
}
diff --git a/app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json b/app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json
new file mode 100644
index 00000000..60d5cddd
--- /dev/null
+++ b/app/src/schemas/com.pitchedapps.frost.db.FrostPrivateDatabase/1.json
@@ -0,0 +1,189 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "0a9d994786b7e07fea95c11d9210ce0e",
+ "entities": [
+ {
+ "tableName": "cookies",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`cookie_id` INTEGER NOT NULL, `name` TEXT, `cookie` TEXT, PRIMARY KEY(`cookie_id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "cookie_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "cookie",
+ "columnName": "cookie",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "cookie_id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "notifications",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`notif_id` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `href` TEXT NOT NULL, `title` TEXT, `text` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, `profileUrl` TEXT, `type` TEXT NOT NULL, PRIMARY KEY(`notif_id`, `userId`), FOREIGN KEY(`userId`) REFERENCES `cookies`(`cookie_id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "notif_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "userId",
+ "columnName": "userId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "href",
+ "columnName": "href",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "text",
+ "columnName": "text",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "profileUrl",
+ "columnName": "profileUrl",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "notif_id",
+ "userId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_notifications_notif_id",
+ "unique": false,
+ "columnNames": [
+ "notif_id"
+ ],
+ "createSql": "CREATE INDEX `index_notifications_notif_id` ON `${TABLE_NAME}` (`notif_id`)"
+ },
+ {
+ "name": "index_notifications_userId",
+ "unique": false,
+ "columnNames": [
+ "userId"
+ ],
+ "createSql": "CREATE INDEX `index_notifications_userId` ON `${TABLE_NAME}` (`userId`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "cookies",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "userId"
+ ],
+ "referencedColumns": [
+ "cookie_id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "frost_cache",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `type` TEXT NOT NULL, `lastUpdated` INTEGER NOT NULL, `contents` TEXT NOT NULL, PRIMARY KEY(`id`, `type`), FOREIGN KEY(`id`) REFERENCES `cookies`(`cookie_id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastUpdated",
+ "columnName": "lastUpdated",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "contents",
+ "columnName": "contents",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id",
+ "type"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": [
+ {
+ "table": "cookies",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "id"
+ ],
+ "referencedColumns": [
+ "cookie_id"
+ ]
+ }
+ ]
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"0a9d994786b7e07fea95c11d9210ce0e\")"
+ ]
+ }
+} \ No newline at end of file
diff --git a/app/src/schemas/com.pitchedapps.frost.db.FrostPublicDatabase/1.json b/app/src/schemas/com.pitchedapps.frost.db.FrostPublicDatabase/1.json
new file mode 100644
index 00000000..fe2aa83e
--- /dev/null
+++ b/app/src/schemas/com.pitchedapps.frost.db.FrostPublicDatabase/1.json
@@ -0,0 +1,40 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "fde868470836ff9230f1d406922d7563",
+ "entities": [
+ {
+ "tableName": "tabs",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`position` INTEGER NOT NULL, `tab` TEXT NOT NULL, PRIMARY KEY(`position`))",
+ "fields": [
+ {
+ "fieldPath": "position",
+ "columnName": "position",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tab",
+ "columnName": "tab",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "position"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"fde868470836ff9230f1d406922d7563\")"
+ ]
+ }
+} \ No newline at end of file