Refactor overflow menus into a composable
This commit is contained in:
parent
f5451a6881
commit
df773ee15c
4 changed files with 139 additions and 142 deletions
|
@ -1,20 +1,29 @@
|
||||||
package eu.kanade.presentation.components
|
package eu.kanade.presentation.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.sizeIn
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.MoreVert
|
||||||
import androidx.compose.material.icons.outlined.RadioButtonChecked
|
import androidx.compose.material.icons.outlined.RadioButtonChecked
|
||||||
import androidx.compose.material.icons.outlined.RadioButtonUnchecked
|
import androidx.compose.material.icons.outlined.RadioButtonUnchecked
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.DpOffset
|
import androidx.compose.ui.unit.DpOffset
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.PopupProperties
|
import androidx.compose.ui.window.PopupProperties
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import me.saket.cascade.CascadeColumnScope
|
||||||
|
import me.saket.cascade.CascadeDropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenu as ComposeDropdownMenu
|
import androidx.compose.material3.DropdownMenu as ComposeDropdownMenu
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -61,3 +70,27 @@ fun RadioMenuItem(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OverflowMenu(
|
||||||
|
content: @Composable CascadeColumnScope.(() -> Unit) -> Unit,
|
||||||
|
) {
|
||||||
|
var moreExpanded by remember { mutableStateOf(false) }
|
||||||
|
val closeMenu = { moreExpanded = false }
|
||||||
|
|
||||||
|
Box {
|
||||||
|
IconButton(onClick = { moreExpanded = !moreExpanded }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.MoreVert,
|
||||||
|
contentDescription = stringResource(R.string.abc_action_menu_overflow_description),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
CascadeDropdownMenu(
|
||||||
|
expanded = moreExpanded,
|
||||||
|
onDismissRequest = closeMenu,
|
||||||
|
offset = DpOffset(8.dp, (-56).dp),
|
||||||
|
) {
|
||||||
|
content(closeMenu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package eu.kanade.presentation.library.components
|
package eu.kanade.presentation.library.components
|
||||||
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.FilterList
|
import androidx.compose.material.icons.outlined.FilterList
|
||||||
import androidx.compose.material.icons.outlined.FlipToBack
|
import androidx.compose.material.icons.outlined.FlipToBack
|
||||||
import androidx.compose.material.icons.outlined.MoreVert
|
|
||||||
import androidx.compose.material.icons.outlined.Search
|
import androidx.compose.material.icons.outlined.Search
|
||||||
import androidx.compose.material.icons.outlined.SelectAll
|
import androidx.compose.material.icons.outlined.SelectAll
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
|
@ -19,10 +17,6 @@ import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
|
@ -32,7 +26,7 @@ import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.DropdownMenu
|
import eu.kanade.presentation.components.OverflowMenu
|
||||||
import eu.kanade.presentation.components.Pill
|
import eu.kanade.presentation.components.Pill
|
||||||
import eu.kanade.presentation.components.SearchToolbar
|
import eu.kanade.presentation.components.SearchToolbar
|
||||||
import eu.kanade.presentation.library.LibraryState
|
import eu.kanade.presentation.library.LibraryState
|
||||||
|
@ -137,35 +131,22 @@ fun LibraryRegularToolbar(
|
||||||
IconButton(onClick = onClickFilter) {
|
IconButton(onClick = onClickFilter) {
|
||||||
Icon(Icons.Outlined.FilterList, contentDescription = stringResource(R.string.action_filter), tint = filterTint)
|
Icon(Icons.Outlined.FilterList, contentDescription = stringResource(R.string.action_filter), tint = filterTint)
|
||||||
}
|
}
|
||||||
var moreExpanded by remember { mutableStateOf(false) }
|
OverflowMenu { closeMenu ->
|
||||||
Box {
|
|
||||||
IconButton(onClick = { moreExpanded = !moreExpanded }) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Outlined.MoreVert,
|
|
||||||
contentDescription = stringResource(R.string.abc_action_menu_overflow_description),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val onDismissRequest = { moreExpanded = false }
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = moreExpanded,
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
) {
|
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.pref_category_library_update)) },
|
text = { Text(text = stringResource(R.string.pref_category_library_update)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
onClickRefresh()
|
onClickRefresh()
|
||||||
onDismissRequest()
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.action_open_random_manga)) },
|
text = { Text(text = stringResource(R.string.action_open_random_manga)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
onClickOpenRandomManga()
|
onClickOpenRandomManga()
|
||||||
onDismissRequest()
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
incognitoMode = incognitoMode,
|
incognitoMode = incognitoMode,
|
||||||
downloadedOnlyMode = downloadedOnlyMode,
|
downloadedOnlyMode = downloadedOnlyMode,
|
||||||
|
|
|
@ -8,7 +8,6 @@ import androidx.compose.material.icons.outlined.Close
|
||||||
import androidx.compose.material.icons.outlined.Download
|
import androidx.compose.material.icons.outlined.Download
|
||||||
import androidx.compose.material.icons.outlined.FilterList
|
import androidx.compose.material.icons.outlined.FilterList
|
||||||
import androidx.compose.material.icons.outlined.FlipToBack
|
import androidx.compose.material.icons.outlined.FlipToBack
|
||||||
import androidx.compose.material.icons.outlined.MoreVert
|
|
||||||
import androidx.compose.material.icons.outlined.SelectAll
|
import androidx.compose.material.icons.outlined.SelectAll
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
@ -20,10 +19,8 @@ import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
@ -31,6 +28,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.presentation.components.AppStateBanners
|
import eu.kanade.presentation.components.AppStateBanners
|
||||||
import eu.kanade.presentation.components.DropdownMenu
|
import eu.kanade.presentation.components.DropdownMenu
|
||||||
|
import eu.kanade.presentation.components.OverflowMenu
|
||||||
import eu.kanade.presentation.manga.DownloadAction
|
import eu.kanade.presentation.manga.DownloadAction
|
||||||
import eu.kanade.presentation.theme.active
|
import eu.kanade.presentation.theme.active
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
@ -157,25 +155,13 @@ fun MangaToolbar(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onClickEditCategory != null || onClickMigrate != null || onClickShare != null) {
|
if (onClickEditCategory != null || onClickMigrate != null || onClickShare != null) {
|
||||||
var moreExpanded by remember { mutableStateOf(false) }
|
OverflowMenu { closeMenu ->
|
||||||
Box {
|
|
||||||
IconButton(onClick = { moreExpanded = !moreExpanded }) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Outlined.MoreVert,
|
|
||||||
contentDescription = stringResource(R.string.abc_action_menu_overflow_description),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val onDismissRequest = { moreExpanded = false }
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = moreExpanded,
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
) {
|
|
||||||
if (onClickEditCategory != null) {
|
if (onClickEditCategory != null) {
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.action_edit_categories)) },
|
text = { Text(text = stringResource(R.string.action_edit_categories)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
onClickEditCategory()
|
onClickEditCategory()
|
||||||
onDismissRequest()
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -184,7 +170,7 @@ fun MangaToolbar(
|
||||||
text = { Text(text = stringResource(R.string.action_migrate)) },
|
text = { Text(text = stringResource(R.string.action_migrate)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
onClickMigrate()
|
onClickMigrate()
|
||||||
onDismissRequest()
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -193,14 +179,13 @@ fun MangaToolbar(
|
||||||
text = { Text(text = stringResource(R.string.action_share)) },
|
text = { Text(text = stringResource(R.string.action_share)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
onClickShare()
|
onClickShare()
|
||||||
onDismissRequest()
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
colors = TopAppBarDefaults.smallTopAppBarColors(
|
colors = TopAppBarDefaults.smallTopAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme
|
containerColor = MaterialTheme.colorScheme
|
||||||
|
|
|
@ -14,11 +14,9 @@ import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
import androidx.compose.material.icons.outlined.MoreVert
|
|
||||||
import androidx.compose.material.icons.outlined.Pause
|
import androidx.compose.material.icons.outlined.Pause
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
@ -52,6 +50,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
import eu.kanade.presentation.components.EmptyScreen
|
||||||
import eu.kanade.presentation.components.ExtendedFloatingActionButton
|
import eu.kanade.presentation.components.ExtendedFloatingActionButton
|
||||||
|
import eu.kanade.presentation.components.OverflowMenu
|
||||||
import eu.kanade.presentation.components.Pill
|
import eu.kanade.presentation.components.Pill
|
||||||
import eu.kanade.presentation.components.Scaffold
|
import eu.kanade.presentation.components.Scaffold
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
@ -61,7 +60,6 @@ import eu.kanade.tachiyomi.databinding.DownloadListBinding
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.FullComposeController
|
import eu.kanade.tachiyomi.ui.base.controller.FullComposeController
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import me.saket.cascade.CascadeDropdownMenu
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
|
@ -147,18 +145,7 @@ class DownloadController :
|
||||||
navigateUp = router::popCurrentController,
|
navigateUp = router::popCurrentController,
|
||||||
actions = {
|
actions = {
|
||||||
if (downloadList.isNotEmpty()) {
|
if (downloadList.isNotEmpty()) {
|
||||||
var expanded by remember { mutableStateOf(false) }
|
OverflowMenu { closeMenu ->
|
||||||
Box {
|
|
||||||
IconButton(onClick = { expanded = !expanded }) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Outlined.MoreVert,
|
|
||||||
contentDescription = stringResource(R.string.abc_action_menu_overflow_description),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
CascadeDropdownMenu(
|
|
||||||
expanded = expanded,
|
|
||||||
onDismissRequest = { expanded = false },
|
|
||||||
) {
|
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.action_reorganize_by)) },
|
text = { Text(text = stringResource(R.string.action_reorganize_by)) },
|
||||||
children = {
|
children = {
|
||||||
|
@ -168,15 +155,21 @@ class DownloadController :
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.action_newest)) },
|
text = { Text(text = stringResource(R.string.action_newest)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
reorderQueue({ it.download.chapter.date_upload }, true)
|
reorderQueue(
|
||||||
expanded = false
|
{ it.download.chapter.date_upload },
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.action_oldest)) },
|
text = { Text(text = stringResource(R.string.action_oldest)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
reorderQueue({ it.download.chapter.date_upload }, false)
|
reorderQueue(
|
||||||
expanded = false
|
{ it.download.chapter.date_upload },
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -187,15 +180,21 @@ class DownloadController :
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.action_asc)) },
|
text = { Text(text = stringResource(R.string.action_asc)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
reorderQueue({ it.download.chapter.chapter_number }, false)
|
reorderQueue(
|
||||||
expanded = false
|
{ it.download.chapter.chapter_number },
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(text = stringResource(R.string.action_desc)) },
|
text = { Text(text = stringResource(R.string.action_desc)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
reorderQueue({ it.download.chapter.chapter_number }, true)
|
reorderQueue(
|
||||||
expanded = false
|
{ it.download.chapter.chapter_number },
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -206,12 +205,11 @@ class DownloadController :
|
||||||
text = { Text(text = stringResource(R.string.action_cancel_all)) },
|
text = { Text(text = stringResource(R.string.action_cancel_all)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
presenter.clearQueue(context)
|
presenter.clearQueue(context)
|
||||||
expanded = false
|
closeMenu()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
)
|
)
|
||||||
|
|
Reference in a new issue