diff options
Diffstat (limited to 'app/src')
-rw-r--r-- | app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt | 181 | ||||
-rw-r--r-- | app/src/main/res/drawable/nav_item_background.xml | 2 | ||||
-rw-r--r-- | app/src/main/res/layout/view_nav_header.xml | 103 | ||||
-rw-r--r-- | app/src/main/res/values/styles.xml | 42 |
4 files changed, 273 insertions, 55 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 5e79c93f..3543300d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt @@ -32,18 +32,26 @@ import android.webkit.ValueCallback import android.webkit.WebChromeClient import android.webkit.WebView import android.widget.FrameLayout +import android.widget.ImageView import androidx.annotation.ColorInt import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.widget.Toolbar +import androidx.core.view.updateLayoutParams +import androidx.drawerlayout.widget.DrawerLayout import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentPagerAdapter import ca.allanwang.kau.searchview.SearchItem import ca.allanwang.kau.searchview.SearchView import ca.allanwang.kau.searchview.SearchViewHolder import ca.allanwang.kau.searchview.bindSearchView +import ca.allanwang.kau.ui.ProgressAnimator import ca.allanwang.kau.utils.adjustAlpha +import ca.allanwang.kau.utils.colorToForeground import ca.allanwang.kau.utils.drawable import ca.allanwang.kau.utils.fadeScaleTransition +import ca.allanwang.kau.utils.gone +import ca.allanwang.kau.utils.invisible +import ca.allanwang.kau.utils.isVisible import ca.allanwang.kau.utils.materialDialog import ca.allanwang.kau.utils.restart import ca.allanwang.kau.utils.setIcon @@ -52,6 +60,7 @@ import ca.allanwang.kau.utils.showIf import ca.allanwang.kau.utils.string import ca.allanwang.kau.utils.tint import ca.allanwang.kau.utils.toDrawable +import ca.allanwang.kau.utils.visible import ca.allanwang.kau.utils.withMinAlpha import com.afollestad.materialdialogs.checkbox.checkBoxPrompt import com.google.android.material.appbar.AppBarLayout @@ -68,7 +77,9 @@ import com.pitchedapps.frost.contracts.VideoViewHolder import com.pitchedapps.frost.databinding.ActivityMainBinding import com.pitchedapps.frost.databinding.ActivityMainBottomTabsBinding import com.pitchedapps.frost.databinding.ActivityMainDrawerWrapperBinding +import com.pitchedapps.frost.databinding.ViewNavHeaderBinding import com.pitchedapps.frost.db.CookieDao +import com.pitchedapps.frost.db.CookieEntity import com.pitchedapps.frost.db.GenericDao import com.pitchedapps.frost.db.getTabs import com.pitchedapps.frost.enums.MainActivityLayout @@ -76,8 +87,11 @@ import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.parsers.FrostSearch import com.pitchedapps.frost.facebook.parsers.SearchParser +import com.pitchedapps.frost.facebook.profilePictureUrl import com.pitchedapps.frost.fragments.BaseFragment import com.pitchedapps.frost.fragments.WebFragment +import com.pitchedapps.frost.glide.FrostGlide +import com.pitchedapps.frost.glide.GlideApp import com.pitchedapps.frost.services.scheduleNotificationsFromPrefs import com.pitchedapps.frost.utils.ACTIVITY_SETTINGS import com.pitchedapps.frost.utils.BiometricUtils @@ -300,6 +314,8 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, itemTextColor = foregroundColor itemIconTintList = foregroundColor + val header = NavHeader() + addHeaderView(header.root) } } @@ -439,51 +455,126 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, // false // } // } -// drawerHeader.setActiveProfile(Prefs.userId) -// primaryFrostItem(FbItem.FEED_MOST_RECENT) -// primaryFrostItem(FbItem.FEED_TOP_STORIES) -// primaryFrostItem(FbItem.ACTIVITY_LOG) -// divider() -// primaryFrostItem(FbItem.PHOTOS) -// primaryFrostItem(FbItem.GROUPS) -// primaryFrostItem(FbItem.FRIENDS) -// primaryFrostItem(FbItem.CHAT) -// primaryFrostItem(FbItem.PAGES) -// divider() -// primaryFrostItem(FbItem.EVENTS) -// primaryFrostItem(FbItem.BIRTHDAYS) -// primaryFrostItem(FbItem.ON_THIS_DAY) -// divider() -// primaryFrostItem(FbItem.NOTES) -// primaryFrostItem(FbItem.SAVED) -// primaryFrostItem(FbItem.MARKETPLACE) -// } -// } - -// private fun Builder.primaryFrostItem(item: FbItem) = this.primaryItem(item.titleId) { -// iicon = item.icon -// iconColor = Prefs.textColor.toLong() -// textColor = Prefs.textColor.toLong() -// selectedIconColor = Prefs.textColor.toLong() -// selectedTextColor = Prefs.textColor.toLong() -// selectedColor = 0x00000001.toLong() -// identifier = item.titleId.toLong() -// onClick { _ -> -// frostEvent("Drawer Tab", "name" to item.name) -// launchWebOverlay(item.url) -// false -// } -// } -// -// private fun Builder.secondaryFrostItem(@StringRes title: Int, onClick: () -> Unit) = -// this.secondaryItem(title) { -// textColor = Prefs.textColor.toLong() -// selectedIconColor = Prefs.textColor.toLong() -// selectedTextColor = Prefs.textColor.toLong() -// selectedColor = 0x00000001.toLong() -// identifier = title.toLong() -// onClick { _ -> onClick(); false } -// } + + private inner class NavHeader { + + private var orderedAccounts: List<CookieEntity> = cookies() + private var pendingUpdate: Boolean = false + private val binding = ViewNavHeaderBinding.inflate(layoutInflater) + val root: View get() = binding.root + + init { + setPrimary(Prefs.userId) + binding.updateAccounts() + with(drawerWrapperBinding) { + drawer.addDrawerListener(object : DrawerLayout.SimpleDrawerListener() { + override fun onDrawerClosed(drawerView: View) { + if (drawer !== navigation) return + if (!pendingUpdate) return + pendingUpdate = false + binding.updateAccounts() + } + }) + } + with(binding) { + optionsContainer.setBackgroundColor( + Prefs.bgColor.withMinAlpha(200).colorToForeground( + 0.1f + ) + ) + var showOptions = false + val animator: ProgressAnimator = ProgressAnimator.ofFloat { } + background.setOnClickListener { + animator.reset() + if (showOptions) { + animator.apply { + withAnimator(optionsContainer.height.toFloat(), 0f) { + optionsContainer.updateLayoutParams { + height = it.toInt() + } + } + withEndAction { + optionsContainer.gone() + } + } + } else { + animator.apply { + optionsContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) + withAnimator( + optionsContainer.height.toFloat(), + optionsContainer.measuredHeight.toFloat() + ) { + optionsContainer.updateLayoutParams { + height = it.toInt() + } + } + withStartAction { + optionsContainer.visible() + } + } + } + showOptions = !showOptions + animator.start() + } + } + } + + private fun setPrimary(id: Long) { + val (primaries, others) = orderedAccounts.partition { it.id == id } + if (primaries.size != 1) { + L._e(null) { "Updating account primaries, could not find specified id" } + } + orderedAccounts = primaries + others + } + + /** + * Syncs UI to match [orderedAccounts]. + * + * We keep this separate as we usually only want to update when the drawer is hidden. + */ + private fun ViewNavHeaderBinding.updateAccounts() { + avatarPrimary.setAccount(orderedAccounts.getOrNull(0), true) + avatarSecondary.setAccount(orderedAccounts.getOrNull(1), false) + avatarTertiary.setAccount(orderedAccounts.getOrNull(2), false) + } + + private fun closeDrawer() { + with(drawerWrapperBinding) { + drawer.closeDrawer(navigation) + } + } + + private fun ImageView.setAccount( + cookie: CookieEntity?, + primary: Boolean + ) { + if (cookie == null) { + invisible() + setOnClickListener(null) + } else { + visible() + GlideApp.with(this) + .load(profilePictureUrl(cookie.id)) + .transform(FrostGlide.circleCrop) + .into(this) + setOnClickListener { + if (primary) { + launchWebOverlay(FbItem.PROFILE.url) + } else { + setPrimary(cookie.id) + pendingUpdate = true + closeDrawer() + launch { + FbCookie.switchUser(cookie.id) + tabsForEachView { _, view -> view.badgeText = null } + refreshAll() + } + } + closeDrawer() + } + } + } + } private fun refreshAll() { L.d { "Refresh all" } diff --git a/app/src/main/res/drawable/nav_item_background.xml b/app/src/main/res/drawable/nav_item_background.xml index 7c7a7209..415dd9f2 100644 --- a/app/src/main/res/drawable/nav_item_background.xml +++ b/app/src/main/res/drawable/nav_item_background.xml @@ -3,7 +3,7 @@ android:color="#f0f"> <item android:id="@android:id/mask" - android:right="8dp"> + android:right="16dp"> <shape android:shape="rectangle"> <corners android:bottomRightRadius="50dp" diff --git a/app/src/main/res/layout/view_nav_header.xml b/app/src/main/res/layout/view_nav_header.xml new file mode 100644 index 00000000..af918736 --- /dev/null +++ b/app/src/main/res/layout/view_nav_header.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="160dp"> + + <androidx.appcompat.widget.AppCompatImageView + android:id="@+id/background" + android:layout_width="0dp" + android:layout_height="160dp" + android:scaleType="centerCrop" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:src="@tools:sample/backgrounds/scenic" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/status_bar_guide" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_begin="24dp" /> + + <ImageView + android:id="@+id/avatar_primary" + style="@style/Main.DrawerPrimaryAvatar" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/status_bar_guide" + tools:src="@tools:sample/avatars" /> + + <ImageView + android:id="@+id/avatar_secondary" + style="@style/Main.DrawerSecondaryAvatar" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/status_bar_guide" + tools:src="@tools:sample/avatars" /> + + <ImageView + android:id="@+id/avatar_tertiary" + style="@style/Main.DrawerSecondaryAvatar" + app:layout_constraintEnd_toStartOf="@id/avatar_secondary" + app:layout_constraintTop_toBottomOf="@id/status_bar_guide" + tools:src="@tools:sample/avatars" /> + + <TextView + android:id="@+id/name" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/kau_activity_horizontal_margin" + android:layout_marginTop="@dimen/kau_activity_vertical_margin" + android:layout_marginEnd="@dimen/kau_activity_horizontal_margin" + android:layout_marginBottom="@dimen/kau_activity_vertical_margin" + android:clickable="false" + android:lines="1" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/arrow" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/avatar_primary" + app:layout_constraintVertical_bias="1" + tools:text="@tools:sample/full_names" /> + + <ImageView + android:id="@+id/arrow" + android:layout_width="18dp" + android:layout_height="18dp" + android:layout_marginStart="@dimen/kau_activity_horizontal_margin" + android:layout_marginEnd="@dimen/kau_activity_horizontal_margin" + app:layout_constraintBottom_toBottomOf="@id/name" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@id/name" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <LinearLayout + android:id="@+id/options_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" + tools:visibility="visible"> + + <TextView + android:id="@+id/options_add_account" + style="@style/Main.DrawerAccountOptions" + android:text="@string/kau_add_account" + tools:drawableStart="@drawable/abc_vector_test" /> + + <TextView + android:id="@+id/options_logout" + style="@style/Main.DrawerAccountOptions" + android:text="@string/kau_logout" + tools:drawableStart="@drawable/abc_vector_test" /> + + </LinearLayout> + +</LinearLayout> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 3cbad6d7..b194a975 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -107,13 +107,13 @@ <item name="popupTheme">@style/AppTheme.PopupOverlay</item> </style> - <style name="Main.ViewPager" parent="" > + <style name="Main.ViewPager" parent=""> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="layout_behavior">@string/appbar_scrolling_view_behavior</item> </style> - <style name="Main.Fab" parent="" > + <style name="Main.Fab" parent="Widget.Design.NavigationView"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_gravity">end|bottom</item> @@ -132,12 +132,36 @@ <item name="android:colorControlHighlight">@android:color/transparent</item> </style> -<!-- <style name="ShapeAppearanceOverlay.Item" parent="">--> -<!-- <item name="cornerFamily">rounded</item>--> -<!-- <item name="cornerSizeTopRight">10dp</item>--> -<!-- <item name="cornerSizeBottomRight">10dp</item>--> -<!-- <item name="cornerSizeBottomLeft">0dp</item>--> -<!-- <item name="cornerSizeTopLeft">0dp</item>--> -<!-- </style>--> + <!-- <style name="ShapeAppearanceOverlay.Item" parent="">--> + <!-- <item name="cornerFamily">rounded</item>--> + <!-- <item name="cornerSizeTopRight">10dp</item>--> + <!-- <item name="cornerSizeBottomRight">10dp</item>--> + <!-- <item name="cornerSizeBottomLeft">0dp</item>--> + <!-- <item name="cornerSizeTopLeft">0dp</item>--> + <!-- </style>--> + + <style name="Main.DrawerMargins" parent=""> + <item name="android:layout_marginStart">@dimen/kau_activity_horizontal_margin</item> + <item name="android:layout_marginEnd">@dimen/kau_activity_horizontal_margin</item> + <item name="android:layout_marginTop">@dimen/kau_activity_vertical_margin</item> + <item name="android:layout_marginBottom">@dimen/kau_activity_vertical_margin</item> + </style> + + <style name="Main.DrawerPrimaryAvatar" parent="Main.DrawerMargins"> + <item name="android:layout_width">56dp</item> + <item name="android:layout_height">56dp</item> + </style> + + <style name="Main.DrawerSecondaryAvatar" parent="Main.DrawerMargins"> + <item name="android:layout_width">40dp</item> + <item name="android:layout_height">40dp</item> + </style> + + <style name="Main.DrawerAccountOptions" parent="Main.DrawerMargins"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:drawablePadding">16dp</item> + <item name="android:gravity">center_vertical</item> + </style> </resources> |