More homescreen UI improvements
This commit is contained in:
parent
15b1215972
commit
24f6024383
@ -0,0 +1,84 @@
|
|||||||
|
package com.topjohnwu.magisk.model.entity
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.core.Const
|
||||||
|
import com.topjohnwu.magisk.databinding.RvItem
|
||||||
|
|
||||||
|
sealed class DeveloperItem {
|
||||||
|
|
||||||
|
abstract val items: List<IconLink>
|
||||||
|
abstract val name: Int
|
||||||
|
|
||||||
|
object Main : DeveloperItem() {
|
||||||
|
override val items =
|
||||||
|
listOf(
|
||||||
|
IconLink.Twitter.Main,
|
||||||
|
IconLink.Patreon,
|
||||||
|
IconLink.PayPal.Main,
|
||||||
|
IconLink.Github
|
||||||
|
)
|
||||||
|
override val name get() = R.string.topjohnwu
|
||||||
|
}
|
||||||
|
|
||||||
|
object App : DeveloperItem() {
|
||||||
|
override val items =
|
||||||
|
listOf<IconLink>(
|
||||||
|
IconLink.Twitter.App,
|
||||||
|
IconLink.PayPal.App
|
||||||
|
)
|
||||||
|
override val name get() = R.string.diareuse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface Dev {
|
||||||
|
val name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface MainDev: Dev {
|
||||||
|
override val name get() = "topjohnwu"
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface AppDev: Dev {
|
||||||
|
override val name get() = "diareuse"
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class IconLink : RvItem() {
|
||||||
|
|
||||||
|
abstract val icon: Int
|
||||||
|
abstract val title: Int
|
||||||
|
abstract val link: String
|
||||||
|
|
||||||
|
override val layoutRes get() = R.layout.item_icon_link
|
||||||
|
|
||||||
|
sealed class PayPal : IconLink(), Dev {
|
||||||
|
override val icon get() = R.drawable.ic_paypal
|
||||||
|
override val title get() = R.string.paypal
|
||||||
|
override val link get() = "https://paypal.me/$name"
|
||||||
|
|
||||||
|
object App : PayPal(), AppDev
|
||||||
|
|
||||||
|
object Main : PayPal(), MainDev
|
||||||
|
}
|
||||||
|
|
||||||
|
object Patreon : IconLink() {
|
||||||
|
override val icon get() = R.drawable.ic_patreon
|
||||||
|
override val title get() = R.string.patreon
|
||||||
|
override val link get() = Const.Url.PATREON_URL
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class Twitter : IconLink(), Dev {
|
||||||
|
override val icon get() = R.drawable.ic_twitter
|
||||||
|
override val title get() = R.string.twitter
|
||||||
|
override val link get() = "https://twitter.com/$name"
|
||||||
|
|
||||||
|
object App : Twitter(), AppDev
|
||||||
|
|
||||||
|
object Main : Twitter(), MainDev
|
||||||
|
}
|
||||||
|
|
||||||
|
object Github : IconLink() {
|
||||||
|
override val icon get() = R.drawable.ic_github
|
||||||
|
override val title get() = R.string.home_item_source
|
||||||
|
override val link get() = Const.Url.SOURCE_CODE_URL
|
||||||
|
}
|
||||||
|
}
|
@ -1,116 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
|
||||||
import com.topjohnwu.magisk.core.Const
|
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
|
||||||
|
|
||||||
sealed class HomeItem : ComparableRvItem<HomeItem>() {
|
|
||||||
|
|
||||||
abstract val icon: Int
|
|
||||||
abstract val title: Int
|
|
||||||
abstract val link: String
|
|
||||||
|
|
||||||
override val layoutRes = R.layout.item_developer_link
|
|
||||||
|
|
||||||
override fun contentSameAs(other: HomeItem) = itemSameAs(other)
|
|
||||||
override fun itemSameAs(other: HomeItem) = this == other
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (other !is HomeItem) return false
|
|
||||||
return icon == other.icon && title == other.title && link == other.link
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode() =
|
|
||||||
icon.hashCode() + title.hashCode() + link.hashCode() + layoutRes.hashCode()
|
|
||||||
|
|
||||||
// region Children
|
|
||||||
sealed class PayPal : HomeItem() {
|
|
||||||
override val icon = R.drawable.ic_paypal
|
|
||||||
override val title = R.string.paypal
|
|
||||||
override val link = "https://paypal.me/%s"
|
|
||||||
|
|
||||||
// region Children
|
|
||||||
object App : PayPal() {
|
|
||||||
override val link = super.link.format("diareuse")
|
|
||||||
}
|
|
||||||
|
|
||||||
object Mainline : PayPal() {
|
|
||||||
override val link = super.link.format("topjohnwu")
|
|
||||||
}
|
|
||||||
// endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
object Patreon : HomeItem() {
|
|
||||||
override val icon = R.drawable.ic_patreon
|
|
||||||
override val title = R.string.patreon
|
|
||||||
override val link = Const.Url.PATREON_URL
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class Twitter : HomeItem() {
|
|
||||||
override val icon = R.drawable.ic_twitter
|
|
||||||
override val title = R.string.twitter
|
|
||||||
override val link = "https://twitter.com/%s"
|
|
||||||
|
|
||||||
// region Children
|
|
||||||
object App : Twitter() {
|
|
||||||
override val link = super.link.format("diareuse")
|
|
||||||
}
|
|
||||||
|
|
||||||
object Mainline : Twitter() {
|
|
||||||
override val link = super.link.format("topjohnwu")
|
|
||||||
}
|
|
||||||
// endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
object Github : HomeItem() {
|
|
||||||
override val icon = R.drawable.ic_github
|
|
||||||
override val title = R.string.home_item_source
|
|
||||||
override val link = Const.Url.SOURCE_CODE_URL
|
|
||||||
}
|
|
||||||
|
|
||||||
object Xda : HomeItem() {
|
|
||||||
override val icon = R.drawable.ic_xda
|
|
||||||
override val title = R.string.xda
|
|
||||||
override val link = Const.Url.XDA_THREAD
|
|
||||||
}
|
|
||||||
// endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class DeveloperItem : ComparableRvItem<DeveloperItem>() {
|
|
||||||
|
|
||||||
abstract val items: List<HomeItem>
|
|
||||||
abstract val name: Int
|
|
||||||
|
|
||||||
override val layoutRes = R.layout.item_developer
|
|
||||||
|
|
||||||
override fun contentSameAs(other: DeveloperItem) = itemSameAs(other)
|
|
||||||
override fun itemSameAs(other: DeveloperItem) = this == other
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (other !is DeveloperItem) return false
|
|
||||||
return name == other.name && items == other.items
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode() = name.hashCode() + items.hashCode() + layoutRes.hashCode()
|
|
||||||
|
|
||||||
//region Children
|
|
||||||
object Mainline : DeveloperItem() {
|
|
||||||
override val items =
|
|
||||||
listOf(HomeItem.PayPal.Mainline, HomeItem.Patreon, HomeItem.Twitter.Mainline)
|
|
||||||
override val name = R.string.topjohnwu
|
|
||||||
}
|
|
||||||
|
|
||||||
object App : DeveloperItem() {
|
|
||||||
override val items =
|
|
||||||
listOf(HomeItem.PayPal.App, HomeItem.Twitter.App)
|
|
||||||
override val name = R.string.diareuse
|
|
||||||
}
|
|
||||||
|
|
||||||
object Project : DeveloperItem() {
|
|
||||||
override val items =
|
|
||||||
listOf(HomeItem.Github, HomeItem.Xda)
|
|
||||||
override val name = R.string.home_links_project
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
}
|
|
@ -2,6 +2,7 @@ package com.topjohnwu.magisk.ui.base
|
|||||||
|
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
|
import com.topjohnwu.magisk.databinding.RvItem
|
||||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.FilterableDiffObservableList
|
import com.topjohnwu.magisk.utils.FilterableDiffObservableList
|
||||||
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
||||||
@ -39,7 +40,7 @@ fun <T : ComparableRvItem<*>> adapterOf() = object : BindingRecyclerViewAdapter<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T : ComparableRvItem<*>> itemBindingOf(
|
inline fun <T : RvItem> itemBindingOf(
|
||||||
crossinline body: (ItemBinding<*>) -> Unit = {}
|
crossinline body: (ItemBinding<*>) -> Unit = {}
|
||||||
) = OnItemBind<T> { itemBinding, _, item ->
|
) = OnItemBind<T> { itemBinding, _, item ->
|
||||||
item.bind(itemBinding)
|
item.bind(itemBinding)
|
||||||
|
@ -15,9 +15,8 @@ import com.topjohnwu.magisk.data.repository.MagiskRepository
|
|||||||
import com.topjohnwu.magisk.ktx.await
|
import com.topjohnwu.magisk.ktx.await
|
||||||
import com.topjohnwu.magisk.ktx.packageName
|
import com.topjohnwu.magisk.ktx.packageName
|
||||||
import com.topjohnwu.magisk.ktx.res
|
import com.topjohnwu.magisk.ktx.res
|
||||||
|
import com.topjohnwu.magisk.model.entity.IconLink
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Manager
|
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Manager
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.DeveloperItem
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.HomeItem
|
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.model.events.OpenInappLinkEvent
|
import com.topjohnwu.magisk.model.events.OpenInappLinkEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
@ -77,11 +76,7 @@ class HomeViewModel(
|
|||||||
val showUninstall get() =
|
val showUninstall get() =
|
||||||
Info.env.magiskVersionCode > 0 && stateMagisk != MagiskState.LOADING && isConnected.get()
|
Info.env.magiskVersionCode > 0 && stateMagisk != MagiskState.LOADING && isConnected.get()
|
||||||
|
|
||||||
val items = listOf(DeveloperItem.Mainline, DeveloperItem.App, DeveloperItem.Project)
|
val itemBinding = itemBindingOf<IconLink> {
|
||||||
val itemBinding = itemBindingOf<HomeItem> {
|
|
||||||
it.bindExtra(BR.viewModel, this)
|
|
||||||
}
|
|
||||||
val itemDeveloperBinding = itemBindingOf<DeveloperItem> {
|
|
||||||
it.bindExtra(BR.viewModel, this)
|
it.bindExtra(BR.viewModel, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.view.ContextThemeWrapper
|
import android.view.ContextThemeWrapper
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.databinding.BindingAdapter
|
import androidx.databinding.BindingAdapter
|
||||||
@ -33,7 +33,7 @@ fun setOnNavigationClickedListener(view: Toolbar, listener: View.OnClickListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@BindingAdapter("srcCompat")
|
@BindingAdapter("srcCompat")
|
||||||
fun setImageResource(view: AppCompatImageView, @DrawableRes resId: Int) {
|
fun setImageResource(view: ImageView, @DrawableRes resId: Int) {
|
||||||
view.setImageResource(resId)
|
view.setImageResource(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
||||||
|
|
||||||
|
<import type="com.topjohnwu.magisk.model.entity.DeveloperItem"/>
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
type="com.topjohnwu.magisk.ui.home.HomeViewModel" />
|
type="com.topjohnwu.magisk.ui.home.HomeViewModel" />
|
||||||
@ -166,23 +168,21 @@
|
|||||||
android:text="@string/home_support_content"
|
android:text="@string/home_support_content"
|
||||||
android:textAppearance="@style/AppearanceFoundation.Caption.Variant" />
|
android:textAppearance="@style/AppearanceFoundation.Caption.Variant" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<include
|
||||||
dividerHorizontal="@{@drawable/divider_l1}"
|
layout="@layout/item_developer"
|
||||||
dividerVertical="@{@drawable/divider_l1}"
|
android:layout_width="wrap_content"
|
||||||
itemBinding="@{viewModel.itemDeveloperBinding}"
|
|
||||||
items="@{viewModel.items}"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/l1"
|
android:layout_marginTop="@dimen/l_50"
|
||||||
android:clipToPadding="false"
|
viewModel="@{viewModel}"
|
||||||
android:nestedScrollingEnabled="false"
|
item="@{DeveloperItem.Main.INSTANCE}" />
|
||||||
android:orientation="horizontal"
|
|
||||||
android:overScrollMode="ifContentScrolls"
|
<include
|
||||||
android:paddingStart="@dimen/l1"
|
layout="@layout/item_developer"
|
||||||
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
|
android:layout_width="wrap_content"
|
||||||
app:spanCount="2"
|
android:layout_height="wrap_content"
|
||||||
tools:itemCount="3"
|
android:layout_marginTop="@dimen/l_50"
|
||||||
tools:listitem="@layout/item_developer" />
|
viewModel="@{viewModel}"
|
||||||
|
item="@{DeveloperItem.App.INSTANCE}" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.DeveloperItem" />
|
type="com.topjohnwu.magisk.model.entity.DeveloperItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
@ -15,55 +15,35 @@
|
|||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
tools:layout_gravity="center|start">
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/l1" >
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<TextView
|
||||||
style="@style/WidgetFoundation.Card.Primary"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constrainedWidth="true"
|
android:text="@{item.name}"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:textAppearance="@style/AppearanceFoundation.Caption"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:textStyle="bold"
|
||||||
app:layout_constraintHorizontal_bias="0"
|
tools:text="\@topjohnwu" />
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:layout_width="match_parent"
|
itemBinding="@{viewModel.itemBinding}"
|
||||||
android:layout_height="wrap_content"
|
items="@{item.items}"
|
||||||
android:orientation="vertical"
|
nestedScrollingEnabled="@{false}"
|
||||||
android:padding="@dimen/l1">
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:fadingEdgeLength="@dimen/l1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingTop="@dimen/l_50"
|
||||||
|
android:requiresFadingEdge="horizontal"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:itemCount="3"
|
||||||
|
tools:listitem="@layout/item_icon_link" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
</LinearLayout>
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@{item.name}"
|
|
||||||
android:textAppearance="@style/AppearanceFoundation.Caption.OnPrimary"
|
|
||||||
android:textStyle="bold"
|
|
||||||
tools:text="\@topjohnwu" />
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
itemBinding="@{viewModel.itemBinding}"
|
|
||||||
items="@{item.items}"
|
|
||||||
nestedScrollingEnabled="@{false}"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:fadingEdgeLength="@dimen/l1"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingTop="@dimen/l_50"
|
|
||||||
android:requiresFadingEdge="horizontal"
|
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
|
||||||
tools:itemCount="3"
|
|
||||||
tools:listitem="@layout/item_developer_link" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.model.entity.recycler.HomeItem" />
|
type="com.topjohnwu.magisk.model.entity.IconLink" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
@ -24,12 +24,12 @@
|
|||||||
android:padding="@dimen/l_50"
|
android:padding="@dimen/l_50"
|
||||||
tools:layout_gravity="center">
|
tools:layout_gravity="center">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<ImageView
|
||||||
android:id="@+id/developer_link"
|
android:id="@+id/developer_link"
|
||||||
style="@style/WidgetFoundation.Image.Small"
|
style="@style/WidgetFoundation.Image.Small"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
app:srcCompat="@{item.icon}"
|
app:srcCompat="@{item.icon}"
|
||||||
app:tint="?colorOnPrimary"
|
app:tint="?colorOnSurface"
|
||||||
tools:srcCompat="@drawable/ic_paypal" />
|
tools:srcCompat="@drawable/ic_paypal" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
Loading…
Reference in New Issue
Block a user