Refactor overflow menus into a composable

This commit is contained in:
arkon 2022-10-30 11:06:41 -04:00
parent f5451a6881
commit df773ee15c
4 changed files with 139 additions and 142 deletions

View file

@ -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)
}
}
}

View file

@ -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,34 +131,21 @@ 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 { DropdownMenuItem(
IconButton(onClick = { moreExpanded = !moreExpanded }) { text = { Text(text = stringResource(R.string.pref_category_library_update)) },
Icon( onClick = {
imageVector = Icons.Outlined.MoreVert, onClickRefresh()
contentDescription = stringResource(R.string.abc_action_menu_overflow_description), closeMenu()
) },
} )
val onDismissRequest = { moreExpanded = false } DropdownMenuItem(
DropdownMenu( text = { Text(text = stringResource(R.string.action_open_random_manga)) },
expanded = moreExpanded, onClick = {
onDismissRequest = onDismissRequest, onClickOpenRandomManga()
) { closeMenu()
DropdownMenuItem( },
text = { Text(text = stringResource(R.string.pref_category_library_update)) }, )
onClick = {
onClickRefresh()
onDismissRequest()
},
)
DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_open_random_manga)) },
onClick = {
onClickOpenRandomManga()
onDismissRequest()
},
)
}
} }
}, },
incognitoMode = incognitoMode, incognitoMode = incognitoMode,

View file

@ -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,46 +155,33 @@ 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 { if (onClickEditCategory != null) {
IconButton(onClick = { moreExpanded = !moreExpanded }) { DropdownMenuItem(
Icon( text = { Text(text = stringResource(R.string.action_edit_categories)) },
imageVector = Icons.Outlined.MoreVert, onClick = {
contentDescription = stringResource(R.string.abc_action_menu_overflow_description), onClickEditCategory()
closeMenu()
},
) )
} }
val onDismissRequest = { moreExpanded = false } if (onClickMigrate != null) {
DropdownMenu( DropdownMenuItem(
expanded = moreExpanded, text = { Text(text = stringResource(R.string.action_migrate)) },
onDismissRequest = onDismissRequest, onClick = {
) { onClickMigrate()
if (onClickEditCategory != null) { closeMenu()
DropdownMenuItem( },
text = { Text(text = stringResource(R.string.action_edit_categories)) }, )
onClick = { }
onClickEditCategory() if (onClickShare != null) {
onDismissRequest() DropdownMenuItem(
}, text = { Text(text = stringResource(R.string.action_share)) },
) onClick = {
} onClickShare()
if (onClickMigrate != null) { closeMenu()
DropdownMenuItem( },
text = { Text(text = stringResource(R.string.action_migrate)) }, )
onClick = {
onClickMigrate()
onDismissRequest()
},
)
}
if (onClickShare != null) {
DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_share)) },
onClick = {
onClickShare()
onDismissRequest()
},
)
}
} }
} }
} }

View file

@ -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,69 +145,69 @@ 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 { DropdownMenuItem(
IconButton(onClick = { expanded = !expanded }) { text = { Text(text = stringResource(R.string.action_reorganize_by)) },
Icon( children = {
imageVector = Icons.Outlined.MoreVert, DropdownMenuItem(
contentDescription = stringResource(R.string.abc_action_menu_overflow_description), text = { Text(text = stringResource(R.string.action_order_by_upload_date)) },
) children = {
} DropdownMenuItem(
CascadeDropdownMenu( text = { Text(text = stringResource(R.string.action_newest)) },
expanded = expanded, onClick = {
onDismissRequest = { expanded = false }, reorderQueue(
) { { it.download.chapter.date_upload },
DropdownMenuItem( true,
text = { Text(text = stringResource(R.string.action_reorganize_by)) }, )
children = { closeMenu()
DropdownMenuItem( },
text = { Text(text = stringResource(R.string.action_order_by_upload_date)) }, )
children = { DropdownMenuItem(
DropdownMenuItem( text = { Text(text = stringResource(R.string.action_oldest)) },
text = { Text(text = stringResource(R.string.action_newest)) }, onClick = {
onClick = { reorderQueue(
reorderQueue({ it.download.chapter.date_upload }, true) { it.download.chapter.date_upload },
expanded = false false,
}, )
) closeMenu()
DropdownMenuItem( },
text = { Text(text = stringResource(R.string.action_oldest)) }, )
onClick = { },
reorderQueue({ it.download.chapter.date_upload }, false) )
expanded = false DropdownMenuItem(
}, text = { Text(text = stringResource(R.string.action_order_by_chapter_number)) },
) children = {
}, DropdownMenuItem(
) text = { Text(text = stringResource(R.string.action_asc)) },
DropdownMenuItem( onClick = {
text = { Text(text = stringResource(R.string.action_order_by_chapter_number)) }, reorderQueue(
children = { { it.download.chapter.chapter_number },
DropdownMenuItem( false,
text = { Text(text = stringResource(R.string.action_asc)) }, )
onClick = { closeMenu()
reorderQueue({ it.download.chapter.chapter_number }, false) },
expanded = false )
}, DropdownMenuItem(
) text = { Text(text = stringResource(R.string.action_desc)) },
DropdownMenuItem( onClick = {
text = { Text(text = stringResource(R.string.action_desc)) }, reorderQueue(
onClick = { { it.download.chapter.chapter_number },
reorderQueue({ it.download.chapter.chapter_number }, true) true,
expanded = false )
}, closeMenu()
) },
}, )
) },
}, )
) },
DropdownMenuItem( )
text = { Text(text = stringResource(R.string.action_cancel_all)) }, DropdownMenuItem(
onClick = { text = { Text(text = stringResource(R.string.action_cancel_all)) },
presenter.clearQueue(context) onClick = {
expanded = false presenter.clearQueue(context)
}, closeMenu()
) },
} )
} }
} }
}, },