Finished moving view strings to strings.xml

This commit is contained in:
Koen 2023-10-25 19:54:48 +02:00
parent 206c3884e9
commit f65eb0cd53
27 changed files with 155 additions and 108 deletions

View file

@ -586,7 +586,7 @@ class Settings : FragmentedStorageFileJson() {
val activity = SettingsActivity.getActivity()!!
if(!StateBackup.hasAutomaticBackup())
UIDialogs.toast(activity, "You don't have any automatic backups", false);
UIDialogs.toast(activity, activity.getString(R.string.you_don_t_have_any_automatic_backups), false);
else
UIDialogs.showAutomaticRestoreDialog(activity, activity.lifecycleScope);
}

View file

@ -100,12 +100,12 @@ class UIDialogs {
dialog.show();
};
if(StateBackup.hasAutomaticBackup() && !skipRestoreCheck)
UIDialogs.showDialog(context, R.drawable.ic_move_up, "An old backup is available", "Would you like to restore this backup?", null, 0,
UIDialogs.Action("Cancel", {}), //To nothing
UIDialogs.Action("Override", {
UIDialogs.showDialog(context, R.drawable.ic_move_up, context.getString(R.string.an_old_backup_is_available), context.getString(R.string.would_you_like_to_restore_this_backup), null, 0,
UIDialogs.Action(context.getString(R.string.cancel), {}), //To nothing
UIDialogs.Action(context.getString(R.string.override), {
dialogAction();
}, UIDialogs.ActionStyle.DANGEROUS),
UIDialogs.Action("Restore", {
UIDialogs.Action(context.getString(R.string.restore), {
UIDialogs.showAutomaticRestoreDialog(context, StateApp.instance.scope);
}, UIDialogs.ActionStyle.PRIMARY));
else {
@ -211,10 +211,10 @@ class UIDialogs {
(if(ex != null ) "${ex.message}" else ""),
if(ex is PluginException) ex.code else null,
0,
UIDialogs.Action("Retry", {
UIDialogs.Action(context.getString(R.string.retry), {
retryAction?.invoke();
}, UIDialogs.ActionStyle.PRIMARY),
UIDialogs.Action("Close", {
UIDialogs.Action(context.getString(R.string.close), {
closeAction?.invoke()
}, UIDialogs.ActionStyle.NONE)
);
@ -226,15 +226,15 @@ class UIDialogs {
}
fun showDataRetryDialog(context: Context, reason: String? = null, retryAction: (() -> Unit)? = null, closeAction: (() -> Unit)? = null) {
val retryButtonAction = Action("Retry", retryAction ?: {}, ActionStyle.PRIMARY)
val closeButtonAction = Action("Close", closeAction ?: {}, ActionStyle.ACCENT)
showDialog(context, R.drawable.ic_no_internet_86dp, "Data Retry", reason, null, 0, closeButtonAction, retryButtonAction)
val retryButtonAction = Action(context.getString(R.string.retry), retryAction ?: {}, ActionStyle.PRIMARY)
val closeButtonAction = Action(context.getString(R.string.close), closeAction ?: {}, ActionStyle.ACCENT)
showDialog(context, R.drawable.ic_no_internet_86dp, context.getString(R.string.data_retry), reason, null, 0, closeButtonAction, retryButtonAction)
}
fun showConfirmationDialog(context: Context, text: String, action: () -> Unit, cancelAction: (() -> Unit)? = null) {
val confirmButtonAction = Action("Confirm", action, ActionStyle.PRIMARY)
val cancelButtonAction = Action("Cancel", cancelAction ?: {}, ActionStyle.ACCENT)
val confirmButtonAction = Action(context.getString(R.string.confirm), action, ActionStyle.PRIMARY)
val cancelButtonAction = Action(context.getString(R.string.cancel), cancelAction ?: {}, ActionStyle.ACCENT)
showDialog(context, R.drawable.ic_error, text, null, null, 0, cancelButtonAction, confirmButtonAction)
}

View file

@ -64,22 +64,22 @@ class UISlideOverlays {
val subtitleSources = video.subtitles;
if(videoSources.size == 0 && (audioSources?.size ?: 0) == 0) {
UIDialogs.toast("No downloads available", false);
UIDialogs.toast(container.context.getString(R.string.no_downloads_available), false);
return null;
}
if(!VideoHelper.isDownloadable(video)) {
Logger.i(TAG, "Attempted to open downloads without valid sources for [${video.name}]: ${video.url}");
UIDialogs.toast( "No downloadable sources (yet)");
UIDialogs.toast( container.context.getString(R.string.no_downloadable_sources_yet));
return null;
}
items.add(SlideUpMenuGroup(container.context, "Video", videoSources,
listOf(listOf(SlideUpMenuItem(container.context, R.drawable.ic_movie, "None", "Audio Only", "none", {
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.video), videoSources,
listOf(listOf(SlideUpMenuItem(container.context, R.drawable.ic_movie, container.context.getString(R.string.none), container.context.getString(R.string.audio_only), "none", {
selectedVideo = null;
menu?.selectOption(videoSources, "none");
if(selectedAudio != null || !requiresAudio)
menu?.setOk("Download");
menu?.setOk(container.context.getString(R.string.download));
}, false)) +
videoSources
.filter { it.isDownloadable() }
@ -88,7 +88,7 @@ class UISlideOverlays {
selectedVideo = it as IVideoUrlSource;
menu?.selectOption(videoSources, it);
if(selectedAudio != null || !requiresAudio)
menu?.setOk("Download");
menu?.setOk(container.context.getString(R.string.download));
}, false)
}).flatten().toList()
));
@ -100,13 +100,13 @@ class UISlideOverlays {
audioSources?.let { audioSources ->
items.add(SlideUpMenuGroup(container.context, "Audio", audioSources, audioSources
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.audio), audioSources, audioSources
.filter { VideoHelper.isDownloadable(it) }
.map {
SlideUpMenuItem(container.context, R.drawable.ic_music, it.name, "${it.bitrate}", it, {
selectedAudio = it as IAudioUrlSource;
menu?.selectOption(audioSources, it);
menu?.setOk("Download");
menu?.setOk(container.context.getString(R.string.download));
}, false);
}));
val asources = audioSources;
@ -125,7 +125,7 @@ class UISlideOverlays {
//ContentResolver is required for subtitles..
if(contentResolver != null) {
items.add(SlideUpMenuGroup(container.context, "Subtitles", subtitleSources, subtitleSources
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.subtitles), subtitleSources, subtitleSources
.map {
SlideUpMenuItem(container.context, R.drawable.ic_edit, it.name, "", it, {
if (selectedSubtitle == it) {
@ -139,7 +139,7 @@ class UISlideOverlays {
}));
}
menu = SlideUpMenuOverlay(container.context, container, "Download Video", null, true, items);
menu = SlideUpMenuOverlay(container.context, container, container.context.getString(R.string.download_video), null, true, items);
if(selectedVideo != null) {
menu.selectOption(videoSources, selectedVideo);
@ -148,7 +148,7 @@ class UISlideOverlays {
audioSources?.let { audioSources -> menu.selectOption(audioSources, selectedAudio); };
}
if(selectedAudio != null || (!requiresAudio && selectedVideo != null)) {
menu.setOk("Download");
menu.setOk(container.context.getString(R.string.download));
}
menu.onOK.subscribe {
@ -185,7 +185,7 @@ class UISlideOverlays {
}
fun showDownloadVideoOverlay(video: IPlatformVideo, container: ViewGroup, useDetails: Boolean = false) {
val handleUnknownDownload: ()->Unit = {
showUnknownVideoDownload("Video", container) { px, bitrate ->
showUnknownVideoDownload(container.context.getString(R.string.video), container) { px, bitrate ->
StateDownloads.instance.download(video, px, bitrate)
};
};
@ -195,7 +195,7 @@ class UISlideOverlays {
val scope = StateApp.instance.scopeOrNull;
if(scope != null) {
val loader = showLoaderOverlay("Fetching video details", container);
val loader = showLoaderOverlay(container.context.getString(R.string.fetching_video_details), container);
scope.launch(Dispatchers.IO) {
try {
val videoDetails = StatePlatform.instance.getContentDetails(video.url, false).await();
@ -209,7 +209,7 @@ class UISlideOverlays {
}
catch(ex: Throwable) {
withContext(Dispatchers.Main) {
UIDialogs.toast("Failed to fetch details for download");
UIDialogs.toast(container.context.getString(R.string.failed_to_fetch_details_for_download));
handleUnknownDownload();
loader.hide(true);
}
@ -220,7 +220,7 @@ class UISlideOverlays {
}
}
fun showDownloadPlaylistOverlay(playlist: Playlist, container: ViewGroup) {
showUnknownVideoDownload("Video", container) { px, bitrate ->
showUnknownVideoDownload(container.context.getString(R.string.video), container) { px, bitrate ->
StateDownloads.instance.download(playlist, px, bitrate);
};
}
@ -232,7 +232,7 @@ class UISlideOverlays {
var targetBitrate: Long = 0;
val resolutions = listOf(
Triple<String, String, Long>("None", "None", -1),
Triple<String, String, Long>(container.context.getString(R.string.none), container.context.getString(R.string.none), -1),
Triple<String, String, Long>("480P", "720x480", 720*480),
Triple<String, String, Long>("720P", "1280x720", 1280*720),
Triple<String, String, Long>("1080P", "1920x1080", 1920*1080),
@ -240,23 +240,23 @@ class UISlideOverlays {
Triple<String, String, Long>("2160P", "3840x2160", 3840*2160)
);
items.add(SlideUpMenuGroup(container.context, "Target Resolution", "Video", resolutions.map {
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.target_resolution), "Video", resolutions.map {
SlideUpMenuItem(container.context, R.drawable.ic_movie, it.first, it.second, it.third, {
targetPxSize = it.third;
menu?.selectOption("Video", it.third);
}, false)
}));
items.add(SlideUpMenuGroup(container.context, "Target Bitrate", "Bitrate", listOf(
SlideUpMenuItem(container.context, R.drawable.ic_movie, "Low Bitrate", "", 1, {
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.target_bitrate), "Bitrate", listOf(
SlideUpMenuItem(container.context, R.drawable.ic_movie, container.context.getString(R.string.low_bitrate), "", 1, {
targetBitrate = 1;
menu?.selectOption("Bitrate", 1);
menu?.setOk("Download");
menu?.setOk(container.context.getString(R.string.download));
}, false),
SlideUpMenuItem(container.context, R.drawable.ic_movie, "High Bitrate", "", 9999999, {
SlideUpMenuItem(container.context, R.drawable.ic_movie, container.context.getString(R.string.high_bitrate), "", 9999999, {
targetBitrate = 9999999;
menu?.selectOption("Bitrate", 9999999);
menu?.setOk("Download");
menu?.setOk(container.context.getString(R.string.download));
}, false)
)));
@ -277,12 +277,12 @@ class UISlideOverlays {
if(Settings.instance.downloads.isHighBitrateDefault()) {
targetBitrate = 9999999;
menu.selectOption("Bitrate", 9999999);
menu.setOk("Download");
menu.setOk(container.context.getString(R.string.download));
}
else {
targetBitrate = 1;
menu.selectOption("Bitrate", 1);
menu.setOk("Download");
menu.setOk(container.context.getString(R.string.download));
}
menu.onOK.subscribe {
@ -310,8 +310,8 @@ class UISlideOverlays {
if (lastUpdated != null) {
items.add(
SlideUpMenuGroup(container.context, "Recently Used Playlist", "recentlyusedplaylist",
SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, lastUpdated.name, "${lastUpdated.videos.size} videos", "",
SlideUpMenuGroup(container.context, container.context.getString(R.string.recently_used_playlist), "recentlyusedplaylist",
SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, lastUpdated.name, "${lastUpdated.videos.size} " + container.context.getString(R.string.videos), "",
{
StatePlaylists.instance.addToPlaylist(lastUpdated.id, video);
StateDownloads.instance.checkForOutdatedPlaylists();
@ -322,23 +322,23 @@ class UISlideOverlays {
val allPlaylists = StatePlaylists.instance.getPlaylists();
val queue = StatePlayer.instance.getQueue();
val watchLater = StatePlaylists.instance.getWatchLater();
items.add(SlideUpMenuGroup(container.context, "Actions", "actions",
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.actions), "actions",
(listOf(
SlideUpMenuItem(container.context, R.drawable.ic_download, "Download", "Download the video", "download",
SlideUpMenuItem(container.context, R.drawable.ic_download, container.context.getString(R.string.download), container.context.getString(R.string.download_the_video), container.context.getString(R.string.download),
{ showDownloadVideoOverlay(video, container, true); }, false))
+ actions)
));
items.add(
SlideUpMenuGroup(container.context, "Add To", "addto",
SlideUpMenuItem(container.context, R.drawable.ic_queue_add, "Add to Queue", "${queue.size} videos", "queue",
SlideUpMenuGroup(container.context, container.context.getString(R.string.add_to), "addto",
SlideUpMenuItem(container.context, R.drawable.ic_queue_add, container.context.getString(R.string.add_to_queue), "${queue.size} " + container.context.getString(R.string.videos), "queue",
{ StatePlayer.instance.addToQueue(video); }),
SlideUpMenuItem(container.context, R.drawable.ic_watchlist_add, "Add to " + StatePlayer.TYPE_WATCHLATER + "", "${watchLater.size} videos", "watch later",
SlideUpMenuItem(container.context, R.drawable.ic_watchlist_add, "${container.context.getString(R.string.add_to)} " + StatePlayer.TYPE_WATCHLATER + "", "${watchLater.size} " + container.context.getString(R.string.videos), "watch later",
{ StatePlaylists.instance.addToWatchLater(SerializedPlatformVideo.fromVideo(video)); })
));
val playlistItems = arrayListOf<SlideUpMenuItem>();
for (playlist in allPlaylists) {
playlistItems.add(SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, "Add to " + playlist.name + "", "${playlist.videos.size} videos", "",
playlistItems.add(SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, "${container.context.getString(R.string.add_to)} " + playlist.name + "", "${playlist.videos.size} " + container.context.getString(R.string.videos), "",
{
StatePlaylists.instance.addToPlaylist(playlist.id, video);
StateDownloads.instance.checkForOutdatedPlaylists();
@ -346,9 +346,9 @@ class UISlideOverlays {
}
if(playlistItems.size > 0)
items.add(SlideUpMenuGroup(container.context, "Playlists", "", playlistItems));
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.playlists), "", playlistItems));
return SlideUpMenuOverlay(container.context, container, "Video Options", null, true, items).apply { show() };
return SlideUpMenuOverlay(container.context, container, container.context.getString(R.string.video_options), null, true, items).apply { show() };
}
@ -360,8 +360,8 @@ class UISlideOverlays {
if (lastUpdated != null) {
items.add(
SlideUpMenuGroup(container.context, "Recently Used Playlist", "recentlyusedplaylist",
SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, lastUpdated.name, "${lastUpdated.videos.size} videos", "",
SlideUpMenuGroup(container.context, container.context.getString(R.string.recently_used_playlist), "recentlyusedplaylist",
SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, lastUpdated.name, "${lastUpdated.videos.size} " + container.context.getString(R.string.videos), "",
{
StatePlaylists.instance.addToPlaylist(lastUpdated.id, video);
StateDownloads.instance.checkForOutdatedPlaylists();
@ -373,18 +373,18 @@ class UISlideOverlays {
val queue = StatePlayer.instance.getQueue();
val watchLater = StatePlaylists.instance.getWatchLater();
items.add(
SlideUpMenuGroup(container.context, "Other", "other",
SlideUpMenuItem(container.context, R.drawable.ic_queue_add, "Queue", "${queue.size} videos", "queue",
SlideUpMenuGroup(container.context, container.context.getString(R.string.other), "other",
SlideUpMenuItem(container.context, R.drawable.ic_queue_add, container.context.getString(R.string.queue), "${queue.size} " + container.context.getString(R.string.videos), "queue",
{ StatePlayer.instance.addToQueue(video); }),
SlideUpMenuItem(container.context, R.drawable.ic_watchlist_add, StatePlayer.TYPE_WATCHLATER, "${watchLater.size} videos", "watch later",
SlideUpMenuItem(container.context, R.drawable.ic_watchlist_add, StatePlayer.TYPE_WATCHLATER, "${watchLater.size} " + container.context.getString(R.string.videos), "watch later",
{ StatePlaylists.instance.addToWatchLater(SerializedPlatformVideo.fromVideo(video)); }),
SlideUpMenuItem(container.context, R.drawable.ic_download, "Download", "Download the video", "download",
SlideUpMenuItem(container.context, R.drawable.ic_download, container.context.getString(R.string.download), container.context.getString(R.string.download_the_video), container.context.getString(R.string.download),
{ showDownloadVideoOverlay(video, container, true); }, false))
);
val playlistItems = arrayListOf<SlideUpMenuItem>();
for (playlist in allPlaylists) {
playlistItems.add(SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, playlist.name, "${playlist.videos.size} videos", "",
playlistItems.add(SlideUpMenuItem(container.context, R.drawable.ic_playlist_add, playlist.name, "${playlist.videos.size} " + container.context.getString(R.string.videos), "",
{
StatePlaylists.instance.addToPlaylist(playlist.id, video);
StateDownloads.instance.checkForOutdatedPlaylists();
@ -392,9 +392,9 @@ class UISlideOverlays {
}
if(playlistItems.size > 0)
items.add(SlideUpMenuGroup(container.context, "Playlists", "", playlistItems));
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.playlists), "", playlistItems));
return SlideUpMenuOverlay(container.context, container, "Add to", null, true, items).apply { show() };
return SlideUpMenuOverlay(container.context, container, container.context.getString(R.string.add_to), null, true, items).apply { show() };
}
fun showFiltersOverlay(lifecycleScope: CoroutineScope, container: ViewGroup, enabledClientsIds: List<String>, filterValues: HashMap<String, List<String>>): SlideUpMenuFilters {
@ -412,8 +412,8 @@ class UISlideOverlays {
.map { btn -> SlideUpMenuItem(container.context, btn.iconResource, btn.text.text.toString(), "", "", {
btn.handler?.invoke(btn);
}, true) as View }.toTypedArray() ?: arrayOf(),
arrayOf(SlideUpMenuItem(container.context, R.drawable.ic_pin, "Change Pins", "Decide which buttons should be pinned", "", {
showOrderOverlay(container, "Select your pins in order", (visible + hidden).map { Pair(it.text.text.toString(), it.tagRef!!) }) {
arrayOf(SlideUpMenuItem(container.context, R.drawable.ic_pin, container.context.getString(R.string.change_pins), container.context.getString(R.string.decide_which_buttons_should_be_pinned), "", {
showOrderOverlay(container, container.context.getString(R.string.select_your_pins_in_order), (visible + hidden).map { Pair(it.text.text.toString(), it.tagRef!!) }) {
val selected = it
.map { x -> visible.find { it.tagRef == x } ?: hidden.find { it.tagRef == x } }
.filter { it != null }
@ -425,7 +425,7 @@ class UISlideOverlays {
}, false))
).flatten().toTypedArray();
return SlideUpMenuOverlay(container.context, container, "More Options", null, true, *views).apply { show() };
return SlideUpMenuOverlay(container.context, container, container.context.getString(R.string.more_options), null, true, *views).apply { show() };
}
fun showOrderOverlay(container: ViewGroup, title: String, options: List<Pair<String, Any>>, onOrdered: (List<Any>)->Unit) {
@ -433,7 +433,7 @@ class UISlideOverlays {
var overlay: SlideUpMenuOverlay? = null;
overlay = SlideUpMenuOverlay(container.context, container, title, "Save", true,
overlay = SlideUpMenuOverlay(container.context, container, title, container.context.getString(R.string.save), true,
options.map { SlideUpMenuItem(container.context, R.drawable.ic_move_up, it.first, "", it.second, {
if(overlay!!.selectOption(null, it.second, true, true)) {
if(!selection.contains(it.second))

View file

@ -160,7 +160,7 @@ class CommentViewHolder : ViewHolder {
val replies = comment.replyCount ?: 0;
if (!readonly || replies > 0) {
_buttonReplies.visibility = View.VISIBLE;
_buttonReplies.text.text = "$replies replies";
_buttonReplies.text.text = "$replies " + itemView.context.getString(R.string.replies);
} else {
_buttonReplies.visibility = View.GONE;
}

View file

@ -38,7 +38,7 @@ class DisabledSourceView : LinearLayout {
client.icon?.setImageView(_imageSource);
_textSource.text = client.name;
_textSourceSubtitle.text = "Tap to open";
_textSourceSubtitle.text = context.getString(R.string.tap_to_open);
_buttonAdd.setOnClickListener { onAdd.emit(source) }
_root.setOnClickListener { onClick.emit(); };

View file

@ -38,7 +38,7 @@ class DisabledSourceViewHolder : ViewHolder {
client.icon?.setImageView(_imageSource);
_textSource.text = client.name;
_textSourceSubtitle.text = "Tap to open";
_textSourceSubtitle.text = itemView.context.getString(R.string.tap_to_open);
source = client;
}
}

View file

@ -57,7 +57,7 @@ class EnabledSourceViewHolder : ViewHolder {
client.icon?.setImageView(_imageSource);
_textSource.text = client.name;
_textSourceSubtitle.text = "Tap to open";
_textSourceSubtitle.text = itemView.context.getString(R.string.tap_to_open);
source = client
}
}

View file

@ -89,7 +89,7 @@ class HistoryListViewHolder : ViewHolder {
var metadata = "";
if (v.video.viewCount > 0)
metadata += "${v.video.viewCount.toHumanNumber()} views";
metadata += "${v.video.viewCount.toHumanNumber()} " + itemView.context.getString(R.string.views);
_textMetadata.text = metadata;

View file

@ -181,15 +181,15 @@ open class PreviewVideoView : LinearLayout {
var metadata = ""
if (content is IPlatformVideo && content.viewCount > 0) {
if(content.isLive)
metadata += "${content.viewCount.toHumanNumber()} watching • ";
metadata += "${content.viewCount.toHumanNumber()} ${context.getString(R.string.watching)}";
else
metadata += "${content.viewCount.toHumanNumber()} views • ";
metadata += "${content.viewCount.toHumanNumber()} ${context.getString(R.string.views)}";
}
var timeMeta = "";
if(isPlanned) {
val ago = content.datetime?.toHumanNowDiffString(true) ?: ""
timeMeta = "available in " + ago;
timeMeta = context.getString(R.string.available_in) + " ${ago}";
}
else {
val ago = content.datetime?.toHumanNowDiffString() ?: ""
@ -210,13 +210,13 @@ open class PreviewVideoView : LinearLayout {
if(!isPlanned)
_textVideoDuration.text = video.duration.toHumanTime(false);
else
_textVideoDuration.text = "Planned";
_textVideoDuration.text = context.getString(R.string.planned);
_playerVideoThumbnail?.setLive(video.isLive);
if(!isPlanned && video.isLive) {
_containerDuration.visibility = GONE;
_containerLive.visibility = VISIBLE;
timeMeta = "LIVE"
timeMeta = context.getString(R.string.live_capitalized)
}
else {
_containerLive.visibility = GONE;

View file

@ -103,7 +103,7 @@ class VideoListEditorViewHolder : ViewHolder {
var metadata = "";
if (v.viewCount > 0)
metadata += "${v.viewCount.toHumanNumber()} views • ";
metadata += "${v.viewCount.toHumanNumber()} ${itemView.context.getString(R.string.views)}";
metadata += v.datetime?.toHumanNowDiffString() ?: "";
_platformIndicator.setPlatformFromClientID(v.id.pluginId);

View file

@ -77,7 +77,7 @@ class CreatorViewHolder(private val _viewGroup: ViewGroup, private val _tiny: Bo
if(authorLink.subscribers == null || (authorLink.subscribers ?: 0) <= 0L)
_textMetadata.visibility = View.GONE;
else {
_textMetadata.text = if((authorLink.subscribers ?: 0) > 0) authorLink.subscribers!!.toHumanNumber() + " subscribers" else "";
_textMetadata.text = if((authorLink.subscribers ?: 0) > 0) authorLink.subscribers!!.toHumanNumber() + " " + _view.context.getString(R.string.subscribers) else "";
_textMetadata.visibility = View.VISIBLE;
}
_buttonSubscribe.setSubscribeChannel(authorLink.url);

View file

@ -45,7 +45,7 @@ class ImportPlaylistsViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter.
override fun bind(playlist: SelectablePlaylist) {
_textName.text = playlist.playlist.name;
_textMetadata.text = "${playlist.playlist.videos.size} videos";
_textMetadata.text = "${playlist.playlist.videos.size} " + _view.context.getString(R.string.videos);
_checkbox.value = playlist.selected;
val thumbnail = playlist.playlist.videos.firstOrNull()?.thumbnails?.getHQThumbnail();

View file

@ -37,7 +37,7 @@ class VideoDownloadViewHolder(_viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<
};
_videoDelete.setOnClickListener {
val id = _video?.id ?: return@setOnClickListener;
UIDialogs.showConfirmationDialog(_view.context, "Are you sure you want to delete this video?", {
UIDialogs.showConfirmationDialog(_view.context, _view.context.getString(R.string.are_you_sure_you_want_to_delete_this_video), {
StateDownloads.instance.deleteCachedVideo(id);
});
}

View file

@ -129,10 +129,10 @@ class AnnouncementView : LinearLayout {
_textClose.text = announcement.cancelName;
}
else
_textClose.text = "Dismiss";
_textClose.text = context.getString(R.string.dismiss);
}
else
_textClose.text = "Dismiss";
_textClose.text = context.getString(R.string.dismiss);
when (announcement.announceType) {
AnnouncementType.DELETABLE -> {

View file

@ -408,10 +408,10 @@ class GestureControlView : LinearLayout {
val seekOffset: Long = 10000;
if (_rewinding) {
_textRewind.text = "${_fastForwardCounter * 10} seconds";
_textRewind.text = "${_fastForwardCounter * 10} " + context.getString(R.string.seconds);
onSeek.emit(-seekOffset);
} else {
_textFastForward.text = "${_fastForwardCounter * 10} seconds";
_textFastForward.text = "${_fastForwardCounter * 10} " + context.getString(R.string.seconds);
onSeek.emit(seekOffset);
}
}

View file

@ -31,12 +31,12 @@ class AddCommentView : LinearLayout {
val now = System.currentTimeMillis()
if (now - _lastClickTime > 3000) {
StatePolycentric.instance.requireLogin(context, "Please login to post a comment") {
StatePolycentric.instance.requireLogin(context, context.getString(R.string.please_login_to_post_a_comment)) {
try {
UIDialogs.showCommentDialog(context, cu, ref) { onCommentAdded.emit(it) };
} catch (e: Throwable) {
Logger.w(TAG, "Failed to post comment", e);
UIDialogs.toast(context, "Failed to post comment: " + e.message);
UIDialogs.toast(context, context.getString(R.string.failed_to_post_comment) + " ${e.message}");
}
};

View file

@ -110,9 +110,9 @@ class ActiveDownloadItem: LinearLayout {
_videoSpeed.text = "${_download.downloadSpeed.toHumanBytesSpeed()} ${(_download.progress * 100).toInt()}%";
_videoState.text = if(!Settings.instance.downloads.shouldDownload())
"Waiting for unmetered" + (if(!_download.error.isNullOrEmpty()) "\n(Last error: " + _download.error + ")" else "");
context.getString(R.string.waiting_for_unmetered) + (if(!_download.error.isNullOrEmpty()) "\n(" + context.getString(R.string.last_error) + ": " + _download.error + ")" else "");
else if(_download.state == VideoDownload.State.QUEUED && !_download.error.isNullOrEmpty())
_download.state.toString() + "\n(Last error: " + _download.error + ")";
_download.state.toString() + "\n(" + context.getString(R.string.last_error) + ": " + _download.error + ")";
else
_download.state.toString();
_videoState.setTextColor(Color.GRAY);
@ -123,7 +123,7 @@ class ActiveDownloadItem: LinearLayout {
};
VideoDownload.State.ERROR -> {
_videoState.setTextColor(Color.RED);
_videoState.text = _download.error ?: "Error";
_videoState.text = _download.error ?: context.getString(R.string.error);
_videoBar.visibility = GONE;
_videoSpeed.visibility = GONE;
}

View file

@ -204,9 +204,9 @@ class LiveChatOverlay : LinearLayout {
_window = window;
if(viewerCount != null)
_textViewers.text = viewerCount.toHumanNumber() + " viewers";
_textViewers.text = viewerCount.toHumanNumber() + " " + context.getString(R.string.viewers);
else if(manager != null)
_textViewers.text = manager.viewCount.toHumanNumber() + " viewers";
_textViewers.text = manager.viewCount.toHumanNumber() + " " + context.getString(R.string.viewers);
else
_textViewers.text = "";
@ -239,7 +239,7 @@ class LiveChatOverlay : LinearLayout {
}
else if(event is LiveEventViewCount)
scope.launch(Dispatchers.Main) {
_textViewers.text = "${event.viewCount.toLong().toHumanNumber()} viewers";
_textViewers.text = "${event.viewCount.toLong().toHumanNumber()} " + context.getString(R.string.viewers);
}
else
handleLiveEvent(event);

View file

@ -25,13 +25,13 @@ class QueueEditorOverlay : LinearLayout {
_editor.onVideoRemoved.subscribe { v -> StatePlayer.instance.removeFromQueue(v) }
_editor.onVideoClicked.subscribe { v -> StatePlayer.instance.setQueuePosition(v) }
_topbar.setInfo("Queue", "");
_topbar.setInfo(context.getString(R.string.queue), "");
}
fun updateQueue() {
val queue = StatePlayer.instance.getQueue();
_editor.setVideos(queue, true);
_topbar.setInfo("Queue", "${queue.size} videos");
_topbar.setInfo(context.getString(R.string.queue), "${queue.size} " + context.getString(R.string.videos));
}
fun cleanup() {

View file

@ -38,7 +38,7 @@ class RepliesOverlay : LinearLayout {
_commentsList.onCommentsLoaded.subscribe { count ->
if (_readonly && count == 0) {
UIDialogs.toast(context, "Expected at least one reply but no replies were returned by the server");
UIDialogs.toast(context, context.getString(R.string.expected_at_least_one_reply_but_no_replies_were_returned_by_the_server));
}
}
@ -46,7 +46,7 @@ class RepliesOverlay : LinearLayout {
val replyCount = c.replyCount;
var metadata = "";
if (replyCount != null && replyCount > 0) {
metadata += "$replyCount replies";
metadata += "$replyCount " + context.getString(R.string.replies);
}
if (c is PolycentricPlatformComment) {
@ -57,7 +57,7 @@ class RepliesOverlay : LinearLayout {
};
_topbar.onClose.subscribe(this, onClose::emit);
_topbar.setInfo("Replies", "");
_topbar.setInfo(context.getString(R.string.Replies), "");
}
fun load(readonly: Boolean, metadata: String, contextUrl: String?, ref: Protocol.Reference?, loader: suspend () -> IPager<IPlatformComment>, onCommentAdded: ((comment: IPlatformComment) -> Unit)? = null) {
@ -69,7 +69,7 @@ class RepliesOverlay : LinearLayout {
_addCommentView.setContext(contextUrl, ref);
}
_topbar.setInfo("Replies", metadata);
_topbar.setInfo(context.getString(R.string.Replies), metadata);
_commentsList.load(readonly, loader);
_onCommentAdded = onCommentAdded;
}

View file

@ -3,6 +3,7 @@ package com.futo.platformplayer.views.overlays.slideup
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.futo.platformplayer.R
import com.futo.platformplayer.UISlideOverlays
import com.futo.platformplayer.api.media.IPlatformClient
import com.futo.platformplayer.api.media.models.FilterGroup
@ -34,7 +35,7 @@ class SlideUpMenuFilters {
_container = container;
_enabledClientsIds = enabledClientsIds;
_filterValues = filterValues;
_slideUpMenuOverlay = SlideUpMenuOverlay(_container.context, _container, "Filters", "Done", true, listOf());
_slideUpMenuOverlay = SlideUpMenuOverlay(_container.context, _container, container.context.getString(R.string.filters), container.context.getString(R.string.done), true, listOf());
_slideUpMenuOverlay.onOK.subscribe {
onOK.emit(_enabledClientsIds, _changed);
_slideUpMenuOverlay.hide();
@ -84,7 +85,7 @@ class SlideUpMenuFilters {
val caps = commonCapabilities;
val items = arrayListOf<View>();
val group = SlideUpMenuRadioGroup(_container.context, "Sources", StatePlatform.instance.getSortedEnabledClient().map { Pair(it.name, it.id) },
val group = SlideUpMenuRadioGroup(_container.context, _container.context.getString(R.string.sources), StatePlatform.instance.getSortedEnabledClient().map { Pair(it.name, it.id) },
_enabledClientsIds, true, true);
group.onSelectedChange.subscribe {

View file

@ -48,10 +48,10 @@ class PillRatingLikesDislikes : LinearLayout {
_iconDislikes = findViewById(R.id.pill_dislike_icon);
_iconLikes = findViewById(R.id.pill_like_icon);
_iconLikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, "Please login to like") { like(it) }; };
_textLikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, "Please login to like") { like(it) }; };
_iconDislikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, "Please login to dislike") { dislike(it) }; };
_textDislikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, "Please login to dislike") { dislike(it) }; };
_iconLikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, context.getString(R.string.please_login_to_like)) { like(it) }; };
_textLikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, context.getString(R.string.please_login_to_like)) { like(it) }; };
_iconDislikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, context.getString(R.string.please_login_to_dislike)) { dislike(it) }; };
_textDislikes.setOnClickListener { StatePolycentric.instance.requireLogin(context, context.getString(R.string.please_login_to_dislike)) { dislike(it) }; };
}
fun setRating(rating: IRating, hasLiked: Boolean = false, hasDisliked: Boolean = false) {

View file

@ -34,7 +34,7 @@ class CommentsList : ConstraintLayout {
}
.exception<Throwable> {
Logger.e(TAG, "Failed to load comments.", it);
UIDialogs.showGeneralRetryErrorDialog(context, "Failed to load comments. " + (it.message ?: ""), it, ::fetchComments);
UIDialogs.showGeneralRetryErrorDialog(context, context.getString(R.string.failed_to_load_comments) + (it.message ?: ""), it, ::fetchComments);
setLoading(false);
} else TaskHandler(IPlatformVideoDetails::class.java, StateApp.instance.scopeGetter);

View file

@ -82,17 +82,17 @@ class SourceHeaderView : LinearLayout {
if (!config.scriptPublicKey.isNullOrEmpty() && !config.scriptSignature.isNullOrEmpty()) {
if (script == null) {
_sourceSignature.setTextColor(Color.rgb(0xAC, 0xAC, 0xAC));
_sourceSignature.text = "Script is not available";
_sourceSignature.text = context.getString(R.string.script_is_not_available);
} else if (config.validate(script)) {
_sourceSignature.setTextColor(Color.rgb(0, 255, 0));
_sourceSignature.text = "Signature is valid";
_sourceSignature.text = context.getString(R.string.signature_is_valid);
} else {
_sourceSignature.setTextColor(Color.rgb(255, 0, 0));
_sourceSignature.text = "Signature is invalid";
_sourceSignature.text = context.getString(R.string.signature_is_invalid);
}
} else {
_sourceSignature.setTextColor(Color.rgb(255, 0, 0));
_sourceSignature.text = "No signature available";
_sourceSignature.text = context.getString(R.string.no_signature_available);
}
}

View file

@ -70,14 +70,14 @@ class SubscribeButton : LinearLayout {
private fun handleSubscribe(channel: IPlatformChannel) {
setIsLoading(false);
StateSubscriptions.instance.addSubscription(channel);
UIDialogs.toast(context, "Subscribed to ${channel.name}");
UIDialogs.toast(context, context.getString(R.string.subscribed_to) + channel.name);
setIsSubscribed(true);
}
private fun handleUnSubscribe(url: String) {
setIsLoading(false);
val removed = StateSubscriptions.instance.removeSubscription(url);
if (removed != null)
UIDialogs.toast(context, "Unsubscribed from ${removed!!.channel.name}");
UIDialogs.toast(context, context.getString(R.string.unsubscribed_from) + removed.channel.name);
setIsSubscribed(false);
}

View file

@ -149,7 +149,7 @@ class UpNextView : LinearLayout {
val metadataTokens = mutableListOf<String>();
if (nextItem.viewCount > 0) {
metadataTokens.add("${nextItem.viewCount.toHumanNumber()} views");
metadataTokens.add("${nextItem.viewCount.toHumanNumber()} " + context.getString(R.string.views));
}
if (nextItem.datetime != null) {

View file

@ -350,7 +350,6 @@
<string name="pay">Pay</string>
<string name="standard_payment_methods">Standard Payment Methods</string>
<string name="stripe_is_a_secure_online_payment_service_that_accepts_major_credit_cards_debit_cards_and_various_localized_payment_methods">Stripe is a secure online payment service that accepts major credit cards, debit cards, and various localized payment methods.</string>
<string name="live_capitalized">LIVE</string>
<string name="add_a_comment">Add a comment…</string>
<string name="dismiss">Dismiss</string>
<string name="scan_a_qr_code_to_install">Scan a QR code to install</string>
@ -527,13 +526,13 @@
<string name="scan_a_qr_code">Scan a QR Code</string>
<string name="not_implemented_yet">Not implemented yet..</string>
<string name="unknown_context">Unknown Context</string>
<string name="something_went_wrong_missing_stack_trace">Something went wrong... missing stack trace?</string>
<string name="something_went_wrong_missing_stack_trace">Something went wrong missing stack trace?</string>
<string name="logs_already_submitted">Logs already submitted.</string>
<string name="no_logs_found">No logs found.</string>
<string name="failed_automated_share_share_manually">Failed automated share, share manually?</string>
<string name="shared_id">Shared {id}</string>
<string name="unhandled_exception_in_vs">Unhandled exception in VS</string>
<string name="send_exception_to_developers">Send exception to developers...</string>
<string name="send_exception_to_developers">Send exception to developers</string>
<string name="your_license_key_has_been_set_an_app_restart_might_be_required">Your license key has been set!\nAn app restart might be required.</string>
<string name="invalid_license_format">Invalid license format</string>
<string name="unknown_content_format">Unknown content format</string>
@ -610,6 +609,7 @@
<string name="expected_media_content_found">Expected media content, found</string>
<string name="failed_to_load_post">Failed to load post.</string>
<string name="replies">replies</string>
<string name="Replies">Replies</string>
<string name="plugin_settings_saved">Plugin settings saved</string>
<string name="plugin_settings">Plugin settings</string>
<string name="these_settings_are_defined_by_the_plugin">These settings are defined by the plugin</string>
@ -684,6 +684,52 @@
<string name="failed_to_retry_for_live_stream">Failed to retry for live stream</string>
<string name="this_app_is_in_development_please_submit_bug_reports_and_understand_that_many_features_are_incomplete">This app is in development. Please submit bug reports and understand that many features are incomplete.</string>
<string name="please_use_at_least_3_characters">Please use at least 3 characters</string>
<string name="are_you_sure_you_want_to_delete_this_video">Are you sure you want to delete this video?</string>
<string name="tap_to_open">Tap to open</string>
<string name="watching">watching</string>
<string name="available_in">available in</string>
<string name="seconds">seconds</string>
<string name="please_login_to_post_a_comment">Please login to post a comment</string>
<string name="failed_to_post_comment">Failed to post comment:</string>
<string name="waiting_for_unmetered">Waiting for unmetered</string>
<string name="last_error">Last error</string>
<string name="error">Error</string>
<string name="filters">Filters</string>
<string name="viewers">viewers</string>
<string name="expected_at_least_one_reply_but_no_replies_were_returned_by_the_server">Expected at least one reply but no replies were returned by the server</string>
<string name="please_login_to_like">Please login to like</string>
<string name="please_login_to_dislike">Please login to dislike</string>
<string name="failed_to_load_comments">"Failed to load comments. "</string>
<string name="script_is_not_available">Script is not available</string>
<string name="signature_is_valid">Signature is valid</string>
<string name="signature_is_invalid">Signature is invalid</string>
<string name="no_signature_available">No signature available</string>
<string name="subscribed_to">"Subscribed to "</string>
<string name="unsubscribed_from">"Unsubscribed from "</string>
<string name="you_don_t_have_any_automatic_backups">You don\'t have any automatic backups</string>
<string name="an_old_backup_is_available">An old backup is available</string>
<string name="would_you_like_to_restore_this_backup">Would you like to restore this backup?</string>
<string name="override">Override</string>
<string name="data_retry">Data Retry</string>
<string name="no_downloads_available">No downloads available</string>
<string name="no_downloadable_sources_yet">No downloadable sources (yet)</string>
<string name="none">None</string>
<string name="audio_only">Audio Only</string>
<string name="download_video">Download Video</string>
<string name="fetching_video_details">Fetching video details</string>
<string name="failed_to_fetch_details_for_download">Failed to fetch details for download</string>
<string name="target_resolution">Target Resolution</string>
<string name="target_bitrate">Target Bitrate</string>
<string name="low_bitrate">Low Bitrate</string>
<string name="high_bitrate">High Bitrate</string>
<string name="actions">Actions</string>
<string name="download_the_video">Download the video</string>
<string name="video_options">Video Options</string>
<string name="change_pins">Change Pins</string>
<string name="decide_which_buttons_should_be_pinned">Decide which buttons should be pinned</string>
<string name="select_your_pins_in_order">Select your pins in order</string>
<string name="more_options">More Options</string>
<string name="save">Save</string>
<string-array name="casting_device_type_array">
<item>FastCast</item>
<item>ChromeCast</item>