M melon/browse/playlist.py => melon/browse/playlist.py +2 -3
@@ 34,13 34,12 @@ class BrowsePlaylistScreen(Adw.NavigationPage):
box = Gtk.Box()
self.external_btn = IconButton("","modem-symbolic")
self.external_btn.connect("clicked", self.on_open_in_browser)
- box.append(self.external_btn)
+ self.header_bar.pack_end(self.external_btn)
self.startplay_btn = IconButton("","media-playback-start-symbolic", tooltip=_("Start playing"))
self.startplay_btn.set_action_name("win.playlistplayer-external")
self.startplay_btn.set_action_target_value(
GLib.Variant("as", [self.playlist.server, self.playlist.id]))
- box.append(self.startplay_btn)
- self.header_bar.pack_end(box)
+ self.header_bar.pack_end(self.startplay_btn)
# base layout
self.box = Adw.PreferencesPage()
M melon/player/__init__.py => melon/player/__init__.py +16 -10
@@ 19,6 19,9 @@ from melon.utils import pass_me
class PlayerScreen(Adw.NavigationPage):
duration = None
position = None
+
+ external_btn = None
+
def on_open_in_browser(self, arg):
Gtk.UriLauncher.new(uri=self.video.url).launch()
@@ 89,16 92,6 @@ class PlayerScreen(Adw.NavigationPage):
subs = get_subscribed_channels()
status.set_description(_("Video could not be loaded"))
status.set_icon_name("weather-few-clouds-night-symbolic")
- icon_button = IconButton(_("Exit Playlist mode"), "window-close-symbolic")
- # TODO fix action
- icon_button.set_action_name("win.browse")
- icon_button.set_margin_bottom(6)
- box = Gtk.CenterBox()
- ls = Gtk.Box(orientation = Gtk.Orientation.VERTICAL)
- ls.append(icon_button)
- ls.append(refresh_btn)
- box.set_center_widget(ls)
- status.set_child(box)
self.scrollview.set_child(status)
return False
@@ 121,6 114,7 @@ class PlayerScreen(Adw.NavigationPage):
self.channel = self.instance.get_channel_info(self.video.channel[1])
GLib.idle_add(self.display_channel)
+ view = None
def __init__(self, server_id, video_id, *args, **kwargs):
super().__init__(*args, **kwargs)
if server_id is None or video_id is None:
@@ 147,6 141,9 @@ class PlayerScreen(Adw.NavigationPage):
self.position = None
self.duration = None
+ # disconnect old webview
+ self.stop_webview()
+
# show fallback title
# in case init_video is called twice,
# this resets the title
@@ 170,6 167,8 @@ class PlayerScreen(Adw.NavigationPage):
server = get_servers_list()[server_id]
self.instance = get_server_instance(server)
+ if not self.external_btn is None:
+ self.header_bar.remove(self.external_btn)
self.external_btn = IconButton("","modem-symbolic")
self.external_btn.connect("clicked", self.on_open_in_browser)
self.header_bar.pack_end(self.external_btn)
@@ 193,6 192,7 @@ class PlayerScreen(Adw.NavigationPage):
def on_hide(self):
self.visible = False
+ self.stop_webview()
# save playback position & duration when closing the video
# NOTE: this does not include closing the app
self.store_position()
@@ 242,6 242,8 @@ class PlayerScreen(Adw.NavigationPage):
self.instance.connect_video_ended(self.view, self.on_end)
def on_end(self, state):
+ if not state:
+ return
# we've reached the end of the video
# might as well manually save the position
if not self.duration is None:
@@ 276,3 278,7 @@ class PlayerScreen(Adw.NavigationPage):
if self.position is None or self.duration is None:
return
set_video_playback_position(self.video, self.position, self.duration)
+
+ def stop_webview(self):
+ if not self.view is None:
+ self.view.terminate_web_process()
M melon/player/playlist.py => melon/player/playlist.py +163 -29
@@ 6,6 6,7 @@ from gi.repository import Gtk, Adw, WebKit, GLib
from unidecode import unidecode
from gettext import gettext as _
import threading
+import random
from melon.servers.utils import get_server_instance, get_servers_list
from melon.servers import SearchMode
@@ 26,6 27,10 @@ class PlaylistPlayerScreen(PlayerScreen):
playlist_instance = None
playlist_content = []
+ playlist_shuffle = False
+ playlist_repeat = False
+ playlist_repeat_single = False
+
def __init__(self, ref: (tuple[str, str] | int), index=0, *args, **kwargs):
# make sure to initalize widget
# PlayerScreen.__init__ will break after initializing parents
@@ 37,6 42,9 @@ class PlaylistPlayerScreen(PlayerScreen):
self.video_duration = None
self.video_position = None
self.playlist_instance = None
+ self.playlist_shuffle = False
+ self.playlist_repeat = False
+ self.playlist_repeat_single = False
# prepare base layout
self.header_bar = Adw.HeaderBar()
@@ 100,9 108,37 @@ class PlaylistPlayerScreen(PlayerScreen):
if self.playlist_index > len(self.playlist_content):
GLib.idle_add(self.playlist_error)
return
- self.prepare(0)
+
+ ind = self.get_next_index(0)
+ if not ind is None:
+ self.prepare(ind)
+
+ def get_next_index(self,fallback=None):
+ index = self.playlist_index + 1
+ if not fallback is None:
+ index = fallback
+
+ if self.playlist_repeat_single:
+ # repeat single song is enabled
+ return self.playlist_index
+ elif self.playlist_shuffle:
+ # select a random title
+ # NOTE: may just repeat the same song again
+ index = random.randrange(0,len(self.playlist_content), 1)
+ return index
+
+ if self.playlist_index+1 >= len(self.playlist_content):
+ # playlist ended
+ if self.playlist_repeat:
+ # playlist is set to repeat so we continue picking songs
+ return self.get_next_index(0)
+ else:
+ # no more songs to play
+ return None
+ return index
def prepare(self, index):
+ self.playlist_index = index
dt = self.playlist_content[index]
server_id = dt.server
video_id = dt.id
@@ 111,47 147,145 @@ class PlaylistPlayerScreen(PlayerScreen):
def on_end(self, state):
super().on_end(state)
- # if there are more videos in the playlist
- # load the next one
- # do nothing if there are no more videos
- if self.playlist_index+1 < len(self.playlist_content):
- self.playlist_index += 1
- self.prepare(self.playlist_index)
+ if not state:
+ return
+ ind = self.get_next_index()
+ if not ind is None:
+ self.prepare(ind)
def empty_playlist(self):
# display playlist is empty banner
# acts as a drop in replacement for the player screen
status = Adw.StatusPage()
status.set_title(_("*crickets chirping*"))
- subs = get_subscribed_channels()
status.set_description(_("This playlist is empty"))
status.set_icon_name("weather-few-clouds-night-symbolic")
- icon_button = IconButton(_("Exit Playlist mode"), "window-close-symbolic")
- # TODO fix action
- icon_button.set_action_name("win.browse")
- icon_button.set_margin_bottom(6)
- box = Gtk.CenterBox()
- ls = Gtk.Box(orientation = Gtk.Orientation.VERTICAL)
- ls.append(icon_button)
- ls.append(refresh_btn)
- box.set_center_widget(ls)
- status.set_child(box)
self.scrollview.set_child(status)
def playlist_error(self):
status = Adw.StatusPage()
status.set_title(_("*crickets chirping*"))
- subs = get_subscribed_channels()
status.set_description(_("There was an error loading the playlist"))
status.set_icon_name("weather-few-clouds-night-symbolic")
- icon_button = IconButton(_("Close"), "window-close-symbolic")
- # TODO fix action
- icon_button.set_action_name("win.browse")
- icon_button.set_margin_bottom(6)
- box = Gtk.CenterBox()
- ls = Gtk.Box(orientation = Gtk.Orientation.VERTICAL)
- ls.append(icon_button)
- ls.append(refresh_btn)
- box.set_center_widget(ls)
- status.set_child(box)
self.scrollview.set_child(status)
+
+ def background(self, video_id):
+ super().background(video_id)
+ GLib.idle_add(self.display_control)
+
+ def ctr_previous_video(self):
+ index = self.playlist_index - 1
+ if index >= 0:
+ self.prepare(index)
+
+ def ctr_next_video(self):
+ index = self.playlist_index + 1
+ if index < len(self.playlist_content):
+ self.prepare(index)
+
+ def ctr_skip_video(self):
+ ind = self.get_next_index()
+ if not ind is None:
+ self.prepare(ind)
+
+ def ctr_toggle_shuffle(self, state):
+ self.playlist_shuffle = state
+ # force rerender the playlist control box
+ # updates the prev/next and repeat_all button
+ self.about.remove(self.ctr_group)
+ self.display_control()
+
+ def ctr_toggle_playlist_repeat(self, state):
+ self.playlist_repeat = state
+ def ctr_toggle_playlist_repeat_single(self, state):
+ self.playlist_repeat_single = state
+
+ def display_control(self):
+ self.ctr_group = Adw.PreferencesGroup()
+ self.ctr_group.set_title(self.playlist.inner.title)
+ self.ctr_group.set_description(self.playlist.inner.description)
+
+ # if the video isn't the first
+ # show a previous button
+ # not shown when shuffle is enbaled
+ if self.playlist_index > 0 and not self.playlist_shuffle:
+ prev_btn = Adw.ActionRow()
+ prev_btn.set_title(_("Previous"))
+ prev_btn.set_subtitle(_("Play video that comes before this one in the playlist"))
+ prev_btn.add_suffix(Gtk.Image.new_from_icon_name("media-skip-backward-symbolic"))
+ prev_btn.connect("activated", lambda _: self.ctr_previous_video())
+ prev_btn.set_activatable(True)
+ self.ctr_group.add(prev_btn)
+
+ # if the video isn't the last
+ # show a next button
+ # not shown when shuffle is enbaled
+ if self.playlist_index+1 < len(self.playlist_content) and not self.playlist_shuffle:
+ next_btn = Adw.ActionRow()
+ next_btn.set_title(_("Next"))
+ next_btn.set_subtitle(_("Play video that comes after this one in the playlist"))
+ next_btn.add_suffix(Gtk.Image.new_from_icon_name("media-skip-forward-symbolic"))
+ next_btn.connect("activated", lambda _: self.ctr_next_video())
+ next_btn.set_activatable(True)
+ self.ctr_group.add(next_btn)
+ elif self.playlist_shuffle:
+ # show alternative next button
+ # which picks a new song
+ skip_btn = Adw.ActionRow()
+ skip_btn.set_title(_("Skip"))
+ skip_btn.set_subtitle(_("Skip this video and pick a new one at random"))
+ skip_btn.add_suffix(Gtk.Image.new_from_icon_name("media-skip-forward-symbolic"))
+ skip_btn.connect("activated", lambda _: self.ctr_skip_video())
+ skip_btn.set_activatable(True)
+ self.ctr_group.add(skip_btn)
+
+ # control the playlist shuffle mode
+ pref_shuffle = Preference(
+ "playlist-shuffle",
+ _("Shuffle"),
+ _("Chooses the next video at random"),
+ PreferenceType.TOGGLE,
+ self.playlist_shuffle,
+ self.playlist_shuffle)
+ widg_shuffle = PreferenceRow(pref_shuffle)
+ widg_shuffle.set_callback(self.ctr_toggle_shuffle)
+ self.ctr_group.add(widg_shuffle.get_widget())
+ # control single video repeat mode
+ pref_repeat_single = Preference(
+ "playlist-repeat-single",
+ _("Repeat current video"),
+ _("Puts this video on loop"),
+ PreferenceType.TOGGLE,
+ self.playlist_repeat_single,
+ self.playlist_repeat_single)
+ widg_repeat_single = PreferenceRow(pref_repeat_single)
+ widg_repeat_single.set_callback(self.ctr_toggle_playlist_repeat_single)
+ self.ctr_group.add(widg_repeat_single.get_widget())
+
+ # control playlist repeat mode
+ # cannot be changed if shuffle mode is enabled
+ # because the playlist never ends
+ if not self.playlist_shuffle:
+ pref_repeat = Preference(
+ "playlist-repeat",
+ _("Repeat playlist"),
+ _("Start playling the playlist from the beginning after reaching the end"),
+ PreferenceType.TOGGLE,
+ self.playlist_repeat,
+ self.playlist_repeat)
+ widg_repeat = PreferenceRow(pref_repeat)
+ widg_repeat.set_callback(self.ctr_toggle_playlist_repeat)
+ self.ctr_group.add(widg_repeat.get_widget())
+
+ # expander with playlist content
+ expander = Adw.ExpanderRow()
+ expander.set_title(_("Playlist Content"))
+ expander.set_subtitle(_("Click on videos to continue playing the playlist from there"))
+ for i in range(len(self.playlist_content)):
+ item = self.playlist_content[i]
+ # onClick: starts playling the playlist from <clicked.index>
+ row = AdaptiveFeedItem(item, onClick=pass_me(lambda _, i: self.prepare(i), i))
+ expander.add_row(row)
+ self.ctr_group.add(expander)
+
+ self.about.add(self.ctr_group)
M melon/servers/invidious/__init__.py => melon/servers/invidious/__init__.py +10 -2
@@ 422,7 422,11 @@ class Invidious(Server):
def on_js_bool(self, obj, async_res, webview, on_bool):
if on_bool is None:
return
- val = webview.call_async_javascript_function_finish(async_res)
+ try:
+ val = webview.call_async_javascript_function_finish(async_res)
+ except Exception as e:
+ on_bool(False)
+ return
if val.is_boolean():
on_bool(val.to_boolean())
else:
@@ 430,7 434,11 @@ class Invidious(Server):
def on_js_double(self, obj, async_res, webview, on_double):
if on_double is None:
return
- val = webview.call_async_javascript_function_finish(async_res)
+ try:
+ val = webview.call_async_javascript_function_finish(async_res)
+ except Exception as e:
+ on_double(None)
+ return
if val.is_number():
on_double(val.to_double())
else:
M melon/widgets/feeditem.py => melon/widgets/feeditem.py +15 -6
@@ 15,11 15,12 @@ class AdaptiveFeedItem(Adw.ActionRow):
"""
FeedItem with automatic adjustment to resource type
"""
- def __init__(self, resource:Resource, show_preview=True, clickable=True, *args, **kwargs):
+ def __init__(self, resource:Resource, show_preview=True, clickable=True, onClick=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.res = resource
self.show_preview = show_preview
self.clickable = clickable
+ self.onClick = onClick
self.update()
def set_resource(self, resource: Resource):
self.res = resource
@@ 31,14 32,16 @@ class AdaptiveFeedItem(Adw.ActionRow):
show_preview = self.show_preview
clickable = self.clickable
self.set_activatable(clickable)
- self.set_action_target_value(
- GLib.Variant("as", [resource.server, resource.id]))
+ if self.onClick is None:
+ self.set_action_target_value(
+ GLib.Variant("as", [resource.server, resource.id]))
thumb_url = None
if isinstance(resource, Video):
thumb_url = resource.thumbnail
self.set_title(unidecode(resource.title).replace("&","&"))
self.set_subtitle(unidecode(resource.channel[0]).replace("&","&"))
- self.set_action_name("win.player")
+ if self.onClick is None:
+ self.set_action_name("win.player")
elif isinstance(resource, Playlist):
thumb_url = resource.thumbnail
self.set_title(unidecode(resource.title).replace("&","&"))
@@ 49,7 52,8 @@ class AdaptiveFeedItem(Adw.ActionRow):
# because it could possibly cut the unicode in half? I think?
sub = unidecode(resource.description)[:80] + pad
self.set_subtitle(sub.replace("&","&"))
- self.set_action_name("win.browse_playlist")
+ if self.onClick is None:
+ self.set_action_name("win.browse_playlist")
elif isinstance(resource, Channel):
thumb_url = resource.avatar
self.set_title(unidecode(resource.name).replace("&","&"))
@@ 60,7 64,12 @@ class AdaptiveFeedItem(Adw.ActionRow):
# because it could possibly cut the unicode in half? I think?
sub = unidecode(resource.bio)[:80] + pad
self.set_subtitle(sub.replace("&","&"))
- self.set_action_name("win.browse_channel")
+ if self.onClick is None:
+ self.set_action_name("win.browse_channel")
+
+ if not self.onClick is None:
+ self.connect("activated", self.onClick)
+
self.preview = Adw.Avatar()
self.preview.set_size(48)
self.preview.set_show_initials(True)
M po/POTFILES.in => po/POTFILES.in +2 -0
@@ 5,6 5,7 @@ melon/browse/channel.py
melon/browse/playlist.py
melon/browse/search.py
melon/browse/server.py
+melon/home/__init__.py
melon/home/history.py
melon/home/new.py
melon/home/playlists.py
@@ 12,6 13,7 @@ melon/home/subs.py
melon/import_providers/newpipe.py
melon/importer.py
melon/player/__init__.py
+melon/player/playlist.py
melon/playlist/__init__.py
melon/playlist/create.py
melon/playlist/pick.py
M po/de.po => po/de.po +160 -64
@@ 7,7 7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Melon 0.1.2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-03-09 08:25+0100\n"
+"POT-Creation-Date: 2024-03-13 07:44+0100\n"
"PO-Revision-Date: 2024-03-01 11:23+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: German <https://translate.codeberg.org/projects/melon/melon-"
@@ 80,9 80,11 @@ msgstr ""
#: ../melon/browse/__init__.py:18 ../melon/browse/search.py:58
#: ../melon/browse/server.py:101 ../melon/browse/server.py:127
-#: ../melon/home/history.py:23 ../melon/home/new.py:28
+#: ../melon/home/history.py:23 ../melon/home/new.py:29
#: ../melon/home/playlists.py:21 ../melon/home/subs.py:20
-#: ../melon/importer.py:61 ../melon/playlist/__init__.py:44
+#: ../melon/importer.py:61 ../melon/player/__init__.py:91
+#: ../melon/player/playlist.py:160 ../melon/player/playlist.py:167
+#: ../melon/playlist/__init__.py:52
msgid "*crickets chirping*"
msgstr "*Grillen zirpen*"
@@ 132,15 134,19 @@ msgstr ""
msgid "Channel"
msgstr ""
-#: ../melon/browse/playlist.py:47 ../melon/player/__init__.py:43
+#: ../melon/browse/playlist.py:38 ../melon/playlist/__init__.py:43
+msgid "Start playing"
+msgstr ""
+
+#: ../melon/browse/playlist.py:57 ../melon/player/__init__.py:50
msgid "Bookmark"
msgstr "Merken"
-#: ../melon/browse/playlist.py:48
+#: ../melon/browse/playlist.py:58
msgid "Add Playlist to your local playlist collection"
msgstr "Wiedergabeliste zur lokalen Sammlung hinzufügen"
-#: ../melon/browse/playlist.py:102
+#: ../melon/browse/playlist.py:112
msgid "Playlist"
msgstr ""
@@ 198,14 204,31 @@ msgstr "Versuche nach einem anderen Begriff zu suchen"
msgid "This feed is empty"
msgstr ""
-#: ../melon/home/history.py:24
-msgid "You haven't watched any videos yet"
-msgstr "Du hast noch keine Videos geschaut"
+#: ../melon/home/__init__.py:18
+msgid "Home"
+msgstr ""
-#: ../melon/home/history.py:26 ../melon/home/new.py:35 ../melon/home/subs.py:23
+#: ../melon/home/__init__.py:39 ../melon/home/history.py:26
+#: ../melon/home/new.py:36 ../melon/home/subs.py:23
msgid "Browse Servers"
msgstr "Dienste durchsuchen"
+#: ../melon/home/__init__.py:46
+msgid "Preferences"
+msgstr ""
+
+#: ../melon/home/__init__.py:47
+msgid "Import Data"
+msgstr ""
+
+#: ../melon/home/__init__.py:48
+msgid "About Melon"
+msgstr ""
+
+#: ../melon/home/history.py:24
+msgid "You haven't watched any videos yet"
+msgstr "Du hast noch keine Videos geschaut"
+
#: ../melon/home/history.py:36 ../melon/home/history.py:117
msgid "History"
msgstr "Verlauf"
@@ 222,31 245,39 @@ msgstr ""
msgid "Load older videos"
msgstr ""
-#: ../melon/home/new.py:22
+#: ../melon/home/new.py:23
msgid "Refresh"
msgstr "Aktualisieren"
-#: ../melon/home/new.py:31
+#: ../melon/home/new.py:32
msgid "Subscribe to a channel first, to view new uploads"
msgstr "Du musst einem Kanal folgen, um neue Videos zu sehen."
-#: ../melon/home/new.py:33
+#: ../melon/home/new.py:34
msgid "The channels you are subscribed to haven't uploaded anything yet"
msgstr "Die Kanäle, die du abonniert hast, haben noch nichts hochgeladen"
-#: ../melon/home/new.py:54
+#: ../melon/home/new.py:55
#, python-brace-format
msgid "(Last refresh: {last_refresh})"
msgstr "(Zuletzt aktualisiert: {last_refresh})"
-#: ../melon/home/new.py:56 ../melon/home/new.py:113
+#: ../melon/home/new.py:57 ../melon/home/new.py:144
msgid "What's new"
msgstr "Neues"
-#: ../melon/home/new.py:57
+#: ../melon/home/new.py:58
msgid "These are the latest videos of channels you follow"
msgstr "Hier sind die neusten Videos von Kanälen, denen du folgst"
+#: ../melon/home/new.py:135
+msgid "Pick up where you left off"
+msgstr ""
+
+#: ../melon/home/new.py:136
+msgid "Watch"
+msgstr ""
+
#: ../melon/home/playlists.py:22
msgid "You don't have any playlists yet"
msgstr "Du hast noch keine Wiedergabelisten"
@@ 310,113 341,178 @@ msgstr "Die folgenden Import-Methoden wurden gefunden"
msgid "There are no available importer methods"
msgstr "Es gibt keine verfügbaren Import-Methoden"
-#: ../melon/player/__init__.py:33
+#: ../melon/player/__init__.py:40
msgid "Description"
msgstr "Beschreibung"
-#: ../melon/player/__init__.py:44
+#: ../melon/player/__init__.py:51
msgid "Add this video to a playlist"
msgstr "Füge dieses Video einer Wiedergabeliste hinzu"
-#: ../melon/player/__init__.py:62
+#: ../melon/player/__init__.py:71
msgid "Quality"
msgstr "Auflösung"
-#: ../melon/player/__init__.py:63
+#: ../melon/player/__init__.py:72
msgid "Video quality"
msgstr "Auflösung"
-#: ../melon/player/__init__.py:78
+#: ../melon/player/__init__.py:93
msgid "Video could not be loaded"
msgstr ""
-#: ../melon/player/__init__.py:110
-msgid "Player"
+#: ../melon/player/__init__.py:124 ../melon/player/__init__.py:150
+#: ../melon/player/playlist.py:51
+msgid "Loading..."
+msgstr ""
+
+#: ../melon/player/playlist.py:161
+msgid "This playlist is empty"
+msgstr ""
+
+#: ../melon/player/playlist.py:168
+msgid "There was an error loading the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:213
+msgid "Previous"
+msgstr ""
+
+#: ../melon/player/playlist.py:214
+msgid "Play video that comes before this one in the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:225
+msgid "Next"
+msgstr ""
+
+#: ../melon/player/playlist.py:226
+msgid "Play video that comes after this one in the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:235
+msgid "Skip"
+msgstr ""
+
+#: ../melon/player/playlist.py:236
+msgid "Skip this video and pick a new one at random"
+msgstr ""
+
+#: ../melon/player/playlist.py:245
+msgid "Shuffle"
+msgstr ""
+
+#: ../melon/player/playlist.py:246
+msgid "Chooses the next video at random"
+msgstr ""
+
+#: ../melon/player/playlist.py:256
+msgid "Repeat current video"
+msgstr ""
+
+#: ../melon/player/playlist.py:257
+msgid "Puts this video on loop"
+msgstr ""
+
+#: ../melon/player/playlist.py:271
+msgid "Repeat playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:272
+msgid "Start playling the playlist from the beginning after reaching the end"
+msgstr ""
+
+#: ../melon/player/playlist.py:282
+msgid "Playlist Content"
+msgstr ""
+
+#: ../melon/player/playlist.py:283
+msgid "Click on videos to continue playing the playlist from there"
msgstr ""
#: ../melon/playlist/__init__.py:39
msgid "Edit"
msgstr "Bearbeiten"
-#: ../melon/playlist/__init__.py:45
+#: ../melon/playlist/__init__.py:53
msgid "You haven't added any videos to this playlist yet"
msgstr "Du hast noch keine Videos zu dieser Wiedergabeliste hinzugefügt"
-#: ../melon/playlist/__init__.py:47
+#: ../melon/playlist/__init__.py:55
msgid "Start watching"
msgstr "Videos anschauen"
-#: ../melon/playlist/__init__.py:77
+#: ../melon/playlist/__init__.py:85
msgid "Edit Playlist"
msgstr "Wiedergabeliste bearbeiten"
-#: ../melon/playlist/__init__.py:83
+#: ../melon/playlist/__init__.py:91
msgid "Playlist details"
msgstr "Wiedergabelistendetails"
-#: ../melon/playlist/__init__.py:84
+#: ../melon/playlist/__init__.py:92
msgid "Change playlist information"
msgstr "Wiedergabelistendetails ändern"
-#: ../melon/playlist/__init__.py:86 ../melon/playlist/create.py:37
+#: ../melon/playlist/__init__.py:94 ../melon/playlist/create.py:37
msgid "Playlist name"
msgstr "Name der Wiedergabeliste"
-#: ../melon/playlist/__init__.py:89 ../melon/playlist/create.py:40
+#: ../melon/playlist/__init__.py:97 ../melon/playlist/create.py:40
msgid "Playlist description"
msgstr "Beschreibung der Wiedergabeliste"
-#: ../melon/playlist/__init__.py:94
+#: ../melon/playlist/__init__.py:102
msgid "Save details"
msgstr "Details speichern"
-#: ../melon/playlist/__init__.py:95
+#: ../melon/playlist/__init__.py:103
msgid "Change playlist title and description. (Closes the dialog)"
msgstr ""
"Titel und Beschreibung der Wiedergabeliste ändern. (Schließt den Dialog)"
-#: ../melon/playlist/__init__.py:105 ../melon/playlist/__init__.py:147
+#: ../melon/playlist/__init__.py:113 ../melon/playlist/__init__.py:155
msgid "Delete Playlist"
msgstr "Wiedergabeliste löschen"
-#: ../melon/playlist/__init__.py:106
+#: ../melon/playlist/__init__.py:114
msgid "Delete this playlist and it's content. This can NOT be undone."
msgstr ""
"Diese Wiedergabeliste und ihren Inhalt löschen. Diese Aktion kann nicht "
"rückgängig gemacht werden."
-#: ../melon/playlist/__init__.py:117
+#: ../melon/playlist/__init__.py:125
msgid "Close"
msgstr "Schließen"
-#: ../melon/playlist/__init__.py:117
+#: ../melon/playlist/__init__.py:125
msgid "Close without changing anything"
msgstr ""
-#: ../melon/playlist/__init__.py:150
+#: ../melon/playlist/__init__.py:158
msgid "Do you really want to delete this playlist?"
msgstr ""
-#: ../melon/playlist/__init__.py:151
+#: ../melon/playlist/__init__.py:159
msgid "This cannot be undone"
msgstr "Dies kann nicht rückgängig gemacht werden"
-#: ../melon/playlist/__init__.py:155 ../melon/playlist/create.py:47
-#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:174
-#: ../melon/widgets/preferencerow.py:217
+#: ../melon/playlist/__init__.py:163 ../melon/playlist/create.py:47
+#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:175
+#: ../melon/widgets/preferencerow.py:218
msgid "Cancel"
msgstr "Abbruch"
-#: ../melon/playlist/__init__.py:155
+#: ../melon/playlist/__init__.py:163
msgid "Do not delete the playlist"
msgstr "Wiedergabeliste nicht löschen"
-#: ../melon/playlist/__init__.py:156 ../melon/widgets/preferencerow.py:206
-#: ../melon/widgets/preferencerow.py:218
+#: ../melon/playlist/__init__.py:164 ../melon/widgets/preferencerow.py:207
+#: ../melon/widgets/preferencerow.py:219
msgid "Delete"
msgstr "Löschen"
-#: ../melon/playlist/__init__.py:156
+#: ../melon/playlist/__init__.py:164
msgid "Delete this playlist"
msgstr "Diese Wiedergabeliste löschen"
@@ 444,7 540,7 @@ msgstr "Unbenannte Wiedergabeliste"
msgid "Do not create playlist"
msgstr "Wiedergabeliste nicht erstellen"
-#: ../melon/playlist/create.py:48 ../melon/widgets/preferencerow.py:175
+#: ../melon/playlist/create.py:48 ../melon/widgets/preferencerow.py:176
msgid "Create"
msgstr "Erstellen"
@@ 480,26 576,26 @@ msgstr "Neue Wiedergabeliste erstellen und Video hinzufügen"
msgid "Add to Playlist"
msgstr "Zur Wiedergabeliste hinzufügen"
-#: ../melon/servers/invidious/__init__.py:27
+#: ../melon/servers/invidious/__init__.py:32
msgid "Open source alternative front-end to YouTube"
msgstr "Quelloffenes alternatives Frontend für YouTube"
-#: ../melon/servers/invidious/__init__.py:32
+#: ../melon/servers/invidious/__init__.py:37
msgid "Instance"
msgstr "Instanz"
-#: ../melon/servers/invidious/__init__.py:33
+#: ../melon/servers/invidious/__init__.py:38
msgid ""
"See https://docs.invidious.io/instances/ for a list of available instances"
msgstr ""
"Auf https://docs.invidious.io/instances/ kannst du eine liste verfügbarer "
"Instanzen finden"
-#: ../melon/servers/invidious/__init__.py:44
+#: ../melon/servers/invidious/__init__.py:49
msgid "Trending"
msgstr "Trends"
-#: ../melon/servers/invidious/__init__.py:45
+#: ../melon/servers/invidious/__init__.py:50
msgid "Popular"
msgstr "Beliebt"
@@ 659,55 755,55 @@ msgstr ""
"Deaktivierte Dienste werden beim Durchsuchen und auf dem Startbildschirm "
"nicht angezeigt"
-#: ../melon/widgets/preferencerow.py:115
+#: ../melon/widgets/preferencerow.py:116
msgid "Add"
msgstr "Hinzufügen"
-#: ../melon/widgets/preferencerow.py:129
+#: ../melon/widgets/preferencerow.py:130
msgid "Move up"
msgstr "Nach oben verschieben"
-#: ../melon/widgets/preferencerow.py:140
+#: ../melon/widgets/preferencerow.py:141
msgid "Move down"
msgstr "Nach unten verschieben"
-#: ../melon/widgets/preferencerow.py:149
+#: ../melon/widgets/preferencerow.py:150
msgid "Remove from list"
msgstr "Von der Liste entfernen"
-#: ../melon/widgets/preferencerow.py:162
+#: ../melon/widgets/preferencerow.py:163
msgid "Add Item"
msgstr "Eintrag hinzufügen"
-#: ../melon/widgets/preferencerow.py:165
+#: ../melon/widgets/preferencerow.py:166
msgid "Create a new list entry"
msgstr "Neuen Listeneintrag erstellen"
-#: ../melon/widgets/preferencerow.py:166
+#: ../melon/widgets/preferencerow.py:167
msgid "Enter the new value here"
msgstr "Gibt den neuen Wert hier ein"
-#: ../melon/widgets/preferencerow.py:169
+#: ../melon/widgets/preferencerow.py:170
msgid "Value"
msgstr "Wert"
-#: ../melon/widgets/preferencerow.py:209
+#: ../melon/widgets/preferencerow.py:210
msgid "Do you really want to delete this item?"
msgstr "Möchtest du den Eintrag wirklich löschen?"
-#: ../melon/widgets/preferencerow.py:210
+#: ../melon/widgets/preferencerow.py:211
msgid "You won't be able to restore it afterwards"
msgstr "Eine Wiederherstellung ist nicht möglich"
-#: ../melon/widgets/preferencerow.py:217
+#: ../melon/widgets/preferencerow.py:218
msgid "Do not remove item"
msgstr "Eintrag nicht entfernen"
-#: ../melon/widgets/preferencerow.py:218
+#: ../melon/widgets/preferencerow.py:219
msgid "Remove item from list"
msgstr "Eintrag von der Liste entfernen"
-#: ../melon/window.py:76
+#: ../melon/window.py:84
msgid "Stream videos on the go"
msgstr "Videos unterwegs streamen"
M po/fa.po => po/fa.po +159 -63
@@ 7,7 7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Melon 0.1.2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-03-09 08:25+0100\n"
+"POT-Creation-Date: 2024-03-13 07:44+0100\n"
"PO-Revision-Date: 2024-03-05 05:13+0000\n"
"Last-Translator: sohrabbehdani <behdanisohrab@gmail.com>\n"
"Language-Team: Persian <https://translate.codeberg.org/projects/melon/melon-"
@@ 75,9 75,11 @@ msgstr ""
#: ../melon/browse/__init__.py:18 ../melon/browse/search.py:58
#: ../melon/browse/server.py:101 ../melon/browse/server.py:127
-#: ../melon/home/history.py:23 ../melon/home/new.py:28
+#: ../melon/home/history.py:23 ../melon/home/new.py:29
#: ../melon/home/playlists.py:21 ../melon/home/subs.py:20
-#: ../melon/importer.py:61 ../melon/playlist/__init__.py:44
+#: ../melon/importer.py:61 ../melon/player/__init__.py:91
+#: ../melon/player/playlist.py:160 ../melon/player/playlist.py:167
+#: ../melon/playlist/__init__.py:52
msgid "*crickets chirping*"
msgstr ""
@@ 126,15 128,19 @@ msgstr ""
msgid "Channel"
msgstr ""
-#: ../melon/browse/playlist.py:47 ../melon/player/__init__.py:43
+#: ../melon/browse/playlist.py:38 ../melon/playlist/__init__.py:43
+msgid "Start playing"
+msgstr ""
+
+#: ../melon/browse/playlist.py:57 ../melon/player/__init__.py:50
msgid "Bookmark"
msgstr "نشانک گذاری"
-#: ../melon/browse/playlist.py:48
+#: ../melon/browse/playlist.py:58
msgid "Add Playlist to your local playlist collection"
msgstr "افزودن این لیستپخش به مجموعه لیستپخش های محلی"
-#: ../melon/browse/playlist.py:102
+#: ../melon/browse/playlist.py:112
msgid "Playlist"
msgstr ""
@@ 191,14 197,31 @@ msgstr ""
msgid "This feed is empty"
msgstr ""
-#: ../melon/home/history.py:24
-msgid "You haven't watched any videos yet"
+#: ../melon/home/__init__.py:18
+msgid "Home"
msgstr ""
-#: ../melon/home/history.py:26 ../melon/home/new.py:35 ../melon/home/subs.py:23
+#: ../melon/home/__init__.py:39 ../melon/home/history.py:26
+#: ../melon/home/new.py:36 ../melon/home/subs.py:23
msgid "Browse Servers"
msgstr "جستجو در کارساز ها"
+#: ../melon/home/__init__.py:46
+msgid "Preferences"
+msgstr ""
+
+#: ../melon/home/__init__.py:47
+msgid "Import Data"
+msgstr ""
+
+#: ../melon/home/__init__.py:48
+msgid "About Melon"
+msgstr ""
+
+#: ../melon/home/history.py:24
+msgid "You haven't watched any videos yet"
+msgstr ""
+
#: ../melon/home/history.py:36 ../melon/home/history.py:117
msgid "History"
msgstr ""
@@ 215,31 238,39 @@ msgstr ""
msgid "Load older videos"
msgstr ""
-#: ../melon/home/new.py:22
+#: ../melon/home/new.py:23
msgid "Refresh"
msgstr ""
-#: ../melon/home/new.py:31
+#: ../melon/home/new.py:32
msgid "Subscribe to a channel first, to view new uploads"
msgstr ""
-#: ../melon/home/new.py:33
+#: ../melon/home/new.py:34
msgid "The channels you are subscribed to haven't uploaded anything yet"
msgstr ""
-#: ../melon/home/new.py:54
+#: ../melon/home/new.py:55
#, python-brace-format
msgid "(Last refresh: {last_refresh})"
msgstr ""
-#: ../melon/home/new.py:56 ../melon/home/new.py:113
+#: ../melon/home/new.py:57 ../melon/home/new.py:144
msgid "What's new"
msgstr ""
-#: ../melon/home/new.py:57
+#: ../melon/home/new.py:58
msgid "These are the latest videos of channels you follow"
msgstr ""
+#: ../melon/home/new.py:135
+msgid "Pick up where you left off"
+msgstr ""
+
+#: ../melon/home/new.py:136
+msgid "Watch"
+msgstr ""
+
#: ../melon/home/playlists.py:22
msgid "You don't have any playlists yet"
msgstr ""
@@ 298,110 329,175 @@ msgstr ""
msgid "There are no available importer methods"
msgstr ""
-#: ../melon/player/__init__.py:33
+#: ../melon/player/__init__.py:40
msgid "Description"
msgstr ""
-#: ../melon/player/__init__.py:44
+#: ../melon/player/__init__.py:51
msgid "Add this video to a playlist"
msgstr "افزودن این ویدئو به لیستپخش"
-#: ../melon/player/__init__.py:62
+#: ../melon/player/__init__.py:71
msgid "Quality"
msgstr ""
-#: ../melon/player/__init__.py:63
+#: ../melon/player/__init__.py:72
msgid "Video quality"
msgstr ""
-#: ../melon/player/__init__.py:78
+#: ../melon/player/__init__.py:93
msgid "Video could not be loaded"
msgstr ""
-#: ../melon/player/__init__.py:110
-msgid "Player"
+#: ../melon/player/__init__.py:124 ../melon/player/__init__.py:150
+#: ../melon/player/playlist.py:51
+msgid "Loading..."
+msgstr ""
+
+#: ../melon/player/playlist.py:161
+msgid "This playlist is empty"
+msgstr ""
+
+#: ../melon/player/playlist.py:168
+msgid "There was an error loading the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:213
+msgid "Previous"
+msgstr ""
+
+#: ../melon/player/playlist.py:214
+msgid "Play video that comes before this one in the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:225
+msgid "Next"
+msgstr ""
+
+#: ../melon/player/playlist.py:226
+msgid "Play video that comes after this one in the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:235
+msgid "Skip"
+msgstr ""
+
+#: ../melon/player/playlist.py:236
+msgid "Skip this video and pick a new one at random"
+msgstr ""
+
+#: ../melon/player/playlist.py:245
+msgid "Shuffle"
+msgstr ""
+
+#: ../melon/player/playlist.py:246
+msgid "Chooses the next video at random"
+msgstr ""
+
+#: ../melon/player/playlist.py:256
+msgid "Repeat current video"
+msgstr ""
+
+#: ../melon/player/playlist.py:257
+msgid "Puts this video on loop"
+msgstr ""
+
+#: ../melon/player/playlist.py:271
+msgid "Repeat playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:272
+msgid "Start playling the playlist from the beginning after reaching the end"
+msgstr ""
+
+#: ../melon/player/playlist.py:282
+msgid "Playlist Content"
+msgstr ""
+
+#: ../melon/player/playlist.py:283
+msgid "Click on videos to continue playing the playlist from there"
msgstr ""
#: ../melon/playlist/__init__.py:39
msgid "Edit"
msgstr ""
-#: ../melon/playlist/__init__.py:45
+#: ../melon/playlist/__init__.py:53
msgid "You haven't added any videos to this playlist yet"
msgstr ""
-#: ../melon/playlist/__init__.py:47
+#: ../melon/playlist/__init__.py:55
msgid "Start watching"
msgstr ""
-#: ../melon/playlist/__init__.py:77
+#: ../melon/playlist/__init__.py:85
msgid "Edit Playlist"
msgstr ""
-#: ../melon/playlist/__init__.py:83
+#: ../melon/playlist/__init__.py:91
msgid "Playlist details"
msgstr ""
-#: ../melon/playlist/__init__.py:84
+#: ../melon/playlist/__init__.py:92
msgid "Change playlist information"
msgstr "تغییر اطلاعات لیست پخش"
-#: ../melon/playlist/__init__.py:86 ../melon/playlist/create.py:37
+#: ../melon/playlist/__init__.py:94 ../melon/playlist/create.py:37
msgid "Playlist name"
msgstr ""
-#: ../melon/playlist/__init__.py:89 ../melon/playlist/create.py:40
+#: ../melon/playlist/__init__.py:97 ../melon/playlist/create.py:40
msgid "Playlist description"
msgstr ""
-#: ../melon/playlist/__init__.py:94
+#: ../melon/playlist/__init__.py:102
msgid "Save details"
msgstr ""
-#: ../melon/playlist/__init__.py:95
+#: ../melon/playlist/__init__.py:103
msgid "Change playlist title and description. (Closes the dialog)"
msgstr "تغییر عنوان و توضیحات لیست پخش (این پنجره بسته می شود)"
-#: ../melon/playlist/__init__.py:105 ../melon/playlist/__init__.py:147
+#: ../melon/playlist/__init__.py:113 ../melon/playlist/__init__.py:155
msgid "Delete Playlist"
msgstr ""
-#: ../melon/playlist/__init__.py:106
+#: ../melon/playlist/__init__.py:114
msgid "Delete this playlist and it's content. This can NOT be undone."
msgstr ""
-#: ../melon/playlist/__init__.py:117
+#: ../melon/playlist/__init__.py:125
msgid "Close"
msgstr "بستن"
-#: ../melon/playlist/__init__.py:117
+#: ../melon/playlist/__init__.py:125
msgid "Close without changing anything"
msgstr "بستن بدون تغییر دادن چیزی"
-#: ../melon/playlist/__init__.py:150
+#: ../melon/playlist/__init__.py:158
msgid "Do you really want to delete this playlist?"
msgstr ""
-#: ../melon/playlist/__init__.py:151
+#: ../melon/playlist/__init__.py:159
msgid "This cannot be undone"
msgstr ""
-#: ../melon/playlist/__init__.py:155 ../melon/playlist/create.py:47
-#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:174
-#: ../melon/widgets/preferencerow.py:217
+#: ../melon/playlist/__init__.py:163 ../melon/playlist/create.py:47
+#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:175
+#: ../melon/widgets/preferencerow.py:218
msgid "Cancel"
msgstr "لغو"
-#: ../melon/playlist/__init__.py:155
+#: ../melon/playlist/__init__.py:163
msgid "Do not delete the playlist"
msgstr ""
-#: ../melon/playlist/__init__.py:156 ../melon/widgets/preferencerow.py:206
-#: ../melon/widgets/preferencerow.py:218
+#: ../melon/playlist/__init__.py:164 ../melon/widgets/preferencerow.py:207
+#: ../melon/widgets/preferencerow.py:219
msgid "Delete"
msgstr ""
-#: ../melon/playlist/__init__.py:156
+#: ../melon/playlist/__init__.py:164
msgid "Delete this playlist"
msgstr ""
@@ 429,7 525,7 @@ msgstr ""
msgid "Do not create playlist"
msgstr ""
-#: ../melon/playlist/create.py:48 ../melon/widgets/preferencerow.py:175
+#: ../melon/playlist/create.py:48 ../melon/widgets/preferencerow.py:176
msgid "Create"
msgstr "ایجاد"
@@ 466,24 562,24 @@ msgstr "ایجاد یک لیستپخش جدید و افزودن ویدئو ب
msgid "Add to Playlist"
msgstr "افزودن به لیستپخش"
-#: ../melon/servers/invidious/__init__.py:27
+#: ../melon/servers/invidious/__init__.py:32
msgid "Open source alternative front-end to YouTube"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:32
+#: ../melon/servers/invidious/__init__.py:37
msgid "Instance"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:33
+#: ../melon/servers/invidious/__init__.py:38
msgid ""
"See https://docs.invidious.io/instances/ for a list of available instances"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:44
+#: ../melon/servers/invidious/__init__.py:49
msgid "Trending"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:45
+#: ../melon/servers/invidious/__init__.py:50
msgid "Popular"
msgstr ""
@@ 623,54 719,54 @@ msgid ""
"Disabled servers won't show up in the browser or on the local/home screen"
msgstr ""
-#: ../melon/widgets/preferencerow.py:115
+#: ../melon/widgets/preferencerow.py:116
msgid "Add"
msgstr "افزودن"
-#: ../melon/widgets/preferencerow.py:129
+#: ../melon/widgets/preferencerow.py:130
msgid "Move up"
msgstr ""
-#: ../melon/widgets/preferencerow.py:140
+#: ../melon/widgets/preferencerow.py:141
msgid "Move down"
msgstr ""
-#: ../melon/widgets/preferencerow.py:149
+#: ../melon/widgets/preferencerow.py:150
msgid "Remove from list"
msgstr ""
-#: ../melon/widgets/preferencerow.py:162
+#: ../melon/widgets/preferencerow.py:163
msgid "Add Item"
msgstr "افزودن مورد"
-#: ../melon/widgets/preferencerow.py:165
+#: ../melon/widgets/preferencerow.py:166
msgid "Create a new list entry"
msgstr "ایجاد یک ورودی لیست جدید"
-#: ../melon/widgets/preferencerow.py:166
+#: ../melon/widgets/preferencerow.py:167
msgid "Enter the new value here"
msgstr ""
-#: ../melon/widgets/preferencerow.py:169
+#: ../melon/widgets/preferencerow.py:170
msgid "Value"
msgstr ""
-#: ../melon/widgets/preferencerow.py:209
+#: ../melon/widgets/preferencerow.py:210
msgid "Do you really want to delete this item?"
msgstr ""
-#: ../melon/widgets/preferencerow.py:210
+#: ../melon/widgets/preferencerow.py:211
msgid "You won't be able to restore it afterwards"
msgstr ""
-#: ../melon/widgets/preferencerow.py:217
+#: ../melon/widgets/preferencerow.py:218
msgid "Do not remove item"
msgstr ""
-#: ../melon/widgets/preferencerow.py:218
+#: ../melon/widgets/preferencerow.py:219
msgid "Remove item from list"
msgstr ""
-#: ../melon/window.py:76
+#: ../melon/window.py:84
msgid "Stream videos on the go"
msgstr ""
M po/melon.pot => po/melon.pot +160 -64
@@ 6,9 6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: Melon 0.1.2\n"
+"Project-Id-Version: Melon 0.1.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-03-09 08:25+0100\n"
+"POT-Creation-Date: 2024-03-13 07:44+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ 74,9 74,11 @@ msgstr ""
#: ../melon/browse/__init__.py:18 ../melon/browse/search.py:58
#: ../melon/browse/server.py:101 ../melon/browse/server.py:127
-#: ../melon/home/history.py:23 ../melon/home/new.py:28
+#: ../melon/home/history.py:23 ../melon/home/new.py:29
#: ../melon/home/playlists.py:21 ../melon/home/subs.py:20
-#: ../melon/importer.py:61 ../melon/playlist/__init__.py:44
+#: ../melon/importer.py:61 ../melon/player/__init__.py:91
+#: ../melon/player/playlist.py:160 ../melon/player/playlist.py:167
+#: ../melon/playlist/__init__.py:52
msgid "*crickets chirping*"
msgstr ""
@@ 125,15 127,19 @@ msgstr ""
msgid "Channel"
msgstr ""
-#: ../melon/browse/playlist.py:47 ../melon/player/__init__.py:43
+#: ../melon/browse/playlist.py:38 ../melon/playlist/__init__.py:43
+msgid "Start playing"
+msgstr ""
+
+#: ../melon/browse/playlist.py:57 ../melon/player/__init__.py:50
msgid "Bookmark"
msgstr ""
-#: ../melon/browse/playlist.py:48
+#: ../melon/browse/playlist.py:58
msgid "Add Playlist to your local playlist collection"
msgstr ""
-#: ../melon/browse/playlist.py:102
+#: ../melon/browse/playlist.py:112
msgid "Playlist"
msgstr ""
@@ 190,14 196,31 @@ msgstr ""
msgid "This feed is empty"
msgstr ""
-#: ../melon/home/history.py:24
-msgid "You haven't watched any videos yet"
+#: ../melon/home/__init__.py:18
+msgid "Home"
msgstr ""
-#: ../melon/home/history.py:26 ../melon/home/new.py:35 ../melon/home/subs.py:23
+#: ../melon/home/__init__.py:39 ../melon/home/history.py:26
+#: ../melon/home/new.py:36 ../melon/home/subs.py:23
msgid "Browse Servers"
msgstr ""
+#: ../melon/home/__init__.py:46
+msgid "Preferences"
+msgstr ""
+
+#: ../melon/home/__init__.py:47
+msgid "Import Data"
+msgstr ""
+
+#: ../melon/home/__init__.py:48
+msgid "About Melon"
+msgstr ""
+
+#: ../melon/home/history.py:24
+msgid "You haven't watched any videos yet"
+msgstr ""
+
#: ../melon/home/history.py:36 ../melon/home/history.py:117
msgid "History"
msgstr ""
@@ 214,31 237,39 @@ msgstr ""
msgid "Load older videos"
msgstr ""
-#: ../melon/home/new.py:22
+#: ../melon/home/new.py:23
msgid "Refresh"
msgstr ""
-#: ../melon/home/new.py:31
+#: ../melon/home/new.py:32
msgid "Subscribe to a channel first, to view new uploads"
msgstr ""
-#: ../melon/home/new.py:33
+#: ../melon/home/new.py:34
msgid "The channels you are subscribed to haven't uploaded anything yet"
msgstr ""
-#: ../melon/home/new.py:54
+#: ../melon/home/new.py:55
#, python-brace-format
msgid "(Last refresh: {last_refresh})"
msgstr ""
-#: ../melon/home/new.py:56 ../melon/home/new.py:113
+#: ../melon/home/new.py:57 ../melon/home/new.py:144
msgid "What's new"
msgstr ""
-#: ../melon/home/new.py:57
+#: ../melon/home/new.py:58
msgid "These are the latest videos of channels you follow"
msgstr ""
+#: ../melon/home/new.py:135
+msgid "Pick up where you left off"
+msgstr ""
+
+#: ../melon/home/new.py:136
+msgid "Watch"
+msgstr ""
+
#: ../melon/home/playlists.py:22
msgid "You don't have any playlists yet"
msgstr ""
@@ 297,110 328,175 @@ msgstr ""
msgid "There are no available importer methods"
msgstr ""
-#: ../melon/player/__init__.py:33
+#: ../melon/player/__init__.py:40
msgid "Description"
msgstr ""
-#: ../melon/player/__init__.py:44
+#: ../melon/player/__init__.py:51
msgid "Add this video to a playlist"
msgstr ""
-#: ../melon/player/__init__.py:62
+#: ../melon/player/__init__.py:71
msgid "Quality"
msgstr ""
-#: ../melon/player/__init__.py:63
+#: ../melon/player/__init__.py:72
msgid "Video quality"
msgstr ""
-#: ../melon/player/__init__.py:78
+#: ../melon/player/__init__.py:93
msgid "Video could not be loaded"
msgstr ""
-#: ../melon/player/__init__.py:110
-msgid "Player"
+#: ../melon/player/__init__.py:124 ../melon/player/__init__.py:150
+#: ../melon/player/playlist.py:51
+msgid "Loading..."
+msgstr ""
+
+#: ../melon/player/playlist.py:161
+msgid "This playlist is empty"
+msgstr ""
+
+#: ../melon/player/playlist.py:168
+msgid "There was an error loading the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:213
+msgid "Previous"
+msgstr ""
+
+#: ../melon/player/playlist.py:214
+msgid "Play video that comes before this one in the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:225
+msgid "Next"
+msgstr ""
+
+#: ../melon/player/playlist.py:226
+msgid "Play video that comes after this one in the playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:235
+msgid "Skip"
+msgstr ""
+
+#: ../melon/player/playlist.py:236
+msgid "Skip this video and pick a new one at random"
+msgstr ""
+
+#: ../melon/player/playlist.py:245
+msgid "Shuffle"
+msgstr ""
+
+#: ../melon/player/playlist.py:246
+msgid "Chooses the next video at random"
+msgstr ""
+
+#: ../melon/player/playlist.py:256
+msgid "Repeat current video"
+msgstr ""
+
+#: ../melon/player/playlist.py:257
+msgid "Puts this video on loop"
+msgstr ""
+
+#: ../melon/player/playlist.py:271
+msgid "Repeat playlist"
+msgstr ""
+
+#: ../melon/player/playlist.py:272
+msgid "Start playling the playlist from the beginning after reaching the end"
+msgstr ""
+
+#: ../melon/player/playlist.py:282
+msgid "Playlist Content"
+msgstr ""
+
+#: ../melon/player/playlist.py:283
+msgid "Click on videos to continue playing the playlist from there"
msgstr ""
#: ../melon/playlist/__init__.py:39
msgid "Edit"
msgstr ""
-#: ../melon/playlist/__init__.py:45
+#: ../melon/playlist/__init__.py:53
msgid "You haven't added any videos to this playlist yet"
msgstr ""
-#: ../melon/playlist/__init__.py:47
+#: ../melon/playlist/__init__.py:55
msgid "Start watching"
msgstr ""
-#: ../melon/playlist/__init__.py:77
+#: ../melon/playlist/__init__.py:85
msgid "Edit Playlist"
msgstr ""
-#: ../melon/playlist/__init__.py:83
+#: ../melon/playlist/__init__.py:91
msgid "Playlist details"
msgstr ""
-#: ../melon/playlist/__init__.py:84
+#: ../melon/playlist/__init__.py:92
msgid "Change playlist information"
msgstr ""
-#: ../melon/playlist/__init__.py:86 ../melon/playlist/create.py:37
+#: ../melon/playlist/__init__.py:94 ../melon/playlist/create.py:37
msgid "Playlist name"
msgstr ""
-#: ../melon/playlist/__init__.py:89 ../melon/playlist/create.py:40
+#: ../melon/playlist/__init__.py:97 ../melon/playlist/create.py:40
msgid "Playlist description"
msgstr ""
-#: ../melon/playlist/__init__.py:94
+#: ../melon/playlist/__init__.py:102
msgid "Save details"
msgstr ""
-#: ../melon/playlist/__init__.py:95
+#: ../melon/playlist/__init__.py:103
msgid "Change playlist title and description. (Closes the dialog)"
msgstr ""
-#: ../melon/playlist/__init__.py:105 ../melon/playlist/__init__.py:147
+#: ../melon/playlist/__init__.py:113 ../melon/playlist/__init__.py:155
msgid "Delete Playlist"
msgstr ""
-#: ../melon/playlist/__init__.py:106
+#: ../melon/playlist/__init__.py:114
msgid "Delete this playlist and it's content. This can NOT be undone."
msgstr ""
-#: ../melon/playlist/__init__.py:117
+#: ../melon/playlist/__init__.py:125
msgid "Close"
msgstr ""
-#: ../melon/playlist/__init__.py:117
+#: ../melon/playlist/__init__.py:125
msgid "Close without changing anything"
msgstr ""
-#: ../melon/playlist/__init__.py:150
+#: ../melon/playlist/__init__.py:158
msgid "Do you really want to delete this playlist?"
msgstr ""
-#: ../melon/playlist/__init__.py:151
+#: ../melon/playlist/__init__.py:159
msgid "This cannot be undone"
msgstr ""
-#: ../melon/playlist/__init__.py:155 ../melon/playlist/create.py:47
-#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:174
-#: ../melon/widgets/preferencerow.py:217
+#: ../melon/playlist/__init__.py:163 ../melon/playlist/create.py:47
+#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:175
+#: ../melon/widgets/preferencerow.py:218
msgid "Cancel"
msgstr ""
-#: ../melon/playlist/__init__.py:155
+#: ../melon/playlist/__init__.py:163
msgid "Do not delete the playlist"
msgstr ""
-#: ../melon/playlist/__init__.py:156 ../melon/widgets/preferencerow.py:206
-#: ../melon/widgets/preferencerow.py:218
+#: ../melon/playlist/__init__.py:164 ../melon/widgets/preferencerow.py:207
+#: ../melon/widgets/preferencerow.py:219
msgid "Delete"
msgstr ""
-#: ../melon/playlist/__init__.py:156
+#: ../melon/playlist/__init__.py:164
msgid "Delete this playlist"
msgstr ""
@@ 428,7 524,7 @@ msgstr ""
msgid "Do not create playlist"
msgstr ""
-#: ../melon/playlist/create.py:48 ../melon/widgets/preferencerow.py:175
+#: ../melon/playlist/create.py:48 ../melon/widgets/preferencerow.py:176
msgid "Create"
msgstr ""
@@ 462,24 558,24 @@ msgstr ""
msgid "Add to Playlist"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:27
+#: ../melon/servers/invidious/__init__.py:32
msgid "Open source alternative front-end to YouTube"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:32
+#: ../melon/servers/invidious/__init__.py:37
msgid "Instance"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:33
+#: ../melon/servers/invidious/__init__.py:38
msgid ""
"See https://docs.invidious.io/instances/ for a list of available instances"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:44
+#: ../melon/servers/invidious/__init__.py:49
msgid "Trending"
msgstr ""
-#: ../melon/servers/invidious/__init__.py:45
+#: ../melon/servers/invidious/__init__.py:50
msgid "Popular"
msgstr ""
@@ 619,54 715,54 @@ msgid ""
"Disabled servers won't show up in the browser or on the local/home screen"
msgstr ""
-#: ../melon/widgets/preferencerow.py:115
+#: ../melon/widgets/preferencerow.py:116
msgid "Add"
msgstr ""
-#: ../melon/widgets/preferencerow.py:129
+#: ../melon/widgets/preferencerow.py:130
msgid "Move up"
msgstr ""
-#: ../melon/widgets/preferencerow.py:140
+#: ../melon/widgets/preferencerow.py:141
msgid "Move down"
msgstr ""
-#: ../melon/widgets/preferencerow.py:149
+#: ../melon/widgets/preferencerow.py:150
msgid "Remove from list"
msgstr ""
-#: ../melon/widgets/preferencerow.py:162
+#: ../melon/widgets/preferencerow.py:163
msgid "Add Item"
msgstr ""
-#: ../melon/widgets/preferencerow.py:165
+#: ../melon/widgets/preferencerow.py:166
msgid "Create a new list entry"
msgstr ""
-#: ../melon/widgets/preferencerow.py:166
+#: ../melon/widgets/preferencerow.py:167
msgid "Enter the new value here"
msgstr ""
-#: ../melon/widgets/preferencerow.py:169
+#: ../melon/widgets/preferencerow.py:170
msgid "Value"
msgstr ""
-#: ../melon/widgets/preferencerow.py:209
+#: ../melon/widgets/preferencerow.py:210
msgid "Do you really want to delete this item?"
msgstr ""
-#: ../melon/widgets/preferencerow.py:210
+#: ../melon/widgets/preferencerow.py:211
msgid "You won't be able to restore it afterwards"
msgstr ""
-#: ../melon/widgets/preferencerow.py:217
+#: ../melon/widgets/preferencerow.py:218
msgid "Do not remove item"
msgstr ""
-#: ../melon/widgets/preferencerow.py:218
+#: ../melon/widgets/preferencerow.py:219
msgid "Remove item from list"
msgstr ""
-#: ../melon/window.py:76
+#: ../melon/window.py:84
msgid "Stream videos on the go"
msgstr ""