Skip to content

Commit

Permalink
feat(player): Add custom buttons (#196)
Browse files Browse the repository at this point in the history
* feat(player): Add custom buttons (aniyomiorg#1855)

* fix BackupCreator

---------

Co-authored-by: Secozzi <[email protected]>
  • Loading branch information
Dark25 and Secozzi authored Jan 17, 2025
1 parent 52d5e04 commit d65dd4e
Show file tree
Hide file tree
Showing 48 changed files with 1,987 additions and 187 deletions.
65 changes: 65 additions & 0 deletions app/src/main/assets/aniyomi.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
aniyomi = {}
function aniyomi.show_text(text)
mp.set_property("user-data/aniyomi/show_text", text)
end
function aniyomi.hide_ui()
mp.set_property("user-data/aniyomi/toggle_ui", "hide")
end
function aniyomi.show_ui()
mp.set_property("user-data/aniyomi/toggle_ui", "show")
end
function aniyomi.toggle_ui()
mp.set_property("user-data/aniyomi/toggle_ui", "toggle")
end
function aniyomi.show_subtitle_settings()
mp.set_property("user-data/aniyomi/show_panel", "subtitle_settings")
end
function aniyomi.show_subtitle_delay()
mp.set_property("user-data/aniyomi/show_panel", "subtitle_delay")
end
function aniyomi.show_audio_delay()
mp.set_property("user-data/aniyomi/show_panel", "audio_delay")
end
function aniyomi.show_video_filters()
mp.set_property("user-data/aniyomi/show_panel", "video_filters")
end
function aniyomi.set_button_title(text)
mp.set_property("user-data/aniyomi/set_button_title", text)
end
function aniyomi.reset_button_title()
mp.set_property("user-data/aniyomi/reset_button_title", "unused")
end
function aniyomi.previous_episode()
mp.set_property("user-data/aniyomi/switch_episode", "p")
end
function aniyomi.next_episode()
mp.set_property("user-data/aniyomi/switch_episode", "n")
end
function aniyomi.int_picker(title, name_format, start, stop, step, property)
mp.set_property("user-data/aniyomi/launch_int_picker", title .. "|" .. name_format .. "|" .. start .. "|" .. stop .. "|" .. step .. "|" .. property)
end
function aniyomi.pause()
mp.set_property("user-data/aniyomi/pause", "pause")
end
function aniyomi.unpause()
mp.set_property("user-data/aniyomi/pause", "unpause")
end
function aniyomi.pauseunpause()
mp.set_property("user-data/aniyomi/pause", "pauseunpause")
end
function aniyomi.seek_to_with_text(value, text)
mp.set_property("user-data/aniyomi/seek_with_text", value .. "|" .. text)
end
function aniyomi.hide_button()
mp.set_property("user-data/aniyomi/toggle_button", "h")
end
function aniyomi.show_button()
mp.set_property("user-data/aniyomi/toggle_button", "s")
end
function aniyomi.left_seek_by(value)
mp.set_property("user-data/aniyomi/seek_by", "l|" .. value)
end
function aniyomi.right_seek_by(value)
mp.set_property("user-data/aniyomi/seek_by", "r|" .. value)
end
return aniyomi
16 changes: 16 additions & 0 deletions app/src/main/java/eu/kanade/domain/DomainModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import mihon.domain.upcoming.anime.interactor.GetUpcomingAnime
import mihon.domain.upcoming.manga.interactor.GetUpcomingManga
import tachiyomi.data.category.anime.AnimeCategoryRepositoryImpl
import tachiyomi.data.category.manga.MangaCategoryRepositoryImpl
import tachiyomi.data.custombutton.CustomButtonRepositoryImpl
import tachiyomi.data.entries.anime.AnimeRepositoryImpl
import tachiyomi.data.entries.manga.MangaRepositoryImpl
import tachiyomi.data.history.anime.AnimeHistoryRepositoryImpl
Expand Down Expand Up @@ -105,6 +106,13 @@ import tachiyomi.domain.category.manga.interactor.SetMangaDisplayMode
import tachiyomi.domain.category.manga.interactor.SetSortModeForMangaCategory
import tachiyomi.domain.category.manga.interactor.UpdateMangaCategory
import tachiyomi.domain.category.manga.repository.MangaCategoryRepository
import tachiyomi.domain.custombuttons.interactor.CreateCustomButton
import tachiyomi.domain.custombuttons.interactor.DeleteCustomButton
import tachiyomi.domain.custombuttons.interactor.GetCustomButtons
import tachiyomi.domain.custombuttons.interactor.ReorderCustomButton
import tachiyomi.domain.custombuttons.interactor.ToggleFavoriteCustomButton
import tachiyomi.domain.custombuttons.interactor.UpdateCustomButton
import tachiyomi.domain.custombuttons.repository.CustomButtonRepository
import tachiyomi.domain.entries.anime.interactor.AnimeFetchInterval
import tachiyomi.domain.entries.anime.interactor.GetAnime
import tachiyomi.domain.entries.anime.interactor.GetAnimeByUrlAndSourceId
Expand Down Expand Up @@ -369,5 +377,13 @@ class DomainModule : InjektModule {
addFactory { DeleteMangaExtensionRepo(get()) }
addFactory { ReplaceMangaExtensionRepo(get()) }
addFactory { UpdateMangaExtensionRepo(get(), get()) }

addSingletonFactory<CustomButtonRepository> { CustomButtonRepositoryImpl(get()) }
addFactory { CreateCustomButton(get()) }
addFactory { DeleteCustomButton(get()) }
addFactory { GetCustomButtons(get()) }
addFactory { UpdateCustomButton(get()) }
addFactory { ReorderCustomButton(get()) }
addFactory { ToggleFavoriteCustomButton(get()) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ object PlayerSettingsGesturesScreen : SearchableSettings {
}

@Composable
private fun SkipIntroLengthDialog(
fun SkipIntroLengthDialog(
initialSkipIntroLength: Int,
onDismissRequest: () -> Unit,
onValueChanged: (skipIntroLength: Int) -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.material.icons.outlined.Memory
import androidx.compose.material.icons.outlined.PlayCircleOutline
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material.icons.outlined.Subtitles
import androidx.compose.material.icons.outlined.Terminal
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TopAppBarDefaults
Expand All @@ -37,6 +38,7 @@ import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.more.settings.screen.SettingsSearchScreen
import eu.kanade.presentation.more.settings.screen.player.custombutton.PlayerSettingsCustomButtonScreen
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen
Expand Down Expand Up @@ -199,6 +201,12 @@ object PlayerSettingsMainScreen : Screen() {
icon = Icons.Outlined.Audiotrack,
screen = PlayerSettingsAudioScreen,
),
Item(
titleRes = MR.strings.pref_player_custom_button,
subtitleRes = MR.strings.pref_player_custom_button_summary,
icon = Icons.Outlined.Terminal,
screen = PlayerSettingsCustomButtonScreen,
),
Item(
titleRes = MR.strings.pref_player_advanced,
subtitleRes = MR.strings.pref_player_advanced_summary,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package eu.kanade.presentation.more.settings.screen.player.custombutton

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.util.fastMap
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.more.settings.screen.player.custombutton.components.CustomButtonCreateDialog
import eu.kanade.presentation.more.settings.screen.player.custombutton.components.CustomButtonDeleteDialog
import eu.kanade.presentation.more.settings.screen.player.custombutton.components.CustomButtonEditDialog
import eu.kanade.presentation.more.settings.screen.player.custombutton.components.CustomButtonScreen
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.collectLatest
import tachiyomi.domain.custombuttons.model.CustomButtonUpdate
import tachiyomi.presentation.core.screens.LoadingScreen

object PlayerSettingsCustomButtonScreen : Screen() {

@Composable
override fun Content() {
val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow
val uriHandler = LocalUriHandler.current
val screenModel = rememberScreenModel { PlayerSettingsCustomButtonScreenModel() }

val state by screenModel.state.collectAsState()

if (state is CustomButtonScreenState.Loading) {
LoadingScreen()
return
}

val successState = state as CustomButtonScreenState.Success

CustomButtonScreen(
state = successState,
onClickFAQ = { uriHandler.openUri("https://aniyomi.org/docs/guides/player-settings/custom-buttons") },
onClickCreate = { screenModel.showDialog(CustomButtonDialog.Create) },
onClickPrimary = { screenModel.togglePrimaryButton(it) },
onClickEdit = { screenModel.showDialog(CustomButtonDialog.Edit(it)) },
onClickDelete = { screenModel.showDialog(CustomButtonDialog.Delete(it)) },
onClickMoveUp = screenModel::moveUp,
onClickMoveDown = screenModel::moveDown,
navigateUp = navigator::pop,
)

when (val dialog = successState.dialog) {
null -> {}
CustomButtonDialog.Create -> {
CustomButtonCreateDialog(
onDismissRequest = screenModel::dismissDialog,
onCreate = screenModel::createCustomButton,
buttonNames = successState.customButtons.fastMap { it.name }.toImmutableList(),
)
}
is CustomButtonDialog.Delete -> {
CustomButtonDeleteDialog(
onDismissRequest = screenModel::dismissDialog,
onDelete = { screenModel.deleteCustomButton(dialog.customButton) },
buttonTitle = dialog.customButton.name,
)
}
is CustomButtonDialog.Edit -> {
CustomButtonEditDialog(
onDismissRequest = screenModel::dismissDialog,
onEdit = { title, content, longPressContent, onStartup ->
screenModel.editCustomButton(
CustomButtonUpdate(
id = dialog.customButton.id,
name = title,
sortIndex = dialog.customButton.sortIndex,
content = content,
longPressContent = longPressContent,
onStartup = onStartup,
),
)
},
buttonNames = (successState.customButtons - dialog.customButton).fastMap {
it.name
}.toImmutableList(),
initialState = dialog.customButton,
)
}
}

LaunchedEffect(Unit) {
screenModel.events.collectLatest { event ->
if (event is CustomButtonEvent.LocalizedMessage) {
context.toast(event.stringRes)
}
}
}
}
}
Loading

0 comments on commit d65dd4e

Please sign in to comment.