Compare commits

..
3 Commits
Author SHA1 Message Date
Jonah Brüchert 5ae78302af Update deps 2022-04-24 20:40:49 +02:00
Jonah Brüchert 7ec01c5854 Add library feature 2022-03-06 14:20:17 +01:00
Jonah Brüchert 2ae7ce866a Import QPersistentData 2022-03-06 14:13:27 +01:00
63 changed files with 667 additions and 7049 deletions

No files matched your search

+1 -1
View File
@@ -3,4 +3,4 @@
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
include:
- 'https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml'
- 'https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-reuse.yml'
+3 -4
View File
@@ -8,7 +8,7 @@ project(audiotube)
include(FeatureSummary)
set(PROJECT_VERSION "22.04")
set(PROJECT_VERSION "22.02")
set(QT5_MIN_VERSION 5.15)
set(KF5_MIN_VERSION 5.81)
@@ -33,15 +33,14 @@ ecm_setup_version(${PROJECT_VERSION}
kde_enable_exceptions()
find_package(Qt5 ${QT5_MIN_VERSION} REQUIRED COMPONENTS Core Gui Qml QuickControls2 Svg Sql)
find_package(Qt5 ${QT5_MIN_VERSION} REQUIRED COMPONENTS Core Gui Qml QuickControls2 Svg)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Kirigami2 I18n CoreAddons Crash)
find_package(pybind11 REQUIRED)
find_package(Ytdlp REQUIRED RUNTIME)
find_package(YTMusicAPI REQUIRED RUNTIME)
ki18n_install(po)
add_subdirectory(src)
add_subdirectory(qpersistentdata)
install(PROGRAMS org.kde.audiotube.desktop DESTINATION ${KDE_INSTALL_APPDIR})
install(FILES org.kde.audiotube.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
+7 -7
View File
@@ -7,13 +7,8 @@
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/9a/bf/1bc7e3096ddc2c398b3d04176530a9c02efe08546d9730c9eef0b07a0a43/yt_dlp-2022.5.18-py2.py3-none-any.whl",
"sha256": "deec1009442312c1e2ee5298966842194d0e950b433f0d4fc844ef464b9c32a7"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/11/dd/e015f3780f42dd9af62cf0107b44ea1298926627ecd70c17b0e484e95bcd/certifi-2022.5.18.1-py3-none-any.whl",
"sha256": "f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"
"url": "https://files.pythonhosted.org/packages/37/45/946c02767aabb873146011e665728b680884cd8fe70dde973c640e45b775/certifi-2021.10.8-py2.py3-none-any.whl",
"sha256": "d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
},
{
"type": "file",
@@ -25,6 +20,11 @@
"url": "https://files.pythonhosted.org/packages/16/b3/f7aa8edf2ff4495116f95fd442b2a346aa55d1d46313143c8814886dbcdb/mutagen-1.45.1-py3-none-any.whl",
"sha256": "9c9f243fcec7f410f138cb12c21c84c64fde4195481a30c9bfb05b5f003adfed"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/6e/77/efb8398b88e51b5d81ec5fefe1c3ea69e775a6f8fef06654be840d22b433/yt_dlp-2022.4.8-py2.py3-none-any.whl",
"sha256": "6edefe326b1e1478fdbe627a66203e5248a6b0dd50c101e682cf700ab70cdf72"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/2a/18/70c32fe9357f3eea18598b23aa9ed29b1711c3001835f7cf99a9818985d0/Brotli-1.0.9.zip",
+9 -9
View File
@@ -7,13 +7,18 @@
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/ec/03/062e6444ce4baf1eac17a6a0ebfe36bb1ad05e1df0e20b110de59c278498/urllib3-1.26.9-py2.py3-none-any.whl",
"sha256": "44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"
"url": "https://files.pythonhosted.org/packages/cb/58/834a6445479c72544d9285badce0a58650520c8ba5adfae7b98e61d133bb/ytmusicapi-0.21.0-py3-none-any.whl",
"sha256": "29d8d44e1911458041882a453b05c37021ff850757c648f93a45d1775dddbae2"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/11/dd/e015f3780f42dd9af62cf0107b44ea1298926627ecd70c17b0e484e95bcd/certifi-2022.5.18.1-py3-none-any.whl",
"sha256": "f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"
"url": "https://files.pythonhosted.org/packages/37/45/946c02767aabb873146011e665728b680884cd8fe70dde973c640e45b775/certifi-2021.10.8-py2.py3-none-any.whl",
"sha256": "d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/ec/03/062e6444ce4baf1eac17a6a0ebfe36bb1ad05e1df0e20b110de59c278498/urllib3-1.26.9-py2.py3-none-any.whl",
"sha256": "44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"
},
{
"type": "file",
@@ -25,11 +30,6 @@
"url": "https://files.pythonhosted.org/packages/2d/61/08076519c80041bc0ffa1a8af0cbd3bf3e2b62af10435d269a9d0f40564d/requests-2.27.1-py2.py3-none-any.whl",
"sha256": "f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/0e/5a/4a5316bddbb697d4b1787159291edfeffd10f73c08b59c7248b15291b601/ytmusicapi-0.22.0-py3-none-any.whl",
"sha256": "d042520f3f76eac2c1498130dbc4e8a4af21ca73496590a5ff054fc4da0af1d8"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/04/a2/d918dcd22354d8958fe113e1a3630137e0fc8b44859ade3063982eacd2a4/idna-3.3-py3-none-any.whl",
+1 -18
View File
@@ -8,7 +8,6 @@ SPDX-License-Identifier: CC0-1.0
<id>org.kde.audiotube</id>
<name>AudioTube</name>
<name xml:lang="ar">تيوب الصوتي</name>
<name xml:lang="az">AudioTube</name>
<name xml:lang="ca">AudioTube</name>
<name xml:lang="ca-valencia">AudioTube</name>
<name xml:lang="cs">AudioTube</name>
@@ -30,13 +29,11 @@ SPDX-License-Identifier: CC0-1.0
<name xml:lang="sk">AudioTube</name>
<name xml:lang="sl">AudioTube</name>
<name xml:lang="sv">AudioTube</name>
<name xml:lang="tr">AudioTube</name>
<name xml:lang="uk">AudioTube</name>
<name xml:lang="x-test">xxAudioTubexx</name>
<name xml:lang="zh-CN">AudioTube</name>
<summary>Convergent YouTube Music client</summary>
<summary xml:lang="ar">عميل موسيقى يوتيوب متعدد المنصات</summary>
<summary xml:lang="az">Birləşmiş YouTube Musiqi müştərisi</summary>
<summary xml:lang="ca">Client convergent de música de YouTube</summary>
<summary xml:lang="ca-valencia">Client convergent de música de YouTube</summary>
<summary xml:lang="de">Konvergentes YouTube-Musikprogramm</summary>
@@ -55,7 +52,6 @@ SPDX-License-Identifier: CC0-1.0
<summary xml:lang="ro">Client convergent de muzică pentru YouTube</summary>
<summary xml:lang="sl">Konvergentni odjemalec glasbe YouTube</summary>
<summary xml:lang="sv">Konvergent YouTube-musikprogram</summary>
<summary xml:lang="tr">Yakınsak YouTube Müzik istemcisi</summary>
<summary xml:lang="uk">Зручний музичний клієнт YouTube</summary>
<summary xml:lang="x-test">xxConvergent YouTube Music clientxx</summary>
<summary xml:lang="zh-CN">桌面和移动设备通用 YouTube Music 客户端</summary>
@@ -63,7 +59,6 @@ SPDX-License-Identifier: CC0-1.0
<project_license>GPL-2.0+</project_license>
<developer_name>KDE Community</developer_name>
<developer_name xml:lang="ar">مجتمع كدي</developer_name>
<developer_name xml:lang="az">KDE İcması</developer_name>
<developer_name xml:lang="ca">La comunitat KDE</developer_name>
<developer_name xml:lang="ca-valencia">La comunitat KDE</developer_name>
<developer_name xml:lang="cs">Komunita KDE</developer_name>
@@ -85,22 +80,12 @@ SPDX-License-Identifier: CC0-1.0
<developer_name xml:lang="sk">KDE komunita</developer_name>
<developer_name xml:lang="sl">Skupnost KDE</developer_name>
<developer_name xml:lang="sv">KDE-gemenskapen</developer_name>
<developer_name xml:lang="tr">KDE Topluluğu</developer_name>
<developer_name xml:lang="uk">Спільнота KDE</developer_name>
<developer_name xml:lang="x-test">xxKDE Communityxx</developer_name>
<developer_name xml:lang="zh-CN">KDE 社区</developer_name>
<content_rating type="oars-1.0"/>
<url type="homepage">https://apps.kde.org/en/audiotube</url>
<releases>
<release version="22.04" date="2022-04-26">
<url>https://www.plasma-mobile.org/2022/04/26/plasma-mobile-gear-22-04/</url>
<description>
<ul>
<li>Update the version of ytmusicapi</li>
<li>General code-refactoring and translation updates</li>
</ul>
</description>
</release>
<release version="22.02" date="2022-02-09">
<url>https://www.plasma-mobile.org/2022/02/09/plasma-mobile-gear-22-02/</url>
<description>
@@ -133,9 +118,8 @@ SPDX-License-Identifier: CC0-1.0
<description>
<p>AudioTube can search YouTube Music, list albums and artists, play automatically generated playlists, albums and allows to put your own playlist together.</p>
<p xml:lang="ar">يمكن لتيوب الصوتي البحث في موسيقى يوتيوب، وعرض الألبومات والفنانين، وتشغيل القوائم والألبومات المولدة تلقائيًا، ويسمح لك بوضع قائمة التشغيل الخاصة بك معًا.</p>
<p xml:lang="az">AudioTube YouTube Musiqi, albomların və ifaçıların siyahısı üzrə axtarış etməyə, yaradılmış mahnı siyahısı və albomları avtomatik oxutmağa və öz mahnı siyahınızı yaratmağa imkan verir.</p>
<p xml:lang="ca">L'AudioTube pot cercar música a YouTube, llistar àlbums i artistes, reproduir llistes de reproducció generades automàticament, àlbums i permet crear la vostra pròpia llista de reproducció.</p>
<p xml:lang="ca-valencia">L'AudioTube pot buscar música a YouTube, llistar àlbums i artistes, reproduir llistes de reproducció generades automàticament, àlbums i permet crear la vostra pròpia llista de reproducció.</p>
<p xml:lang="ca-valencia">L'AudioTube pot cercar música a YouTube, llistar àlbums i artistes, reproduir llistes de reproducció generades automàticament, àlbums i permet crear la vostra pròpia llista de reproducció.</p>
<p xml:lang="de">AudioTube kann Musik auf YouTube durchsuchen, Alben und Interpreten auflisten, automatisch generierte Wiedergabelisten und Alben abspielen und erlaubt es, eine eigene Wiedergabeliste zusammenzustellen.</p>
<p xml:lang="en-GB">AudioTube can search YouTube Music, list albums and artists, play automatically generated playlists, albums and allows to put your own playlist together.</p>
<p xml:lang="es">AudioTube puede buscar música de YouTube, listar álbumes y artistas, reproducir las listas de reproducción generadas, álbumes y le permite crear su propia lista de reproducción.</p>
@@ -151,7 +135,6 @@ SPDX-License-Identifier: CC0-1.0
<p xml:lang="pt-BR">O AudioTube pode pesquisar no YouTube Music, listar álbuns e artistas, rodar listas de reprodução geradas automaticamente, álbuns inteiros, e criar a sua própria lista de reprodução.</p>
<p xml:lang="sl">AudioTube lahko išče po YouTube Music, izdela sezname albumov in avtorjev, samodejno predvaja generirane sezname, albume in sestavlja vaše sezname predvajanja.</p>
<p xml:lang="sv">AudioTube kan söka på YouTube Music, lista album och artister, spela upp automatiskt genererade spellistor, albums och låter dig sammanställa egna spellistor.</p>
<p xml:lang="tr">AudioTube, YouTube Müzik'te arama yapabilir; albümleri, sanatçıları listeler; kendiliğinden oluşturulmuş çalma listelerini, albümleri çalar ve kendi çalma listenizi oluşturmanıza izin verir.</p>
<p xml:lang="uk">AudioTube може виконувати пошук на YouTube Music, показувати списки альбомів та виконавців, відтворювати створені автоматично списки відтворення, альбоми та надає вам змогу створювати власні списки відворення.</p>
<p xml:lang="x-test">xxAudioTube can search YouTube Music, list albums and artists, play automatically generated playlists, albums and allows to put your own playlist together.xx</p>
<p xml:lang="zh-CN">AudioTube 可以搜索 YouTube Music 的内容,列出专辑和艺人,播放自动生成的播放列表,还可以自行制作播放列表。</p>
-4
View File
@@ -1,7 +1,6 @@
[Desktop Entry]
Name=AudioTube
Name[ar]=تيوب الصوتي
Name[az]=AudioTube
Name[ca]=AudioTube
Name[ca@valencia]=AudioTube
Name[cs]=AudioTube
@@ -23,13 +22,11 @@ Name[ro]=AudioTube
Name[sk]=AudioTube
Name[sl]=AudioTube
Name[sv]=AudioTube
Name[tr]=AudioTube
Name[uk]=AudioTube
Name[x-test]=xxAudioTubexx
Name[zh_CN]=AudioTube
Comment=YouTube Music client
Comment[ar]=عميل يوتيوب ميوزيك
Comment[az]=YouTube Musiqi müştərisi
Comment[ca]=Client de música de YouTube
Comment[ca@valencia]=Client de música de YouTube
Comment[cs]=Hudební klient YouTube
@@ -51,7 +48,6 @@ Comment[ro]=Client de muzică pentru YouTube
Comment[sk]=Hudobný klient YouTube
Comment[sl]=Glasbeni odjemalec Youtube
Comment[sv]=YouTube-musikprogram
Comment[tr]=YouTube Müzik istemcisi
Comment[uk]=Музичний клієнт YouTube
Comment[x-test]=xxYouTube Music clientxx
Comment[zh_CN]=YouTube Music 客户端
-169
View File
@@ -1,169 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Zayed Al-Saidi <[email protected]>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-01-21 22:52+0400\n"
"Last-Translator: Zayed Al-Saidi <[email protected]>\n"
"Language-Team: ar\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"X-Generator: Lokalize 21.07.70\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "زايد السعيدي"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "شغّل"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "شغل التالي"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "أضف إلى قائمة التّشغيل"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr "تشغيل الفيديو غير مدعوم حتى الآن. هل تريد تشغيل صوت فقط من \"%1\"؟"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "الألبومات"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "فردي"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "أغاني"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "الفيديوهات"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "حسنًا"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "ألغِ"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "تيوب الصوتي"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "لا يوجد وسائط تعمل"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "أزل المسار"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "لا يوجد وسائط تعمل"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "اخلط"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "الفنّانون"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "قوائم التّشغيل"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "مجهول"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "شغل التالي"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "راديو"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "اعثر على موسيقى على موسيقى يوتيوب"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "ابحث"
#~ msgid "Clear"
#~ msgstr "امسح"
#~ msgid "Pause"
#~ msgstr "ألبث"
#~ msgid "Expand"
#~ msgstr "وسع"
-170
View File
@@ -1,170 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Kheyyam Gojayev <[email protected]>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-04-22 18:44+0400\n"
"Last-Translator: Kheyyam Gojayev <[email protected]>\n"
"Language-Team: Azerbaijani <[email protected]>\n"
"Language: az\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 21.12.3\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Xəyyam Qocayev"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Başladın"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Sonrakını oxudun"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Mahnı siyahısına əlavə edin"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Video göstərilməsi hələlik dəstəklənmir. Siz yalnız \"%1\" videosunun səsini "
"oynatmaq istəyirsiniz?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albomlar"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Musiqilər"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Mahnılar"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videolar"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OLDU"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "İmtina"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Media faylı oynadılmır"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Mahnını silin"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Media faylı oynadılmır"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Qarışıq"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "İfaçılar"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Mahnı siyahıları"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Bilinməyən"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Sonrakını başladın"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Musiqini YouTube Musiqi-də tapın"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Axtarın"
#~ msgid "Clear"
#~ msgstr "Təmizləyin"
#~ msgid "Pause"
#~ msgstr "Fasilə"
#~ msgid "Expand"
#~ msgstr "Açmaq"
-163
View File
@@ -1,163 +0,0 @@
# Translation of audiotube.po to Catalan
# Copyright (C) 2021-2022 This_file_is_part_of_KDE
# This file is distributed under the license LGPL version 2.1 or
# version 3 or later versions approved by the membership of KDE e.V.
#
# Antoni Bella Pérez <[email protected]>, 2021.
# Josep M. Ferrer <[email protected]>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-24 08:45+0200\n"
"Last-Translator: Josep M. Ferrer <[email protected]>\n"
"Language-Team: Catalan <[email protected]>\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 20.12.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Antoni Bella"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Reprodueix"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Reprodueix el següent"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Afegeix a la llista de reproducció"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Encara no s'admet la reproducció de vídeo. Voleu reproduir només l'àudio de "
"«%1»?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Àlbums"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Individuals"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Cançons"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Vídeos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "D'acord"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Cancel·la"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Preferides"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "Les més reproduïdes"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr "Ara s'està reproduint"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr "Cua"
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Elimina la pista"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "No s'està reproduint cap suport"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Barreja"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistes"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Llistes de reproducció"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Desconeguda"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Reprodueix el següent"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Ràdio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Cerca a la Música de Youtube"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Cerca"
-172
View File
@@ -1,172 +0,0 @@
# Translation of audiotube.po to Catalan (Valencian)
# Copyright (C) 2021 This_file_is_part_of_KDE
# This file is distributed under the license LGPL version 2.1 or
# version 3 or later versions approved by the membership of KDE e.V.
#
# Antoni Bella Pérez <[email protected]>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2021-12-05 16:03+0100\n"
"Last-Translator: Antoni Bella Pérez <[email protected]>\n"
"Language-Team: Catalan <[email protected]>\n"
"Language: ca@valencia\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 21.11.90\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Antoni Bella"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Reprodueix"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Reprodueix el següent"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Afig a la llista de reproducció"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Encara no s'admet la reproducció de vídeo. Voleu reproduir només l'àudio de "
"«%1»?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Àlbums"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Individuals"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Cançons"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Vídeos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "D'acord"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Cancel·la"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "No s'està reproduint cap suport"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Elimina la pista"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "No s'està reproduint cap suport"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Barreja"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistes"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Llistes de reproducció"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Desconeguda"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Reprodueix el següent"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Ràdio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Busca a la Música de Youtube"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Busca"
#~ msgid "Clear"
#~ msgstr "Neteja"
#~ msgid "Pause"
#~ msgstr "Pausa"
#~ msgid "Expand"
#~ msgstr "Expandeix"
-170
View File
@@ -1,170 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
# Vit Pelcak <[email protected]>, 2021, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-01-11 17:36+0100\n"
"Last-Translator: Vit Pelcak <[email protected]>\n"
"Language-Team: Czech <[email protected]>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Lokalize 21.12.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Vít Pelčák"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Přehrát"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Přehrát následující"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Přidat do seznamu skladeb"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Přehrávání videa ještě není podporováno. Chcete z \"%1\" přehrávat pouze "
"zvuk?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Alba"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Samotné"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Písně"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videa"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Zrušit"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Nepřehrává se žádné médium"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Odstranit skladbu"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Nepřehrává se žádné médium"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Zamíchat"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Umělci"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Seznamy skladeb"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Neznámý"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Přehrát následující"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Rádio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Najít hudbu na Hudba YouTube"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Hledat"
#~ msgid "Clear"
#~ msgstr "Vyprázdnit"
#~ msgid "Pause"
#~ msgstr "Pozastavit"
#~ msgid "Expand"
#~ msgstr "Rozvinout"
-174
View File
@@ -1,174 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
# Burkhard Lück <[email protected]>, 2021.
# Frederik Schwarzer <[email protected]>, 2021, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-02-20 10:37+0100\n"
"Last-Translator: Frederik Schwarzer <[email protected]>\n"
"Language-Team: German <[email protected]>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 21.08.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Deutsches KDE-Übersetzerteam"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Wiedergabe"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Nächste Wiedergabe"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Zur Wiedergabeliste hinzufügen"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Die Video-Wiedergabe wird noch nicht unterstützt. Möchten Sie nur die "
"Audiospur von „%1“ abspielen?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Alben"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Singles"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Songs"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Abbrechen"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Es werden keine Medien wiedergegeben"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Stück entfernen"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Es werden keine Medien wiedergegeben"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Zufällig"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Interpreten"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Wiedergabelisten"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Unbekannt"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Nächste Wiedergabe"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Musik auf YouTube suchen"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Suchen"
#~ msgid "Clear"
#~ msgstr "Löschen"
#~ msgid "Pause"
#~ msgstr "Pause"
#~ msgid "Expand"
#~ msgstr "Erweitern"
#~ msgid "Play only Audio"
#~ msgstr "Nur Audio abspielen"
-173
View File
@@ -1,173 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Steve Allewell <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-01-01 15:21+0000\n"
"Last-Translator: Steve Allewell <[email protected]>\n"
"Language-Team: British English <[email protected]>\n"
"Language: en_GB\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 21.12.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Steve Allewell"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Play"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Play Next"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Add to Playlist"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albums"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Singles"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Songs"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Cancel"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "No media playing"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Remove Track"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "No media playing"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Shuffle"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artists"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Playlists"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Unknown"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Play next"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Find music on YouTube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Search"
#~ msgid "Clear"
#~ msgstr "Clear"
#~ msgid "Pause"
#~ msgstr "Pause"
#~ msgid "Expand"
#~ msgstr "Expand"
#~ msgid "Play only Audio"
#~ msgstr "Play only Audio"
-174
View File
@@ -1,174 +0,0 @@
# Spanish translations for audiotube.po package.
# Copyright (C) 2021 This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Automatically generated, 2021.
# Eloy Cuadra <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-25 00:18+0200\n"
"Last-Translator: Eloy Cuadra <[email protected]>\n"
"Language-Team: Spanish <[email protected]>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 22.04.1\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Eloy Cuadra"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Reproducir"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Reproducir siguiente"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Añadir a la lista de reproducción"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"La reproducción de vídeo aún no está permitida. ¿Desea reproducir solo el "
"sonido de «%1»?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Álbumes"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Sencillos"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Canciones"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Vídeos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "Aceptar"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Cancelar"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Favoritos"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "Más reproducidos"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr "Reproduciendo"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr "Cola"
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Eliminar pista"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Ningún medio en reproducción"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Desordenar"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistas"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Listas de reproducción"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Desconocido"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Reproducir siguiente"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Encuentre música en YouTube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Buscar"
#~ msgid "Clear"
#~ msgstr "Borrar todo"
#~ msgid "Pause"
#~ msgstr "Pausar"
#~ msgid "Expand"
#~ msgstr "Expandir"
#~ msgid "Play only Audio"
#~ msgstr "Reproducir solo el sonido"
-176
View File
@@ -1,176 +0,0 @@
# Translation for audiotube.po to Euskara/Basque (eu).
# Copyright (C) 2021-2022, This file is copyright:
# This file is distributed under the same license as the audiotube package.
# KDE euskaratzeko proiektuko arduraduna <[email protected]>.
#
# Translators:
# Iñigo Salvador Azurmendi <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-02-21 18:58+0100\n"
"Last-Translator: Iñigo Salvador Azurmendi <[email protected]>\n"
"Language-Team: Basque <[email protected]>\n"
"Language: eu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 21.12.2\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Iñigo Salvador Azurmendi"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Jo"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Jo hurrengoa"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Gehitu jotze-zerrendara"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Oraindik ez dago bideoa atzera jotzeko euskarririk. «%1»(r)en audioa "
"bakarrik jo nahi duzu?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albumak"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Banakoa"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Abestiak"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Bideoak"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "Ados"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Utzi"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Ez da euskarririk jotzen ari"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Kendu pista"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Ez da euskarririk jotzen ari"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Nahastu"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistak"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Jotze-zerrendak"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Ezezaguna"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Jo hurrengoa"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Irratia"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Aurkitu musika «Youtube Music»en"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Bilatu"
#~ msgid "Clear"
#~ msgstr "Garbitu"
#~ msgid "Pause"
#~ msgstr "Eten"
#~ msgid "Expand"
#~ msgstr "Zabaldu"
#~ msgid "Play only Audio"
#~ msgstr "Audio bakarrik jo"
-172
View File
@@ -1,172 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
# Tommi Nieminen <[email protected]>, 2021, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-01-11 22:47+0200\n"
"Last-Translator: Tommi Nieminen <[email protected]>\n"
"Language-Team: Finnish <[email protected]>\n"
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 20.04.2\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Tommi Nieminen"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Toista"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Toista seuraava"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Lisää soittolistaan"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Videotoistoa ei vielä tueta. Haluatko toistaa videosta ”%1” vain äänen?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albumit"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Singlet"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Kappaleet"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videot"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Peru"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Mitään ei toisteta"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Poista raita"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Mitään ei toisteta"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Sekoita"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistit"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Soittolistat"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Tuntematon"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Toista seuraava"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Etsi musiikkia Youtube Musicista"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Etsi"
#~ msgid "Clear"
#~ msgstr "Tyhjennä"
#~ msgid "Pause"
#~ msgstr "Tauko"
#~ msgid "Expand"
#~ msgstr "Laajenna"
#~ msgid "Play only Audio"
#~ msgstr "Toista vain ääni"
-170
View File
@@ -1,170 +0,0 @@
# Xavier Besnard <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-23 20:05+0200\n"
"Last-Translator: Xavier Besnard <[email protected]>\n"
"Language-Team: French <[email protected]>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Lokalize 22.04.1\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Xavier Besnard"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Lire"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Lire le suivant"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Ajouter à la liste de lecture"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"La lecture de vidéos n'est pas encore prise en charge. Voulez-vous vraiment "
"lire uniquement l'audio de « %1 » ?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albums"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Titres uniques"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Chansons"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Vidéos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "Ok"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Annuler"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Favoris"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "Les plus lus"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Aucun média en lecture"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Supprimer une piste"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Aucun média en lecture"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Mélanger"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistes"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Listes de lecture"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Inconnu"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Lire le suivant"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Rechercher de la musique sur « YouTube Music »"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Rechercher"
#~ msgid "Clear"
#~ msgstr "Effacer"
#~ msgid "Pause"
#~ msgstr "Pause"
#~ msgid "Expand"
#~ msgstr "Développer"
#~ msgid "Play only Audio"
#~ msgstr "Ne lire que l'audio"
-172
View File
@@ -1,172 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Raghavendra Kamath <[email protected]>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2021-09-17 20:09+0530\n"
"Last-Translator: Raghavendra Kamath <[email protected]>\n"
"Language-Team: kde-hindi\n"
"Language: hi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Lokalize 21.08.1\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "राघवेंद्र कामत"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "बजाएँ"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "अगला बजाएँ"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "गीत-सूची में जोड़ें"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"वीडियो चलाना अभी तक समर्थित नहीं है। क्या आप केवल \"%1\" का ध्वनी चलाना चाहते हैं?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "एल्बम्स"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "एक गीत"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "गीत"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "वीडियो"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr ""
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr ""
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "ओडियो-ट्यूब"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "कोई मीडिया नहीं बजा रहा है"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "गाना हटाएँ"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "कोई मीडिया नहीं बजा रहा है"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "फेंटें"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "कलाकार"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "गीत-सूचीयाँ"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "अज्ञात"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "अगला बजाएँ"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "रेडियो"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "यूट्यूब संगीत पर संगीत ढूंढें"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "खोजें"
#~ msgid "Clear"
#~ msgstr "साफ करें"
#~ msgid "Pause"
#~ msgstr "रोकें"
#~ msgid "Expand"
#~ msgstr "विस्तृत करें"
#~ msgid "Play only Audio"
#~ msgstr "केवल ध्वनी चलाएँ"
-173
View File
@@ -1,173 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
# Vincenzo Reale <[email protected]>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2021-12-06 02:46+0100\n"
"Last-Translator: Vincenzo Reale <[email protected]>\n"
"Language-Team: Italian <[email protected]>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 21.08.3\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Vincenzo Reale"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Riproduci"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Riproduci successivo"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Aggiungi alla scaletta"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"La riproduzione dei video non è ancora supportata. Vuoi riprodurre solo "
"l'audio di «%1»?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Album"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Singoli"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Brani"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Video"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Annulla"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Nessun supporto in riproduzione"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Rimuovi traccia"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Nessun supporto in riproduzione"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Mescola"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artisti"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Scalette"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Sconosciuto"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Riproduci successivo"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Trova musica su Youtube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Cerca"
#~ msgid "Clear"
#~ msgstr "Pulisci"
#~ msgid "Pause"
#~ msgstr "Pausa"
#~ msgid "Expand"
#~ msgstr "Espandi"
#~ msgid "Play only Audio"
#~ msgstr "Riproduci solo l'audio"
-171
View File
@@ -1,171 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
# Shinjo Park <[email protected]>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2021-12-08 00:45+0100\n"
"Last-Translator: Shinjo Park <[email protected]>\n"
"Language-Team: Korean <[email protected]>\n"
"Language: ko\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Lokalize 21.08.1\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "박신조"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "재생"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "다음 재생"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "재생 목록에 추가"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr "비디오 재생은 지원하지 않습니다. \"%1\"의 오디오만 재생하시겠습니까?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "앨범"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "싱글"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "곡"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "비디오"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "확인"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "취소"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "재생 중인 미디어 없음"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "트랙 삭제"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "재생 중인 미디어 없음"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "무순서 재생"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "아티스트"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "재생 목록"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "알 수 없음"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "다음 재생"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "라디오"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "YouTube Music에서 음악 찾기"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "검색"
#~ msgid "Clear"
#~ msgstr "지우기"
#~ msgid "Pause"
#~ msgstr "일시 정지"
#~ msgid "Expand"
#~ msgstr "확장"
#~ msgid "Play only Audio"
#~ msgstr "오디오만 재생"
-172
View File
@@ -1,172 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Freek de Kruijf <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-24 10:48+0200\n"
"Last-Translator: Freek de Kruijf <[email protected]>\n"
"Language-Team: \n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 22.04.1\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Freek de Kruijf - 2021 t/m 2022"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Afspelen"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Volgende afspelen"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Aan afspeellijst toevoegen"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Afspelen van video wordt nog niet ondersteund. Wilt u alleen het geluid van "
"\"%1\" afspelen?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albums"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Enkelvoudige"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Songs"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Video's"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Annuleren"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Favorieten"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "Meest afgespeeld"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr "Speelt nu"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr "Wachtrij"
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Track verwijderen"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Er speelt geen medium"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Willekeurig afspelen"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artiesten"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Afspeellijsten"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Onbekend"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Volgende afspelen"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Muziek zoeken op YouTube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Zoeken"
#~ msgid "Clear"
#~ msgstr "Wissen"
#~ msgid "Pause"
#~ msgstr "Pauzeren"
#~ msgid "Expand"
#~ msgstr "Uitbreiden"
#~ msgid "Play only Audio"
#~ msgstr "Alleen geluid afspelen"
-171
View File
@@ -1,171 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# A S Alam <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-01-01 09:11-0800\n"
"Last-Translator: A S Alam <[email protected]>\n"
"Language-Team: Punjabi <[email protected]>\n"
"Language: pa\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 21.04.3\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "ਅਮਨਪਰੀਤ ਸਿੰਘ ਆਲਮ ੨੦੨੧"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "alam yellow @ gmail.com"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "ਚਲਾਓ"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "ਅਗਲਾ ਚਲਾਓ"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "ਪਲੇਅਲਿਸਟ ਵਿੱਚ ਜੋੜੋ"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr "ਵਿਡੀਓ ਪਲੇਅਬੈਕ ਹਾਲੇ ਸਹਾਇਕ ਨਹੀਂ ਹੈ। ਕੀ ਤੁਸੀਂ \"%1\" ਦਾ ਆਡੀਓ ਹੀ ਚਲਾਉਣਾ ਚਾਹੋਗੇ?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "ਐਲਬਮਾਂ"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "ਇਕੱਲੇ"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "ਗੀਤ"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "ਵਿਡੀਓ"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "ਠੀਕ ਹੈ"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "ਰੱਦ ਕਰੋ"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "ਆਡੀਓ-ਟਿਊਬ"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ ਚੱਲਦਾ"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "ਟਰੈਕ ਨੂੰ ਹਟਾਓ"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ ਚੱਲਦਾ"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "ਰਲਵੇਂ"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "ਕਲਾਕਾਰ"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "ਪਲੇਅਲਿਸਟਾਂ"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "ਅਣਪਛਾਤਾ"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "ਅਗਲਾ ਚਲਾਓ"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "ਰੇਡੀਓ"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "ਯੂਟਿਊਬ ਸੰਗੀਤ ਉੱਤੇ ਸੰਗੀਤ ਲੱਭੋ"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "ਖੋਜੋ"
#~ msgid "Clear"
#~ msgstr "ਮਿਟਾਓ"
#~ msgid "Pause"
#~ msgstr "ਵਿਰਾਮ"
#~ msgid "Expand"
#~ msgstr "ਫੈਲਾਓ"
#~ msgid "Play only Audio"
#~ msgstr "ਸਿਰਫ਼ ਆਡੀਓ ਹੀ ਚਲਾਓ"
-175
View File
@@ -1,175 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Łukasz Wojniłowicz <[email protected]>, 2021.
# Ignacy Kajdan <[email protected]>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2021-12-30 12:38+0100\n"
"Last-Translator: Łukasz Wojniłowicz <[email protected]>\n"
"Language-Team: Polish <[email protected]>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
"X-Generator: Lokalize 22.03.70\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Łukasz Wojniłowicz, Ignacy Kajdan"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected], [email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Odtwórz"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Odtwórz następny"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Dodaj do listy odtwarzania"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Odtwarzanie wideo nie jest jeszcze obsługiwane. Czy odtworzyć tylko dźwięk z "
"„%1”?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albumy"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Single"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Piosenki"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Filmy"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Anuluj"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Nic nie jest odtwarzane"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Usuń utwór"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Nic nie jest odtwarzane"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Wymieszaj"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Wykonawcy"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Listy odtwarzania"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Nieznany"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Odtwórz następny"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Znajdź muzykę w serwisie YouTube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Szukaj"
#~ msgid "Clear"
#~ msgstr "Wyczyść"
#~ msgid "Pause"
#~ msgstr "Wstrzymaj"
#~ msgid "Expand"
#~ msgstr "Rozwiń"
#~ msgid "Play only Audio"
#~ msgstr "Odtwórz tylko dźwięk"
-175
View File
@@ -1,175 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2021-09-04 18:29+0100\n"
"Last-Translator: José Nuno Coelho Pires <[email protected]>\n"
"Language-Team: Portuguese <[email protected]>\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-POFile-SpellExtra: Singles AudioTube YouTube Music\n"
"X-POFile-IgnoreConsistency: Singles\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "José Nuno Pires"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Reproduzir"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Reproduzir o Seguinte"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Adicionar à Lista de Reprodução"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"A reprodução de vídeos ainda não é suportada. Deseja reproduzir apenas o "
"áudio de \"%1\"?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Álbuns"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "'Singles'"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Músicas"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Vídeos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Cancelar"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Nada em reprodução"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Remover a Faixa"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Nada em reprodução"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Baralhar"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistas"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Listas de Reprodução"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Desconhecido"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Reproduzir o seguinte"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Rádio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Procurar música no YouTube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Procurar"
#~ msgid "Clear"
#~ msgstr "Limpar"
#~ msgid "Pause"
#~ msgstr "Pausa"
#~ msgid "Expand"
#~ msgstr "Expandir"
#~ msgid "Play only Audio"
#~ msgstr "Reproduzir só o Áudio"
-174
View File
@@ -1,174 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Luiz Fernando Ranghetti <[email protected]>, 2021.
# Thiago Masato Costa Sueto <[email protected]>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2021-12-09 10:13-0300\n"
"Last-Translator: Luiz Fernando Ranghetti <[email protected]>\n"
"Language-Team: Portuguese <[email protected]>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Lokalize 20.04.2\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Luiz Fernando Ranghetti"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Reproduzir"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Reproduzir próxima"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Adicionar à lista de reprodução"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"A reprodução de vídeos ainda não é suportada. Deseja reproduzir apenas o "
"áudio de \"%1\"?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Álbuns"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Singles"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Músicas"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Vídeos"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Cancelar"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Nenhuma mídia em reprodução"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Remover faixa"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Nenhuma mídia em reprodução"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Embaralhar"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artistas"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Listas de músicas"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Desconhecido"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Reproduzir próxima"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Rádio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Encontre músicas no YouTube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Pesquisar"
#~ msgid "Clear"
#~ msgstr "Limpar"
#~ msgid "Pause"
#~ msgstr "Pausar"
#~ msgid "Expand"
#~ msgstr "Expandir"
#~ msgid "Play only Audio"
#~ msgstr "Reproduzir apenas áudio"
-165
View File
@@ -1,165 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Alexander Yavorsky <[email protected]>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-10 21:39+0300\n"
"Last-Translator: Alexander Yavorsky <[email protected]>\n"
"Language-Team: Russian <[email protected]>\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Lokalize 21.08.3\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Александр Яворский"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Воспроизвести"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Воспроизвести следующий"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr ""
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Альбомы"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr ""
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr ""
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Видеозаписи"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "ОК"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Отмена"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Удалить дорожку"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr ""
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Перемешать"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr ""
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr ""
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr ""
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr ""
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Радио"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr ""
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Поиск"
#~ msgid "Clear"
#~ msgstr "Очистить"
#~ msgid "Pause"
#~ msgstr "Приостановить"
-167
View File
@@ -1,167 +0,0 @@
# translation of audiotube.po Slovak
# Roman Paholik <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-04-07 18:01+0200\n"
"Last-Translator: Roman Paholik <[email protected]>\n"
"Language-Team: Slovak <[email protected]>\n"
"Language: sk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 21.12.3\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Roman Paholík"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Prehrať"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, fuzzy, kde-format
#| msgid "Play"
msgid "Play Next"
msgstr "Prehrať"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Pridať do zoznamu skladieb"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albumy"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Samotné"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr ""
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videá"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "OK"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Zrušiť"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Neprehráva sa žiadne médium"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Neprehráva sa žiadne médium"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Zamiešať"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Interpreti"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Zoznamy skladieb"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Neznáme"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr ""
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Rádio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr ""
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Hľadať"
#~ msgid "Clear"
#~ msgstr "Vyčistiť"
#~ msgid "Pause"
#~ msgstr "Pozastaviť"
#~ msgid "Expand"
#~ msgstr "Rozvinúť"
-171
View File
@@ -1,171 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Matjaž Jeran <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-24 07:26+0200\n"
"Last-Translator: Matjaž Jeran <[email protected]>\n"
"Language-Team: Slovenian <[email protected]>\n"
"Language: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 21.12.2\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
"%100==4 ? 3 : 0);\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Matjaž Jeran"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Predvajaj"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Predvajaj naslednjo"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Dodaj v seznam predvajanja"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr "Video playback še ni podprt. Ali želite predvajati samo zvok \"%1\"?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albumi"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Singli"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Glasba"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videposnetki"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "V redu"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Prekliči"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Priljubljeni"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "Največkrat predvajani"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr "Pravkar predvajano"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr "Čakalna vrsta"
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Odstrani sled"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Niče se ne predvaja"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Premešaj"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Avtorji"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Seznami predvajanja"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Neznano"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Predvajaj naslednjo"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Najdi glasbo na Youtube Music"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Išči"
#~ msgid "Clear"
#~ msgstr "Očisti"
#~ msgid "Pause"
#~ msgstr "Premor"
#~ msgid "Expand"
#~ msgstr "Razširi"
#~ msgid "Play only Audio"
#~ msgstr "Predvajaj samo zvok"
-171
View File
@@ -1,171 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Stefan Asserhäll <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-23 17:51+0200\n"
"Last-Translator: Stefan Asserhäll <[email protected]>\n"
"Language-Team: Swedish <[email protected]>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 20.08.1\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Stefan Asserhäll"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Spela"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Spela nästa"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Lägg till i spellista"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr "Videouppspelning stöds inte ännu. Vill du bara spela ljudet på \"%1\"?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Album"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Singlar"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Låtar"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videor"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "Ok"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Avbryt"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Favoriter"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "Mest spelade"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "Inga media spelar"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Ta bort spår"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Inga media spelar"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Blanda"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Artister"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Spellistor"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Okänd"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Spela nästa"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radio"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Sök efter musik på YouTube musik"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Sök"
#~ msgid "Clear"
#~ msgstr "Rensa"
#~ msgid "Pause"
#~ msgstr "Paus"
#~ msgid "Expand"
#~ msgstr "Expandera"
#~ msgid "Play only Audio"
#~ msgstr "Spela bara ljud"
-169
View File
@@ -1,169 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
#
# Emir SARI <[email protected]>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-24 11:59+0300\n"
"Last-Translator: Emir SARI <[email protected]>\n"
"Language-Team: Turkish <[email protected]>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Lokalize 22.04.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Emir SARI"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Çal"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Sonrakini Çal"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Çalma Listesine Ekle"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Video oynatımı henüz desteklenmiyor. \"%1\" videosunun yalnızca sesinin "
"çalınmasını ister misiniz?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Albümler"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Tekliler"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Şarkılar"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Videolar"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "Tamam"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "İptal"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Beğeniler"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "En Çok Çalınanlar"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr "Şimdi Çalınıyor"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr "Kuyruk"
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Parçayı Kaldır"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Ortam çalmıyor"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Karıştır"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Sanatçılar"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Çalma Listeleri"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Bilinmiyor"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Sonrakini çal"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Radyo"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "YouTube Müzik'te müzik bul"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Ara"
#~ msgid "Clear"
#~ msgstr "Temizle"
#~ msgid "Pause"
#~ msgstr "Duraklat"
#~ msgid "Expand"
#~ msgstr "Genişlet"
-173
View File
@@ -1,173 +0,0 @@
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the PACKAGE package.
#
# Yuri Chornoivan <[email protected]>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-24 08:21+0300\n"
"Last-Translator: Yuri Chornoivan <[email protected]>\n"
"Language-Team: Ukrainian <[email protected]>\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Lokalize 20.12.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Юрій Чорноіван"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "Відтворити"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "Відтворити наступну"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "Додати до списку відтворення"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"Підтримки відтворення відео ще не передбачено. Хочете, щоб було відтворено "
"лише звукову частину «%1»?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "Альбоми"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "Одинарні"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "Пісні"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "Відео"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "Гаразд"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "Скасувати"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "Улюблені"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "Часто слухали"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr "Зараз відтворюємо"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr "Додати до черги"
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "Вилучити композицію"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "Відтворення не відбувається"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "Перемішати"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "Виконавці"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "Списки відтворення"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "Невідомий"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "Відтворити наступну"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "Радіо"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "Шукати музику на сайті «Музика Youtube»"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "Пошук"
#~ msgid "Clear"
#~ msgstr "Спорожнити"
#~ msgid "Pause"
#~ msgstr "Призупинити"
#~ msgid "Expand"
#~ msgstr "Розгорнути"
#~ msgid "Play only Audio"
#~ msgstr "Відтворити лише звук"
-160
View File
@@ -1,160 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR This file is copyright:
# This file is distributed under the same license as the audiotube package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: audiotube\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-24 01:49+0000\n"
"Last-Translator: transxx.py program <[email protected]>\n"
"Language-Team: KDE Test Language <[email protected]>\n"
"Language: x-test\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "xxYour namesxx"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "xxYour emailsxx"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "xxPlayxx"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "xxPlay Nextxx"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "xxAdd to Playlistxx"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr ""
"xxVideo playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?xx"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "xxAlbumsxx"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "xxSinglesxx"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "xxSongsxx"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "xxVideosxx"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "xxOKxx"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "xxCancelxx"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr "xxFavouritesxx"
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr "xxMost playedxx"
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "xxAudioTubexx"
#: contents/ui/MaximizedPlayerPage.qml:86
#, kde-format
msgid "Now Playing"
msgstr "xxNow Playingxx"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr "xxQueuexx"
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "xxRemove Trackxx"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "xxNo media playingxx"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "xxShufflexx"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "xxArtistsxx"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "xxPlaylistsxx"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "xxUnknownxx"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "xxPlay nextxx"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "xxRadioxx"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "xxFind music on YouTube Musicxx"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "xxSearchxx"
-168
View File
@@ -1,168 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: kdeorg\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-05-25 00:46+0000\n"
"PO-Revision-Date: 2022-05-15 15:46\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: kdeorg\n"
"X-Crowdin-Project-ID: 269464\n"
"X-Crowdin-Language: zh-CN\n"
"X-Crowdin-File: /kf5-trunk/messages/audiotube/audiotube.pot\n"
"X-Crowdin-File-ID: 25474\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Qi Binye, Tyson Tan"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "[email protected], [email protected]"
#: contents/ui/AlbumPage.qml:19 contents/ui/PlaylistPage.qml:19
#, kde-format
msgid "Play"
msgstr "播放"
#: contents/ui/AlbumPage.qml:61 contents/ui/ArtistPage.qml:101
#: contents/ui/PlaylistPage.qml:67
#, kde-format
msgid "Play Next"
msgstr "播放下一首"
#: contents/ui/AlbumPage.qml:66 contents/ui/ArtistPage.qml:107
#: contents/ui/PlaylistPage.qml:72 contents/ui/SearchPage.qml:123
#, kde-format
msgid "Add to Playlist"
msgstr "添加到播放列表"
#: contents/ui/ArtistPage.qml:39 contents/ui/SearchPage.qml:67
#, kde-format
msgid ""
"Video playback is not supported yet. Do you want to play only the audio of "
"\"%1\"?"
msgstr "视频播放尚未被支持。您想要只播放“%1”中的音频吗?"
#: contents/ui/ArtistPage.qml:55 contents/ui/SearchPage.qml:25
#, kde-format
msgid "Albums"
msgstr "专辑"
#: contents/ui/ArtistPage.qml:57
#, kde-format
msgid "Singles"
msgstr "单曲"
#: contents/ui/ArtistPage.qml:59 contents/ui/SearchPage.qml:31
#, kde-format
msgid "Songs"
msgstr "曲目"
#: contents/ui/ArtistPage.qml:61 contents/ui/SearchPage.qml:33
#, kde-format
msgid "Videos"
msgstr "视频"
#: contents/ui/ConfirmationMessage.qml:16
#, kde-format
msgid "OK"
msgstr "确定"
#: contents/ui/ConfirmationMessage.qml:21
#, kde-format
msgid "Cancel"
msgstr "取消"
#: contents/ui/LibraryPage.qml:15
#, kde-format
msgid "Favourites"
msgstr ""
#: contents/ui/LibraryPage.qml:67
#, kde-format
msgid "Most played"
msgstr ""
#: contents/ui/main.qml:93
#, kde-format
msgid "AudioTube"
msgstr "AudioTube"
#: contents/ui/MaximizedPlayerPage.qml:86
#, fuzzy, kde-format
#| msgid "No media playing"
msgid "Now Playing"
msgstr "没有正在播放的媒体"
#: contents/ui/MaximizedPlayerPage.qml:112
#, kde-format
msgid "Queue"
msgstr ""
#: contents/ui/MaximizedPlayerPage.qml:224
#, kde-format
msgid "Remove Track"
msgstr "移除曲目"
#: contents/ui/MaximizedPlayerPage.qml:244
#: contents/ui/MinimizedPlayerControls.qml:96
#, kde-format
msgid "No media playing"
msgstr "没有正在播放的媒体"
#: contents/ui/PlaylistPage.qml:26
#, kde-format
msgid "Shuffle"
msgstr "随机播放"
#: contents/ui/SearchPage.qml:27
#, kde-format
msgid "Artists"
msgstr "艺人"
#: contents/ui/SearchPage.qml:29
#, kde-format
msgid "Playlists"
msgstr "播放列表"
#: contents/ui/SearchPage.qml:36
#, kde-format
msgid "Unknown"
msgstr "未知"
#: contents/ui/SearchPage.qml:117
#, kde-format
msgid "Play next"
msgstr "播放下一首"
#: contents/ui/SearchPage.qml:129
#, kde-format
msgid "Radio"
msgstr "电台"
#: contents/ui/SearchPage.qml:147
#, kde-format
msgid "Find music on YouTube Music"
msgstr "查找 YouTube Music 中的音乐"
#: contents/ui/SearchPage.qml:150
#, kde-format
msgid "Search"
msgstr "搜索"
#~ msgid "Clear"
#~ msgstr "清除"
#~ msgid "Pause"
#~ msgstr "暂停"
#~ msgid "Expand"
#~ msgstr "展开"
+8
View File
@@ -0,0 +1,8 @@
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(LMDB REQUIRED)
find_package(Qt5 COMPONENTS Core REQUIRED)
add_subdirectory(src)
+24
View File
@@ -0,0 +1,24 @@
# Try to find the LMBD libraries and headers
# LMDB_FOUND - system has LMDB lib
# LMDB_INCLUDE_DIR - the LMDB include directory
# LMDB_LIBRARIES - Libraries needed to use LMDB
# FindCWD based on FindGMP by:
# Copyright (c) 2006, Laurent Montel, <[email protected]>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# Adapted from FindCWD by:
# Copyright 2013 Conrad Steenberg <[email protected]>
# Aug 31, 2013
find_path(LMDB_INCLUDE_DIR NAMES lmdb.h PATHS "$ENV{LMDB_DIR}/include")
find_library(LMDB_LIBRARIES NAMES lmdb PATHS "$ENV{LMDB_DIR}/lib" )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LMDB DEFAULT_MSG LMDB_INCLUDE_DIR LMDB_LIBRARIES)
if(LMDB_FOUND)
message(STATUS "Found lmdb (include: ${LMDB_INCLUDE_DIR}, library: ${LMDB_LIBRARIES})")
mark_as_advanced(LMDB_INCLUDE_DIR LMDB_LIBRARIES)
endif()
+3
View File
@@ -0,0 +1,3 @@
add_library(qpersistentdata STATIC qpersistentdata.h qpersistentdata.cpp)
target_link_libraries(qpersistentdata PUBLIC Qt::Core ${LMDB_LIBRARIES})
target_include_directories(qpersistentdata PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+17
View File
@@ -0,0 +1,17 @@
#include "qpersistentdata.h"
#include <QDebug>
#include <QDateTime>
int main() {
auto data = QPersistentData("/tmp");
Q_ASSERT(data.isValid());
data.insert(1, QSize(1,11));
Q_ASSERT(data.value<QSize>(1) == QSize(1,11));
data.insert("idList", QVector<int> {1, 2, 3, 4, 5});
data.insert(u"moinLeude", u"Moin Leude");
data.insert(QVector<QByteArray>({"moin", "leude"}), "Yo");
data.insert(QDateTime(), u"Hello World"_qs);
qDebug() << data.value<QVector<int>>("idList");
}
+193
View File
@@ -0,0 +1,193 @@
#include "qpersistentdata.h"
#include <QtGlobal>
#include <QVariant>
#include <QDebug>
#include <QStandardPaths>
#include <QDir>
#include <QStringBuilder>
#include <QLoggingCategory>
#include <string_view>
#include <optional>
#include <tuple>
#include <lmdb.h>
Q_DECLARE_LOGGING_CATEGORY(PersistentDataLog)
Q_LOGGING_CATEGORY(PersistentDataLog, "qpersistentdata")
struct EnvironmentHolder {
MDB_env *env = nullptr;
int users = 0;
int maxDbs = 10;
};
EnvironmentHolder DATABASE_ENVIRONMENT;
void qPersistentDataSetMaxDbs(int num)
{
DATABASE_ENVIRONMENT.maxDbs = num;
}
///
/// Increments the number of references to the global database
/// environment on construction, and decrements it on destruction
///
/// This should ensure that an EnvHandle is always a valid handle to
/// an MDB_env
///
class EnvHandle {
public:
EnvHandle() {
DATABASE_ENVIRONMENT.users++;
if (!DATABASE_ENVIRONMENT.env) {
const QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) % "/persistent-data/";
QDir(path).mkpath(QStringLiteral("."));
int s = mdb_env_create(&DATABASE_ENVIRONMENT.env);
Q_ASSERT(s == MDB_SUCCESS);
s = mdb_env_set_maxdbs(DATABASE_ENVIRONMENT.env, DATABASE_ENVIRONMENT.maxDbs);
Q_ASSERT(s == MDB_SUCCESS);
if (int status = mdb_env_open(DATABASE_ENVIRONMENT.env, path.toUtf8(), 0, 0664) != MDB_SUCCESS) {
qCDebug(PersistentDataLog) << "Failed to open database with exit code" << status;
mdb_env_close(DATABASE_ENVIRONMENT.env);
}
}
}
EnvHandle(EnvHandle &) {
DATABASE_ENVIRONMENT.users++;
}
EnvHandle &operator=(const EnvHandle &) = default;
EnvHandle(EnvHandle &&) = default;
EnvHandle &operator=(EnvHandle &&) = default;
~EnvHandle() {
DATABASE_ENVIRONMENT.users--;
if (DATABASE_ENVIRONMENT.users == 0) {
qCDebug(PersistentDataLog) << "Closing database handle";
mdb_env_close(DATABASE_ENVIRONMENT.env);
}
}
operator MDB_env*() {
return DATABASE_ENVIRONMENT.env;
}
};
/// Qt wrapper for MDB_val
struct LMDBValueView : public MDB_val {
constexpr LMDBValueView() : MDB_val()
{
mv_size = 0;
mv_data = nullptr;
}
constexpr LMDBValueView(const QByteArray &bytes) : MDB_val()
{
mv_size = static_cast<size_t>(bytes.size());
mv_data = const_cast<char *>(bytes.data());
}
[[nodiscard]] constexpr const char *data() const {
return static_cast<const char *>(mv_data);
}
[[nodiscard]] constexpr std::size_t size() const {
return mv_size;
}
[[nodiscard]] QByteArray toByteArray() const {
return QByteArray(data(), size());
}
};
struct QPersistentDataPrivate {
QByteArray name;
EnvHandle handle;
~QPersistentDataPrivate() = default;
};
QPersistentData::QPersistentData(EnvHandle handle, const QByteArray &name)
: d(std::make_unique<QPersistentDataPrivate>())
{
d->handle = handle;
d->name = name;
}
QPersistentData::QPersistentData(const QByteArray &name)
: QPersistentData(EnvHandle(), name)
{
}
int QPersistentData::insert(const QByteArray &key, const QByteArray &value)
{
if (!d->handle) {
return MDB_INVALID;
}
MDB_txn *wtxn = nullptr;
if (int status = mdb_txn_begin(d->handle, nullptr, 0, &wtxn) != MDB_SUCCESS) {
return status;
}
MDB_dbi dbi {};
if (int status = mdb_dbi_open(wtxn, d->name, MDB_CREATE, &dbi) != MDB_SUCCESS) {
return status;
}
LMDBValueView k(key);
LMDBValueView v(value);
if (int status = mdb_put(wtxn, dbi, &k, &v, 0) != MDB_SUCCESS) {
return status;
}
if (int status = mdb_txn_commit(wtxn) != MDB_SUCCESS) {
return status;
}
mdb_dbi_close(d->handle, dbi);
return {};
}
QByteArray QPersistentData::value(const QByteArray &key) const
{
if (!d->handle) {
return {};
}
MDB_txn *rtxn = nullptr;
if (int status = mdb_txn_begin(d->handle, nullptr, MDB_RDONLY, &rtxn) != MDB_SUCCESS) {
qCDebug(PersistentDataLog) << "Failed to start transaction:" << status;
return {};
}
MDB_dbi dbi {};
if (int status = mdb_dbi_open(rtxn, d->name, MDB_CREATE, &dbi) != MDB_SUCCESS) {
qCDebug(PersistentDataLog) << "Failed to open database handle:" << status;
return {};
}
LMDBValueView k(key);
LMDBValueView v;
if (int status = mdb_get(rtxn, dbi, &k, &v) != MDB_SUCCESS) {
qCDebug(PersistentDataLog) << "Failed to retrieve data from the database:" << status;
return {};
}
mdb_txn_abort(rtxn);
mdb_dbi_close(d->handle, dbi);
return v.toByteArray();
}
bool QPersistentData::isValid() const
{
return d->handle;
}
QPersistentData::~QPersistentData() = default;
QPersistentData::QPersistentData(QPersistentData &&other) noexcept = default;
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include <QByteArray>
#include <QDataStream>
#include <QSize>
#include <QIODevice>
#include <optional>
#include <memory>
struct QPersistentDataPrivate;
class MDB_env;
class MDB_cursor;
class MDB_txn;
class EnvHandle;
typedef unsigned int MDB_dbi;
///
/// Set the number of databases that can be used in parallel
///
void qPersistentDataSetMaxDbs(int num);
class QPersistentData {
public:
QPersistentData(QPersistentData &&other) noexcept;
~QPersistentData();
QPersistentData(const QByteArray &name);
int insert(const QByteArray &key, const QByteArray &value);
template <typename KeyType, typename ValueType>
int insert(const KeyType &key, const ValueType &value) {
QByteArray keyS;
QByteArray valS;
QDataStream keyStream(&keyS, QIODevice::WriteOnly);
keyStream << key;
QDataStream valStream(&valS, QIODevice::WriteOnly);
valStream << value;
return insert(keyS, valS);
}
[[nodiscard]] QByteArray value(const QByteArray &key) const;
template <typename ValueType, typename KeyType>
ValueType value(const KeyType &key) const {
QByteArray keyS;
QDataStream keyStream(&keyS, QIODevice::WriteOnly);
keyStream << key;
auto val = value(keyS);
QDataStream vStream(val);
ValueType out;
vStream >> out;
return out;
}
[[nodiscard]] bool isValid() const;
private:
explicit QPersistentData(EnvHandle handle, const QByteArray &name);
std::shared_ptr<QPersistentDataPrivate> d;
};
+1 -1
View File
@@ -3,5 +3,5 @@
#
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
ytmusicapi==0.22.0
ytmusicapi==0.21.0
yt-dlp
+2 -11
View File
@@ -10,14 +10,6 @@ target_link_libraries(ytm PUBLIC pybind11::embed)
target_include_directories(ytm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(ytm PRIVATE -DRANDALL_WAS_HERE)
add_library(asyncdatabase STATIC
asyncdatabase.cpp
asyncdatabase_p.h
)
target_include_directories(asyncdatabase PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(asyncdatabase PUBLIC Qt5::Sql)
add_subdirectory(example)
add_executable(audiotube
@@ -49,9 +41,8 @@ target_link_libraries(audiotube
KF5::CoreAddons
KF5::Crash
ytm
asyncdatabase
qpersistentdata
)
target_compile_definitions(audiotube PRIVATE -DQT_NO_KEYWORDS -DQT_NO_URL_CAST_FROM_STRING -DQT_QML_DEBUG)
target_compile_definitions(audiotube PRIVATE -DQT_NO_KEYWORDS -DQT_NO_URL_CAST_FROM_STRING)
install(TARGETS audiotube ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
-309
View File
@@ -1,309 +0,0 @@
// SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "asyncdatabase.h"
#include <QDir>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QUrl>
#include <QStringBuilder>
#include <QVariant>
#include <QSqlResult>
#include <QSqlError>
#include <QLoggingCategory>
#define SCHAMA_MIGRATIONS_TABLE "__qt_schema_migrations"
Q_DECLARE_LOGGING_CATEGORY(asyncdatabase)
Q_LOGGING_CATEGORY(asyncdatabase, "asyncdatabase")
namespace asyncdatabase_private {
// migrations
void createInternalTable(QSqlDatabase &database) {
QSqlQuery query(QStringLiteral("create table if not exists " SCHAMA_MIGRATIONS_TABLE " ("
"version Text primary key not null, "
"run_on timestamp not null default current_timestamp)"), database);
if (!query.exec()) {
printSqlError(query);
}
}
void markMigrationRun(QSqlDatabase &database, const QString &name) {
qCDebug(asyncdatabase) << "Marking migration" << name << "as done.";
QSqlQuery query(database);
if (!query.prepare(QStringLiteral("insert into " SCHAMA_MIGRATIONS_TABLE " (version) values (:name)"))) {
printSqlError(query);
}
query.bindValue(QStringLiteral(":name"), QVariant(name));
if (!query.exec()) {
printSqlError(query);
}
}
bool checkMigrationAlreadyRun(QSqlDatabase &database, const QString &name) {
qCDebug(asyncdatabase) << "Checking whether migration" << name << "is already applied";
QSqlQuery query(database);
query.prepare(QStringLiteral("select count(*) from " SCHAMA_MIGRATIONS_TABLE " where version = :name"));
query.bindValue(QStringLiteral(":name"), QVariant(name));
query.exec();
query.next();
int count = query.value(0).toInt();
bool isApplied = count > 0;
if (isApplied) {
qCDebug(asyncdatabase) << "… yes";
} else {
qDebug(asyncdatabase) << "… no";
}
return isApplied;
}
void runDatabaseMigrations(QSqlDatabase &database, const QString &migrationDirectory)
{
createInternalTable(database);
QDir dir(migrationDirectory);
auto entries = dir.entryList(QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot, QDir::SortFlag::Name);
for (const auto &entry : entries) {
QDir subdir(entry);
if (!checkMigrationAlreadyRun(database, subdir.dirName())) {
QFile file(migrationDirectory % QDir::separator() % entry % QDir::separator() % "up.sql");
if (!file.open(QFile::ReadOnly)) {
qCDebug(asyncdatabase) << "Failed to open migration file" << file.fileName();
}
qCDebug(asyncdatabase) << "Running migration" << subdir.dirName();
database.transaction();
// Hackish
const auto statements = file.readAll().split(';');
bool migrationSuccessful = true;
for (const QByteArray &statement : statements) {
const auto trimmedStatement = statement.trimmed();
QSqlQuery query(database);
if (!trimmedStatement.isEmpty()) {
qCDebug(asyncdatabase) << "Running" << trimmedStatement;
if (!query.prepare(trimmedStatement)) {
printSqlError(query);
} else {
bool success = query.exec();
migrationSuccessful &= success;
if (!success) {
printSqlError(query);
}
}
}
}
if (migrationSuccessful) {
database.commit();
markMigrationRun(database, subdir.dirName());
} else {
database.rollback();
}
}
}
qCDebug(asyncdatabase) << "Migrations finished";
}
struct AsyncSqlDatabasePrivate {
QSqlDatabase database;
};
// Internal asynchronous database class
QFuture<void> AsyncSqlDatabase::establishConnection(const DatabaseConfiguration &configuration)
{
return runAsync<void>([=, this] {
d->database = QSqlDatabase::addDatabase(configuration.type());
if (configuration.databaseName()) {
d->database.setDatabaseName(*configuration.databaseName());
}
if (configuration.hostName()) {
d->database.setHostName(*configuration.hostName());
}
if (configuration.userName()) {
d->database.setUserName(*configuration.userName());
}
if (configuration.password()) {
d->database.setPassword(*configuration.password());
}
if (!d->database.open()) {
qCDebug(asyncdatabase) << "Failed to open database" << d->database.lastError().text();
if (configuration.databaseName()) {
qCDebug(asyncdatabase) << "Tried to use database" << *configuration.databaseName();
}
}
});
}
AsyncSqlDatabase::AsyncSqlDatabase()
: QObject()
, d(std::make_unique<AsyncSqlDatabasePrivate>())
{
}
Row AsyncSqlDatabase::retrieveRow(const QSqlQuery &query) {
Row row;
int i = 0;
while (true) {
if (query.isValid()) {
QVariant value = query.value(i);
if (value.isValid()) {
row.push_back(std::move(value));
i++;
} else {
break;
}
} else {
break;
}
}
return row;
}
Rows AsyncSqlDatabase::retrieveRows(QSqlQuery &query)
{
Rows rows;
while (query.next()) {
rows.push_back(retrieveRow(query));
}
return rows;
}
std::optional<Row> AsyncSqlDatabase::retrieveOptionalRow(QSqlQuery &query)
{
query.next();
if (query.isValid()) {
return retrieveRow(query);
} else {
return std::nullopt;
}
}
QSqlDatabase &AsyncSqlDatabase::db()
{
return d->database;
}
AsyncSqlDatabase::~AsyncSqlDatabase() = default;
void printSqlError(const QSqlQuery &query)
{
qCDebug(asyncdatabase) << "SQL error:" << query.lastError().text();
}
QSqlQuery prepareQuery(const QSqlDatabase &database, const QString &sqlQuery)
{
qCDebug(asyncdatabase) << "Running" << sqlQuery;
QSqlQuery query(database);
if (!query.prepare(sqlQuery)) {
printSqlError(query);
}
return query;
}
QSqlQuery runQuery(QSqlQuery &query)
{
if (!query.exec()) {
printSqlError(query);
}
return query;
}
}
struct DatabaseConfigurationPrivate : public QSharedData {
QString type;
std::optional<QString> hostName;
std::optional<QString> databaseName;
std::optional<QString> userName;
std::optional<QString> password;
};
DatabaseConfiguration::DatabaseConfiguration() : d(new DatabaseConfigurationPrivate)
{}
DatabaseConfiguration::~DatabaseConfiguration() = default;
DatabaseConfiguration::DatabaseConfiguration(const DatabaseConfiguration &) = default;
void DatabaseConfiguration::setType(const QString &type) {
d->type = type;
}
const QString &DatabaseConfiguration::type() const {
return d->type;
}
void DatabaseConfiguration::setHostName(const QString &hostName) {
d->hostName = hostName;
}
const std::optional<QString> &DatabaseConfiguration::hostName() const {
return d->hostName;
}
void DatabaseConfiguration::setDatabaseName(const QString &databaseName) {
d->databaseName = databaseName;
}
const std::optional<QString> &DatabaseConfiguration::databaseName() const {
return d->databaseName;
}
void DatabaseConfiguration::setUserName(const QString &userName) {
d->userName = userName;
}
const std::optional<QString> &DatabaseConfiguration::userName() const {
return d->userName;
}
void DatabaseConfiguration::setPassword(const QString &password) {
d->password = password;
}
const std::optional<QString> &DatabaseConfiguration::password() const {
return d->password;
}
struct ThreadedDatabasePrivate {
asyncdatabase_private::AsyncSqlDatabase db;
};
std::unique_ptr<ThreadedDatabase> ThreadedDatabase::establishConnection(DatabaseConfiguration config) {
auto threadedDb = std::make_unique<ThreadedDatabase>();
threadedDb->setObjectName(QStringLiteral("database thread"));
threadedDb->d->db.moveToThread(&*threadedDb);
threadedDb->start();
threadedDb->d->db.establishConnection(config);
return threadedDb;
}
ThreadedDatabase::ThreadedDatabase()
: QThread()
, d(std::make_unique<ThreadedDatabasePrivate>())
{
}
ThreadedDatabase::~ThreadedDatabase()
{
quit();
wait();
}
asyncdatabase_private::AsyncSqlDatabase &ThreadedDatabase::db()
{
return d->db;
}
-152
View File
@@ -1,152 +0,0 @@
// SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#pragma once
class QUrl;
class QSqlDatabase;
#include <QString>
#include <QObject>
#include <QFuture>
#include <QSharedDataPointer>
#include <memory>
#include <optional>
#include <tuple>
#include <vector>
#include "asyncdatabase_p.h"
struct DatabaseConfigurationPrivate;
///
/// Options for connecting to a database
///
class DatabaseConfiguration {
public:
DatabaseConfiguration();
DatabaseConfiguration(const DatabaseConfiguration &);
~DatabaseConfiguration();
/// Set the name of the database driver, for example DATABASE_TYPE_SQLITE or a custom string.
void setType(const QString &type);
const QString &type() const;
/// Set the hostname
void setHostName(const QString &hostName);
const std::optional<QString> &hostName() const;
/// Set the name of the database (path of the file for SQLite)
void setDatabaseName(const QString &databaseName);
const std::optional<QString> &databaseName() const;
/// Set user name
void setUserName(const QString &userName);
const std::optional<QString> &userName() const;
/// Set password
void setPassword(const QString &password);
const std::optional<QString> &password() const;
private:
QSharedDataPointer<DatabaseConfigurationPrivate> d;
};
///
/// The SQLite database driver
///
const QString DATABASE_TYPE_SQLITE = QStringLiteral("QSQLITE");
template <typename T>
concept FromSql = requires(T v, typename T::ColumnTypes row)
{
typename T::ColumnTypes;
{ std::tuple(row) } -> std::same_as<typename T::ColumnTypes>;
{ T::fromSql(row) } -> std::same_as<T>;
};
struct ThreadedDatabasePrivate;
class ThreadedDatabase : public QThread {
public:
///
/// \brief Connect to a database
/// \param configuration of the database connection
/// \return
///
static std::unique_ptr<ThreadedDatabase> establishConnection(DatabaseConfiguration config);
///
/// \brief Execute an SQL query on the database, ignoring the result.
/// \param SQL query string to execute
/// \param Parameters to bind to the placeholders in the SQL Query
/// \return
///
template <typename ...Args>
requires std::conjunction_v<std::is_convertible<Args, QVariant>...>
auto execute(const QString &sqlQuery, Args... args) -> QFuture<void> {
return db().execute(sqlQuery, args...);
}
///
/// Run database migrations in the given directory.
/// The directory needs to contain a subdirectory for each migration.
/// The subdirectories need to be named so that when sorted alphabetically the migrations will be run in the correct order.
/// Each subdirectory needs to contain a file named up.sql.
///
/// \param Directory which contains the migrations.
/// \return
///
auto runMigrations(const QString &migrationDirectory) -> QFuture<void> {
return db().runMigrations(migrationDirectory);
}
///
/// \brief Execute an SQL query on the database, retrieving the result.
/// \param SQL Query to execute
/// \param parameters to bind to the placeholders in the SQL query.
/// \return Future of a list of lists of variants.
///
/// T must provide a tuple of the column types as `using ColumnTypes = std::tuple<...>`
/// and a `static T fromSql(ColumnTypes tuple)` deserialization method.
///
template <typename T, typename ...Args>
requires FromSql<T> && std::conjunction_v<std::is_convertible<Args, QVariant>...>
auto getResults(const QString &sqlQuery, Args... args) -> QFuture<std::vector<T>> {
return db().getResults<T, Args...>(sqlQuery, args...);
}
///
/// \brief Like getResults, but for retrieving just one row.
///
template <typename T, typename ...Args>
requires FromSql<T> && std::conjunction_v<std::is_convertible<Args, QVariant>...>
auto getResult(const QString &sqlQuery, Args... args) -> QFuture<std::optional<T>> {
return db().getResult<T, Args...>(sqlQuery, args...);
}
ThreadedDatabase();
~ThreadedDatabase();
private:
asyncdatabase_private::AsyncSqlDatabase &db();
std::unique_ptr<ThreadedDatabasePrivate> d;
};
///
/// \brief Deserialize just a single value from a query result.
///
template <typename T>
struct SingleValue {
using ColumnTypes = std::tuple<T>;
static SingleValue fromSql(ColumnTypes tuple) {
auto [value] = tuple;
return SingleValue { value };
}
T value;
};
-178
View File
@@ -1,178 +0,0 @@
// SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#pragma once
#include <memory>
#include <tuple>
#include <optional>
#include <QFuture>
#include <QFutureWatcher>
#include <QSqlQuery>
#include <QSqlDatabase>
#include <QThread>
class DatabaseConfiguration;
namespace asyncdatabase_private {
// Helpers
template <typename Tuple, typename Func, std::size_t i>
inline constexpr void iterate_impl(Tuple &tup, Func fun)
{
if constexpr(i >= std::tuple_size_v<std::decay_t<decltype(tup)>>) {
return;
} else {
fun(std::get<i>(tup));
return asyncdatabase_private::iterate_impl<Tuple, Func, i + 1>(tup, fun);
}
}
template <typename Tuple, typename Func>
inline constexpr void iterate_tuple(Tuple &tup, Func fun)
{
asyncdatabase_private::iterate_impl<Tuple, Func, 0>(tup, fun);
}
template <typename T, typename QObjectDerivedType, typename Function>
void connectFuture(const QFuture<T> &future, QObjectDerivedType *self, const Function &fun) {
auto watcher = std::make_shared<QFutureWatcher<T>>();
watcher->setFuture(future);
QObject::connect(watcher.get(), &QFutureWatcherBase::finished, self, [self, watcher, fun, future] {
if constexpr (std::is_same_v<void, T>) {
if constexpr (std::is_member_function_pointer_v<Function>) {
fun->*(self);
} else {
fun();
}
} else if (future.resultCount() > 0) {
if constexpr (std::is_member_function_pointer_v<Function>) {
(self->*fun)(watcher->result());
} else {
fun(watcher->result());
}
}
});
}
using Row = std::vector<QVariant>;
using Rows = std::vector<Row>;
template <typename RowTypesTuple>
auto parseRow(const Row &row) -> RowTypesTuple
{
auto tuple = RowTypesTuple();
int i = 0;
asyncdatabase_private::iterate_tuple(tuple, [&](auto &elem) {
elem = row.at(i).value<std::decay_t<decltype(elem)>>();
i++;
});
return tuple;
}
template <typename RowTypesTuple>
auto parseRows(const Rows &rows) -> std::vector<RowTypesTuple> {
std::vector<RowTypesTuple> parsedRows;
parsedRows.reserve(rows.size());
std::ranges::transform(rows, std::back_inserter(parsedRows), parseRow<RowTypesTuple>);
return parsedRows;
}
void runDatabaseMigrations(QSqlDatabase &database, const QString &migrationDirectory);
void printSqlError(const QSqlQuery &query);
// non-template helper functions to allow patching a much as possible in the shared library
QSqlQuery prepareQuery(const QSqlDatabase &database, const QString &sqlQuery);
QSqlQuery runQuery(QSqlQuery &query);
struct AsyncSqlDatabasePrivate;
class AsyncSqlDatabase : public QObject {
Q_OBJECT
public:
QFuture<void> establishConnection(const DatabaseConfiguration &configuration);
template <typename T, typename ...Args>
auto getResults(const QString &sqlQuery, Args... args) -> QFuture<std::vector<T>> {
return runAsync<std::vector<T>>([=, this] {
auto query = executeQuery(sqlQuery, args...);
const auto rows = parseRows<typename T::ColumnTypes>(retrieveRows(query));
std::vector<T> deserializedRows;
std::ranges::transform(rows, std::back_inserter(deserializedRows), T::fromSql);
return deserializedRows;
});
}
template <typename T, typename ...Args>
auto getResult(const QString &sqlQuery, Args... args) -> QFuture<std::optional<T>> {
return runAsync<std::optional<T>>([=, this]() -> std::optional<T> {
auto query = executeQuery(sqlQuery, args...);
if (const auto row = retrieveOptionalRow(query)) {
return T::fromSql(parseRow<typename T::ColumnTypes>(*row));
}
return std::nullopt;
});
}
template <typename ...Args>
auto execute(const QString &sqlQuery, Args... args) -> QFuture<void> {
return runAsync<void>([=, this] {
executeQuery(sqlQuery, args...);
});
}
auto runMigrations(const QString &migrationDirectory) -> QFuture<void> {
return runAsync<void>([=, this] {
runDatabaseMigrations(db(), migrationDirectory);
});
}
AsyncSqlDatabase();
~AsyncSqlDatabase();
private:
template <typename ...Args>
QSqlQuery executeQuery(const QString &sqlQuery, Args... args) {
auto query = prepareQuery(db(), sqlQuery);
auto argsTuple = std::make_tuple<Args...>(std::move(args)...);
int i = 0;
asyncdatabase_private::iterate_tuple(argsTuple, [&](auto &arg) {
query.bindValue(i, arg);
i++;
});
return runQuery(query);
}
template <typename T, typename Functor>
QFuture<T> runAsync(Functor func) {
auto interface = std::make_shared<QFutureInterface<T>>();
QMetaObject::invokeMethod(this, [interface, func] {
if constexpr (!std::is_same_v<T, void>) {
auto result = func();
interface->reportResult(result);
} else {
func();
}
interface->reportFinished();
});
return interface->future();
}
Row retrieveRow(const QSqlQuery &query);
Rows retrieveRows(QSqlQuery &query);
std::optional<Row> retrieveOptionalRow(QSqlQuery &query);
QSqlDatabase &db();
std::unique_ptr<AsyncSqlDatabasePrivate> d;
};
}
+5 -38
View File
@@ -47,50 +47,17 @@ private:
std::unique_ptr<T> m_item = nullptr;
};
///
/// Similar to QObject::connect, except that the first two arguments are replaced with a QFuture.
///
template <typename T, typename QObjectDerivedType, typename Function>
void connectFuture(const QFuture<T> &future, QObjectDerivedType *self, const Function &fun) {
template <typename T, typename Function>
void connectFuture(const QFuture<T> &future, QObject *self, const Function &fun) {
auto watcher = std::make_shared<QFutureWatcher<T>>();
watcher->setFuture(future);
QObject::connect(watcher.get(), &QFutureWatcherBase::finished, self, [self, watcher, fun, future] {
if constexpr (std::is_same_v<void, T>) {
if constexpr (std::is_member_function_pointer_v<Function>) {
(self->*fun)();
} else {
fun();
}
} else if (future.resultCount() > 0) {
if constexpr (std::is_member_function_pointer_v<Function>) {
(self->*fun)(watcher->result());
} else {
fun(watcher->result());
}
QObject::connect(watcher.get(), &QFutureWatcherBase::finished, self, [watcher, fun, future] {
if (future.resultCount() > 0) {
fun(watcher->result());
}
});
}
///
/// Applies a function to a the contained value of a QFuture once it finishes.
/// @returns a QFuture that finishes once the future given as first argument finished
///
template <typename T, typename U, typename Func>
QFuture<U> mapFuture(const QFuture<T> &future, Func mapFunction) {
auto watcher = std::make_shared<QFutureWatcher<T>>();
watcher->setFuture(future);
auto interface = std::make_shared<QFutureInterface<U>>();
QObject::connect(watcher.get(), &QFutureWatcherBase::finished, watcher.get(), [interface, watcher, mapFunction] {
auto result = watcher->result();
auto mapped = mapFunction(std::move(result));
interface->reportResult(mapped);
interface->reportFinished();
});
return interface->future();
}
class AsyncYTMusic : public QObject
{
friend class YTMusicThread;
-7
View File
@@ -21,13 +21,6 @@ Kirigami.ScrollablePage {
applicationWindow().playPlaylist(albumModel.playlistId)
}
}
right: Kirigami.Action {
icon.name: "media-playlist-shuffle"
text: i18n("Shuffle")
onTriggered: {
applicationWindow().playShufflePlaylist(albumModel.playlistId)
}
}
}
ListView {
+9 -114
View File
@@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
import QtQuick 2.1
import QtQuick.Controls 2.12 as Controls
import QtQuick.Layouts 1.3
@@ -10,38 +6,9 @@ import org.kde.kirigami 2.14 as Kirigami
import org.kde.ytmusic 1.0
Kirigami.ScrollablePage {
globalToolBarStyle: Kirigami.ApplicationHeaderStyle.None
// so that there is still a separator, since the header style is none
Kirigami.Separator {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
}
ColumnLayout {
RowLayout {
Layout.fillWidth: true
Kirigami.Heading {
text: i18n("Favourites")
Layout.alignment: Qt.AlignLeft
}
// Spacer
Item {
Layout.fillWidth: true
}
Controls.ToolButton {
text: i18n("Show All")
Layout.alignment: Qt.AlignRight
icon.name: "arrow-right"
onClicked: pageStack.layers.push("qrc:/PlaybackHistory.qml", {
"dataModel": Library.favourites,
"title": i18n("Favourite Songs")
})
}
Kirigami.Heading {
text: i18n("Favourites")
}
Controls.ScrollView {
Layout.fillWidth: true
@@ -49,23 +16,22 @@ Kirigami.ScrollablePage {
Repeater {
Layout.fillWidth: true
model: Library.favourites
onCountChanged: () => console.log("Count:", count)
delegate: ColumnLayout {
id: delegateItem
required property string title
required property string artists
required property string videoId
Layout.fillWidth: false
Layout.maximumWidth: 200
Component.onCompleted: {
console.log(modelData)
}
Kirigami.Card {
id: card
Layout.preferredHeight: 200
onClicked: play(delegateItem.videoId)
onClicked: play(modelData)
ThumbnailSource {
id: thumbnailSource
videoId: delegateItem.videoId
videoId: modelData
}
header: Image {
@@ -74,81 +40,10 @@ Kirigami.ScrollablePage {
fillMode: Image.PreserveAspectCrop
asynchronous: true
}
actions: [
Kirigami.Action {
icon.name: "delete"
onTriggered: Library.removeFavourite(delegateItem.videoId)
}
]
}
Controls.Label {
Layout.maximumWidth: 200
text: delegateItem.title
elide: Qt.ElideRight
}
}
}
}
}
RowLayout {
Layout.fillWidth: true
Kirigami.Heading {
text: i18n("Most played")
Layout.alignment: Qt.AlignLeft
}
// Spacer
Item {
Layout.fillWidth: true
}
Controls.ToolButton {
text: i18n("Show All")
Layout.alignment: Qt.AlignRight
icon.name: "arrow-right"
onClicked: pageStack.layers.push("qrc:/PlaybackHistory.qml", {
"dataModel": Library.playbackHistory,
"title": i18n("Played Songs")
})
}
}
Controls.ScrollView {
Layout.fillWidth: true
RowLayout {
Repeater {
Layout.fillWidth: true
model: Library.mostPlayed
delegate: ColumnLayout {
id: mpdelegateItem
required property string title
required property string artists
required property string videoId
Layout.fillWidth: false
Layout.maximumWidth: 200
Kirigami.Card {
id: mpcard
Layout.preferredHeight: 200
onClicked: play(mpdelegateItem.videoId)
ThumbnailSource {
id: mpthumbnailSource
videoId: mpdelegateItem.videoId
}
header: Image {
sourceSize: "200x200"
source: mpthumbnailSource.cachedPath
fillMode: Image.PreserveAspectCrop
asynchronous: true
}
}
Controls.Label {
Layout.maximumWidth: 200
text: mpdelegateItem.title
text: Library.videoTitle(modelData)
elide: Qt.ElideRight
}
}
-427
View File
@@ -1,427 +0,0 @@
// SPDX-FileCopyrightText: 2020-2022 Devin Lin <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.0
import QtMultimedia 5.12
import org.kde.kirigami 2.19 as Kirigami
import org.kde.ytmusic 1.0
Item {
id: root
required property var info // VideoInfoExtractor object
required property var audio // Audio object
signal requestClose()
// background image
Item {
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: Qt.rgba(25, 25, 30, 1)
}
Image {
anchors.fill: parent
asynchronous: true
source: info.thumbnail
fillMode: Image.PreserveAspectCrop
sourceSize.width: 512
sourceSize.height: 512
}
layer.enabled: true
layer.effect: HueSaturation {
cached: true
lightness: -0.5
saturation: 1.9
layer.enabled: true
layer.effect: FastBlur {
cached: true
radius: 100
}
}
}
// content
ColumnLayout {
anchors.fill: parent
spacing: 0
// hide arrow button
ToolButton {
id: closeButton
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
Layout.maximumHeight: parent.height
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
Layout.maximumWidth: parent.height
Layout.preferredWidth: Kirigami.Units.gridUnit * 3
Layout.topMargin: Kirigami.Units.smallSpacing
icon.name: "arrow-down"
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
onClicked: root.requestClose()
}
// top tab bar
RowLayout {
id: tabBar
Layout.alignment: Qt.AlignHCenter
ToolButton {
id: nowPlayingTab
text: i18n("Now Playing")
padding: Kirigami.Units.largeSpacing
onClicked: swipeView.setCurrentIndex(0)
Layout.preferredHeight: Kirigami.Units.gridUnit * 2
Layout.preferredWidth: Kirigami.Units.gridUnit * 9
contentItem: Label {
text: nowPlayingTab.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
color: "white" // we need to ensure the label is white
}
// selection indicator
Rectangle {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
color: Kirigami.Theme.highlightColor
height: 1
visible: swipeView.currentIndex == 0
}
}
ToolButton {
id: queueTab
text: i18n("Queue")
padding: Kirigami.Units.largeSpacing
onClicked: swipeView.setCurrentIndex(1)
Layout.preferredHeight: Kirigami.Units.gridUnit * 2
Layout.preferredWidth: Kirigami.Units.gridUnit * 9
contentItem: Label {
text: queueTab.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
color: "white"
}
// selection indicator
Rectangle {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
color: Kirigami.Theme.highlightColor
height: 1
visible: swipeView.currentIndex == 1
}
}
}
// tabs
SwipeView {
id: swipeView
property double specWidth: {
let allowedWidth = root.width - Kirigami.Units.largeSpacing * 4;
let allowedHeight = root.height - Kirigami.Units.largeSpacing * 8 - (closeButton.height + tabBar.height + bottomPlayerControls.height);
if (allowedWidth > allowedHeight) {
return allowedHeight;
} else {
return allowedWidth;
}
}
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
Layout.fillWidth: true
Layout.preferredHeight: specWidth
// music art
Item {
height: swipeView.width
width: swipeView.height
Image {
anchors.centerIn: parent
width: swipeView.specWidth
height: swipeView.specWidth
asynchronous: true
mipmap: true
source: info.thumbnail
sourceSize {
width: 512
height: 512
}
fillMode: Image.PreserveAspectCrop
}
}
// playlist
ListView {
id: playlistView
width: swipeView.width
height: swipeView.height
clip: true
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
BusyIndicator {
anchors.centerIn: parent
visible: UserPlaylistModel.loading || UserPlaylistModel.loading
}
model: UserPlaylistModel
delegate: Kirigami.SwipeListItem {
id: delegateItem
required property string title
required property string videoId
required property string artists
required property bool isCurrent
backgroundColor: 'transparent'
highlighted: isCurrent
onClicked: UserPlaylistModel.skipTo(videoId)
ColumnLayout {
Layout.fillWidth: true
Kirigami.Heading {
elide: Text.ElideRight
Layout.fillWidth: true
level: 2
text: title
}
Label {
elide: Text.ElideRight
Layout.fillWidth: true
text: artists
}
}
actions: [
Kirigami.Action {
text: i18n("Remove Track")
icon.name: "list-remove"
icon.color: "white"
onTriggered: UserPlaylistModel.remove(delegateItem.videoId)
}
]
}
}
}
ColumnLayout {
id: bottomPlayerControls
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.leftMargin: Kirigami.Units.gridUnit * 2
Layout.rightMargin: Kirigami.Units.gridUnit * 2
Layout.bottomMargin: Kirigami.Units.gridUnit * 2
// song name
Label {
id: mainLabel
text: info.title ? info.title : i18n("No media playing")
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
maximumLineCount: 1
// Hardcoded because the footerbar blur always makes a dark-ish
// background, so we don't want to use a color scheme color that
// might also be dark
color: "white"
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.5
font.weight: Font.Bold
font.bold: true
}
// song artist
Kirigami.Heading {
id: authorLabel
text: info.artist ? info.artist : info.channel
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
maximumLineCount: 1
// Hardcoded because the footerbar blur always makes a dark-ish
// background, so we don't want to use a color scheme color that
// might also be dark
color: "white"
opacity: 0.9
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.3
font.weight: Font.Bold
font.bold: true
}
// slider row
RowLayout {
Layout.topMargin: Kirigami.Units.gridUnit * 2
spacing: Kirigami.Units.smallSpacing
Label {
Layout.alignment: Qt.AlignVCenter
color: "white"
visible: info.title
text: PlayerUtils.formatTimestamp(audio.position)
}
Slider {
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
from: 0
to: audio.duration
value: audio.position
enabled: audio.seekable
onMoved: {
console.log("Value:", value);
audio.seek(Math.floor(value));
}
Behavior on value {
NumberAnimation {
duration: 1000
}
}
}
Label {
Layout.alignment: Qt.AlignVCenter
color: "white"
visible: info.title
text: PlayerUtils.formatTimestamp(audio.duration)
}
}
RowLayout {
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
spacing: Kirigami.Units.largeSpacing
// ensure white icons
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
ToolButton {
id: favouriteButton
readonly property QtObject favouriteWatcher: Library.favouriteWatcher(info.videoId)
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
Layout.maximumWidth: height
Layout.preferredWidth: height
onClicked: if (favouriteWatcher)
favouriteWatcher.isFavourite
? Library.removeFavourite(info.videoId)
: Library.addFavourite(info.videoId, info.title)
icon.name: favouriteWatcher ? (favouriteWatcher.isFavourite ? "starred-symbolic" : "non-starred-symbolic") : ""
icon.width: Kirigami.Units.gridUnit * 1.5
icon.height: Kirigami.Units.gridUnit * 1.5
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
ToolButton {
id: skipBackwardButton
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
Layout.maximumWidth: height
Layout.preferredWidth: height
enabled: false
icon.name: "media-skip-backward"
icon.width: Kirigami.Units.gridUnit * 1.5
icon.height: Kirigami.Units.gridUnit * 1.5
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
ToolButton {
id: playPauseButton
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.preferredHeight: Kirigami.Units.gridUnit * 4
Layout.maximumWidth: height
Layout.preferredWidth: height
enabled: info.audioUrl != ""
onClicked: audio.playbackState === Audio.PlayingState ? audio.pause() : audio.play()
icon.name: audio.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
icon.width: Kirigami.Units.gridUnit * 3
icon.height: Kirigami.Units.gridUnit * 3
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
ToolButton {
id: skipForwardButton
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
Layout.maximumWidth: height
Layout.preferredWidth: height
enabled: UserPlaylistModel.canSkip
onClicked: UserPlaylistModel.next()
icon.name: "media-skip-forward"
icon.width: Kirigami.Units.gridUnit * 1.5
icon.height: Kirigami.Units.gridUnit * 1.5
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
ToolButton {
id: shuffleButton
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
Layout.maximumWidth: height
Layout.preferredWidth: height
onClicked: UserPlaylistModel.shufflePlaylist()
icon.name: "media-playlist-shuffle"
icon.width: Kirigami.Units.gridUnit * 1.5
icon.height: Kirigami.Units.gridUnit * 1.5
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
}
}
}
}
-217
View File
@@ -1,217 +0,0 @@
// SPDX-FileCopyrightText: 2020-2022 Devin Lin <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.0
import QtMultimedia 5.12
import org.kde.kirigami 2.19 as Kirigami
import org.kde.ytmusic 1.0
Item {
id: root
required property int progressBarHeight
required property int minimizedPlayerContentHeight
required property var info // VideoInfoExtractor object
required property var audio // Audio object
readonly property bool isWidescreen: width >= Kirigami.Units.gridUnit * 40
signal requestOpen()
Rectangle {
id: miniProgressBar
z: 1
visible: !root.isWidescreen
anchors.top: parent.top
anchors.left: parent.left
height: root.progressBarHeight
color: Kirigami.Theme.highlightColor
width: parent.width * (audio.position / audio.duration)
}
RowLayout {
anchors.fill: parent
spacing: 0
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.maximumWidth: Kirigami.Units.gridUnit * 20
Layout.preferredWidth: Kirigami.Units.gridUnit * 20
color: Qt.rgba(0, 0, 0, trackClick.containsMouse ? 0.1 : trackClick.pressed ? 0.3 : 0)
RowLayout {
anchors.fill: parent
anchors.leftMargin: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing
// track image
Item {
property double imageSize: root.height - Kirigami.Units.largeSpacing * 2
Layout.alignment: Qt.AlignVCenter
Layout.maximumWidth: imageSize
Layout.preferredWidth: imageSize
Layout.maximumHeight: imageSize
Layout.minimumHeight: imageSize
Image {
id: mainIcon
anchors.fill: parent
visible: !loadingIndicator.visible
asynchronous: true
mipmap: true
source: info.thumbnail
sourceSize.width: 512
sourceSize.height: 512
fillMode: Image.PreserveAspectCrop
}
BusyIndicator {
id: loadingIndicator
anchors.centerIn: parent
visible: UserPlaylistModel.loading
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
}
// track information
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Label {
id: mainLabel
text: info.title ? info.title : i18n("No media playing")
textFormat: Text.PlainText
wrapMode: Text.Wrap
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
maximumLineCount: 1
// Hardcoded because the footerbar blur always makes a dark-ish
// background, so we don't want to use a color scheme color that
// might also be dark
color: "white"
font.weight: Font.Bold
}
Label {
id: authorLabel
text: info.artist ? info.artist : info.channel
textFormat: Text.PlainText
wrapMode: Text.Wrap
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
maximumLineCount: 1
// Hardcoded because the footerbar blur always makes a dark-ish
// background, so we don't want to use a color scheme color that
// might also be dark
color: "white"
}
}
}
MouseArea {
id: trackClick
anchors.fill: parent
hoverEnabled: true
onClicked: root.requestOpen()
}
}
RowLayout {
visible: root.isWidescreen
Layout.preferredWidth: 0
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: Kirigami.Units.largeSpacing
Layout.rightMargin: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.smallSpacing
Label {
Layout.alignment: Qt.AlignVCenter
color: "white"
visible: info.title
text: PlayerUtils.formatTimestamp(audio.position)
}
Slider {
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
from: 0
to: audio.duration
value: audio.position
enabled: audio.seekable
onMoved: {
console.log("Value:", value);
audio.seek(Math.floor(value));
}
Behavior on value {
NumberAnimation {
duration: 1000
}
}
}
Label {
Layout.alignment: Qt.AlignVCenter
color: "white"
visible: info.title
text: PlayerUtils.formatTimestamp(audio.duration)
}
}
ToolButton {
id: playPauseButton
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
Layout.maximumWidth: height
Layout.preferredWidth: height
enabled: info.audioUrl != ""
onClicked: audio.playbackState === Audio.PlayingState ? audio.pause() : audio.play()
icon.name: audio.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
icon.width: Kirigami.Units.gridUnit
icon.height: Kirigami.Units.gridUnit
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
ToolButton {
id: skipForwardButton
Layout.rightMargin: Math.floor(Kirigami.Units.smallSpacing / 2)
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
Layout.maximumWidth: height
Layout.preferredWidth: height
enabled: UserPlaylistModel.canSkip
onClicked: UserPlaylistModel.next()
icon.name: "media-skip-forward"
icon.width: Kirigami.Units.gridUnit
icon.height: Kirigami.Units.gridUnit
icon.color: "white"
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
}
}
}
-76
View File
@@ -1,76 +0,0 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15 as Controls
import org.kde.kirigami 2.15 as Kirigami
import org.kde.ytmusic 1.0
Kirigami.ScrollablePage {
id: playbackHistoryPage
title: i18n("Unknown list of songs")
property QtObject dataModel
ListView {
id: listView
reuseItems: true
Kirigami.PlaceholderMessage {
visible: listView.count < 1
text: i18n("No songs here yet")
anchors.centerIn: parent
}
model: playbackHistoryPage.dataModel
delegate: Kirigami.SwipeListItem {
id: delegateItem
required property string title
required property string videoId
required property string artists
RowLayout {
ThumbnailSource {
id: thumbnailSource
videoId: delegateItem.videoId
}
Item {
width: Kirigami.Units.gridUnit * 3
height: Kirigami.Units.gridUnit * 3
Image {
sourceSize: "200x200"
source: thumbnailSource.cachedPath
fillMode: Image.PreserveAspectCrop
width: Kirigami.Units.gridUnit * 3
height: Kirigami.Units.gridUnit * 3
Layout.alignment: Qt.AlignLeft
}
}
Controls.Label {
text: delegateItem.title
Layout.fillWidth: true
}
}
actions: [
Kirigami.Action {
icon.name: "go-next"
text: i18n("Play Next")
onTriggered: UserPlaylistModel.playNext(delegateItem.videoId, delegateItem.title, delegateItem.artists)
},
Kirigami.Action {
icon.name: "media-playlist-append"
text: i18n("Add to Playlist")
onTriggered: UserPlaylistModel.append(delegateItem.videoId, delegateItem.title, delegateItem.artists)
}
]
}
}
}
+205 -363
View File
@@ -1,422 +1,264 @@
// SPDX-FileCopyrightText: 2021 Jonah Brüchert <[email protected]>
// SPDX-FileCopyrightText: 2021 Bart De Vries <[email protected]>
// SPDX-FileCopyrightText: 2020-2022 Devin Lin <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.12 as Controls
import QtMultimedia 5.12
import QtGraphicalEffects 1.0
import org.kde.kirigami 2.12 as Kirigami
import org.kde.ytmusic 1.0
import QtMultimedia 5.12
Flickable {
Item {
id: footerItem
property bool maximized: false
readonly property int progressBarHeight: Kirigami.Units.gridUnit / 6
readonly property int minimizedPlayerContentHeight: Math.round(Kirigami.Units.gridUnit * 3.5)
readonly property int minimizedPlayerHeight: minimizedPlayerContentHeight + progressBarHeight
boundsBehavior: Flickable.StopAtBounds
function close() {
toClose.restart();
}
anchors.left: parent.left
anchors.right: parent.right
height: maximized ? applicationWindow().height : 75
function resetToBoundsOnFlick() {
if (!atYBeginning || !atYEnd) {
if (footerItem.verticalVelocity > 0) {
toOpen.restart();
} else if (footerItem.verticalVelocity < 0) {
toClose.restart();
} else { // i.e. when verticalVelocity === 0
if (contentY > contentHeight / 4) {
toOpen.restart();
} else {
toClose.restart();
}
}
}
}
function resetToBoundsOnResize() {
if (contentY > contentHeight / 4) {
contentY = contentHeight / 2;
} else {
contentY = 0;
}
}
NumberAnimation on contentY {
id: toOpen
from: contentY
to: contentHeight / 2
duration: Kirigami.Units.longDuration * 2
easing.type: Easing.OutCubic
running: false
}
NumberAnimation on contentY {
id: toClose
from: contentY
to: 0
duration: Kirigami.Units.longDuration * 2
easing.type: Easing.OutCubic
running: false
}
// snap to end
MouseArea {
Rectangle {
color: Kirigami.Theme.backgroundColor
Kirigami.Theme.colorSet: Kirigami.Theme.Window
anchors.fill: footerLayout
propagateComposedEvents: true
onPressed: {
toOpen.stop();
toClose.stop();
propagateComposedEvents = true;
}
onReleased: footerItem.resetToBoundsOnFlick()
}
onMovementStarted: {
toOpen.stop();
toClose.stop();
}
onFlickStarted: resetToBoundsOnFlick()
onMovementEnded: resetToBoundsOnFlick()
onHeightChanged: resetToBoundsOnResize()
property var videoInfoExtractor: VideoInfoExtractor {
id: info
onSongChanged: audio.play()
videoId: UserPlaylistModel.currentVideoId
onTitleChanged: Library.addPlaybackHistoryItem(info.videoId, info.title)
}
property var audioPlayer: Audio {
id: audio
source: info.audioUrl
onStatusChanged: {
if (status === Audio.EndOfMedia) {
console.log("Song ended");
UserPlaylistModel.next();
}
}
}
contentHeight: height * 2
ColumnLayout {
id: footerLayout
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
height: parent.height
anchors.fill: parent
// margin from top
Item {
Layout.minimumHeight: footerItem.height - footerItem.minimizedPlayerHeight
}
Controls.Control {
GridLayout {
id: playerLayout
readonly property bool mobile: width > height
Layout.fillHeight: footerItem.maximized
Layout.fillWidth: true
padding: 0
implicitHeight: footerItem.minimizedPlayerHeight
// minimized player background
background: Item {
Rectangle {
anchors.fill: parent
color: Qt.rgba(25, 25, 30, 1)
}
flow: width > height ? GridLayout.LeftToRight : GridLayout.TopToBottom
visible: footerItem.maximized
ColumnLayout {
Layout.fillWidth: info.thumbnail
Layout.fillHeight: info.thumbnail
Image {
opacity: 0.2
source: info.thumbnail
asynchronous: true
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
Layout.preferredWidth: footerLayout.width * 0.5
fillMode: Image.PreserveAspectFit
}
layer.enabled: true
layer.effect: HueSaturation {
cached: true
Controls.ToolButton{
text: "Fav"
onClicked: Library.addFavourite(info.videoId)
}
}
lightness: -0.5
saturation: 1.9
Item {
Layout.fillWidth: true
Layout.fillHeight: true
layer.enabled: true
layer.effect: FastBlur {
cached: true
radius: 64
transparentBorder: false
Controls.ScrollView {
anchors.fill: parent
ListView {
anchors.fill: parent
id: playlistView
clip: true
Controls.BusyIndicator {
anchors.centerIn: parent
visible: UserPlaylistModel.loading || UserPlaylistModel.loading
}
onCountChanged: {
if (count < 1) {
footerItem.maximized = false
}
}
model: UserPlaylistModel
delegate: Kirigami.SwipeListItem {
id: delegateItem
required property string title
required property string videoId
required property string artists
required property bool isCurrent
highlighted: isCurrent
onClicked: UserPlaylistModel.skipTo(videoId)
ColumnLayout {
Layout.fillWidth: true
Kirigami.Heading {
elide: Text.ElideRight
Layout.fillWidth: true
level: 2
text: title
}
Controls.Label {
elide: Text.ElideRight
Layout.fillWidth: true
text: artists
}
}
actions: [
Kirigami.Action {
text: i18n("Remove Track")
icon.name: "list-remove"
onTriggered: UserPlaylistModel.remove(delegateItem.videoId)
}
]
}
header: Controls.ToolBar {
anchors.left: parent.left
anchors.right: parent.right
RowLayout {
anchors.fill: parent
Item {
Layout.fillWidth: true
}
Controls.ToolButton {
text: i18n("Clear")
icon.name: "edit-clear-all"
onClicked: UserPlaylistModel.clear()
}
Controls.ToolButton {
text: i18n("Shuffle")
icon.name: "media-playlist-shuffle"
onClicked: UserPlaylistModel.shufflePlaylist()
}
}
}
}
}
}
MinimizedPlayerControls {
progressBarHeight: footerItem.progressBarHeight
minimizedPlayerContentHeight: footerItem.minimizedPlayerContentHeight
height: minimizedPlayerHeight
focus: true
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
info: footerItem.videoInfoExtractor
audio: footerItem.audioPlayer
onRequestOpen: toOpen.start();
}
}
MaximizedPlayerPage {
id: maximizedPlayerPage
Kirigami.Separator {
Layout.fillWidth: true
Layout.fillHeight: true
implicitHeight: footerItem.height
info: footerItem.videoInfoExtractor
audio: footerItem.audioPlayer
onRequestClose: toClose.start();
}
//GridLayout {
//id: playerLayout
//readonly property bool mobile: width > height
RowLayout {
id: player
//Layout.fillHeight: footerItem.maximized
//Layout.fillWidth: true
//flow: width > height ? GridLayout.LeftToRight : GridLayout.TopToBottom
//visible: footerItem.maximized
Layout.fillWidth: true
Layout.fillHeight: !footer.maximized
//ColumnLayout {
//Layout.preferredWidth: footerLayout.width * (playerLayout.mobile ? 1 : 0.5)
//Layout.preferredHeight: footerLayout.height * (playerLayout.mobile ? 0.5 : 1)
VideoInfoExtractor {
id: info
//Item {
//Layout.fillWidth: true
//Layout.fillHeight: true
onSongChanged: audio.play()
videoId: UserPlaylistModel.currentVideoId
}
//Image {
//anchors.fill: parent
//source: info.thumbnail
//fillMode: Image.PreserveAspectFit
//}
//}
//Controls.RoundButton {
//readonly property QtObject favouriteWatcher: Library.favouriteWatcher(info.videoId)
Audio {
id: audio
//Layout.alignment: Qt.AlignHCenter
//icon.name: favouriteWatcher ? (favouriteWatcher.isFavourite ? "starred-symbolic" : "non-starred-symbolic") : ""
//onClicked: if (favouriteWatcher)
//favouriteWatcher.isFavourite
//? Library.removeFavourite(info.videoId)
//: Library.addFavourite(info.videoId, info.title)
//}
//}
source: info.audioUrl
onStatusChanged: {
if (status === Audio.EndOfMedia) {
console.log("Song ended");
UserPlaylistModel.next();
}
}
}
//Item {
//Layout.fillWidth: true
//Layout.fillHeight: true
//Layout.preferredWidth: footerLayout.width * (playerLayout.mobile ? 1 : 0.5)
//Layout.preferredHeight: footerLayout.height * (playerLayout.mobile ? 0.5 : 1)
Controls.ToolButton {
display: Controls.AbstractButton.IconOnly
Layout.preferredWidth: parent.height
Layout.fillHeight: true
enabled: info.audioUrl != ""
text: audio.playbackState === Audio.PlayingState ? i18n("Pause") : i18n("Play")
visible: !info.loading
icon.name: audio.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
onClicked: audio.playbackState === Audio.PlayingState ? audio.pause() : audio.play()
}
//Controls.ScrollView {
//anchors.fill: parent
Controls.ToolButton {
display: Controls.AbstractButton.IconOnly
Layout.preferredWidth: parent.height
Layout.fillHeight: true
enabled: UserPlaylistModel.canSkip
visible: !info.loading
icon.name: "media-skip-forward"
onClicked: UserPlaylistModel.next()
}
//ListView {
//anchors.fill: parent
//id: playlistView
Controls.BusyIndicator {
Layout.fillHeight: true
visible: info.loading
}
//clip: true
ColumnLayout {
Layout.fillHeight: true
Layout.topMargin: Kirigami.Units.smallSpacing
Layout.bottomMargin: Kirigami.Units.smallSpacing
//Controls.BusyIndicator {
//anchors.centerIn: parent
//visible: UserPlaylistModel.loading || UserPlaylistModel.loading
//}
Kirigami.Heading {
level: 3
Layout.fillWidth: true
elide: Qt.ElideRight
text: info.title ? info.title : i18n("No media playing")
}
//onCountChanged: {
//if (count < 1) {
//footerItem.maximized = false
//}
//}
RowLayout{
//model: UserPlaylistModel
Controls.Label{
visible: info.title
text: PlayerUtils.formatTimestamp(audio.position)
}
//delegate: Kirigami.SwipeListItem {
//id: delegateItem
//required property string title
//required property string videoId
//required property string artists
//required property bool isCurrent
Controls.Slider {
Layout.fillWidth: true
from: 0
to: audio.duration
value: audio.position
enabled: audio.seekable
onMoved: {
console.log("Value:", value);
audio.seek(Math.floor(value));
}
//highlighted: isCurrent
//onClicked: UserPlaylistModel.skipTo(videoId)
Behavior on value {
NumberAnimation {
duration: 1000
}
//ColumnLayout {
//Layout.fillWidth: true
//Kirigami.Heading {
//elide: Text.ElideRight
//Layout.fillWidth: true
//level: 2
//text: title
//}
}
//Controls.Label {
//elide: Text.ElideRight
//Layout.fillWidth: true
//text: artists
//}
//}
}
//actions: [
//Kirigami.Action {
//text: i18n("Remove Track")
//icon.name: "list-remove"
//onTriggered: UserPlaylistModel.remove(delegateItem.videoId)
//}
//]
//}
Controls.Label{
visible: info.title
text: PlayerUtils.formatTimestamp(audio.duration)
}
//header: Controls.ToolBar {
//anchors.left: parent.left
//anchors.right: parent.right
//RowLayout {
//anchors.fill: parent
//Item {
//Layout.fillWidth: true
//}
//Controls.ToolButton {
//text: i18n("Clear")
//icon.name: "edit-clear-all"
//onClicked: UserPlaylistModel.clear()
//}
//Controls.ToolButton {
//text: i18n("Shuffle")
//icon.name: "media-playlist-shuffle"
//onClicked: UserPlaylistModel.shufflePlaylist()
//}
//}
//}
//}
//}
//}
//}
//Kirigami.Separator {
//Layout.fillWidth: true
//}
//RowLayout {
//id: player
//Layout.fillWidth: true
//Layout.fillHeight: !footer.maximized
//Controls.ToolButton {
//display: Controls.AbstractButton.IconOnly
//Layout.preferredWidth: parent.height
//Layout.fillHeight: true
//enabled: info.audioUrl != ""
//text: audio.playbackState === Audio.PlayingState ? i18n("Pause") : i18n("Play")
//visible: !info.loading
//icon.name: audio.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
//onClicked: audio.playbackState === Audio.PlayingState ? audio.pause() : audio.play()
//}
//Controls.ToolButton {
//display: Controls.AbstractButton.IconOnly
//Layout.preferredWidth: parent.height
//Layout.fillHeight: true
//enabled: UserPlaylistModel.canSkip
//visible: !info.loading
//icon.name: "media-skip-forward"
//onClicked: UserPlaylistModel.next()
//}
//Controls.BusyIndicator {
//Layout.fillHeight: true
//visible: info.loading
//}
//ColumnLayout {
//Layout.fillHeight: true
//Layout.topMargin: Kirigami.Units.smallSpacing
//Layout.bottomMargin: Kirigami.Units.smallSpacing
//Kirigami.Heading {
//level: 3
//Layout.fillWidth: true
//elide: Qt.ElideRight
//text: info.title ? info.title : i18n("No media playing")
//}
//RowLayout{
//Controls.Label{
//visible: info.title
//text: PlayerUtils.formatTimestamp(audio.position)
//}
//Controls.Slider {
//Layout.fillWidth: true
//from: 0
//to: audio.duration
//value: audio.position
//enabled: audio.seekable
//onMoved: {
//console.log("Value:", value);
//audio.seek(Math.floor(value));
//}
//Behavior on value {
//NumberAnimation {
//duration: 1000
//}
//}
//}
//Controls.Label{
//visible: info.title
//text: PlayerUtils.formatTimestamp(audio.duration)
//}
//}
}
//}
}
//Controls.ToolButton {
//display: Controls.AbstractButton.IconOnly
//Layout.preferredWidth: parent.height
//text: i18n("Expand")
//enabled: playlistView.count > 0
//Layout.fillHeight: true
//icon.name: footerItem.maximized ? "arrow-down" : "arrow-up"
//onClicked: footerItem.maximized = !footerItem.maximized
//}
Controls.ToolButton {
display: Controls.AbstractButton.IconOnly
Layout.preferredWidth: parent.height
text: i18n("Expand")
enabled: playlistView.count > 0
Layout.fillHeight: true
icon.name: footerItem.maximized ? "arrow-down" : "arrow-up"
onClicked: footerItem.maximized = !footerItem.maximized
}
//}
}
}
//Behavior on height {
//NumberAnimation {
//}
//}
Behavior on height {
NumberAnimation {
}
}
}
+57 -120
View File
@@ -12,12 +12,10 @@ import org.kde.ytmusic 1.0
Kirigami.ApplicationWindow {
id: root
property alias searchField: searchLoader.item // TODO
property bool wideScreen: width >= 600
property bool showSearch: false // only applicable if not widescreen
property alias searchField: searchField
header: Controls.Control {
visible: !footer.maximized
padding: Kirigami.Units.largeSpacing
background: Rectangle {
@@ -28,62 +26,71 @@ Kirigami.ApplicationWindow {
Kirigami.Theme.colorSet: Kirigami.Theme.Header
color: Kirigami.Theme.backgroundColor
}
contentItem: RowLayout {
Controls.ToolButton {
id: searchBack
Layout.alignment: Qt.AlignLeft
visible:
(!root.wideScreen && root.showSearch && root.searchField.text === "")
|| pageStack.layers.depth > 1
text: i18n("Back")
icon.name: "go-previous-view"
display: Controls.ToolButton.IconOnly
onClicked: if (root.showSearch)
root.showSearch = false
else
pageStack.layers.pop()
}
Kirigami.Heading {
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: Kirigami.Units.largeSpacing
level: 1
text: "AudioTube"
visible: !root.wideScreen && !root.showSearch
}
// spacer
contentItem: RowLayout{
Item {
Layout.fillWidth: !root.wideScreen
Layout.fillWidth: true
}
Loader {
id: searchLoader
visible: root.wideScreen || root.showSearch
Layout.alignment: Qt.AlignHCenter
Kirigami.SearchField {
id: searchField
delaySearch: true
selectByMouse: true
Layout.fillWidth: true
Layout.maximumWidth: 400
sourceComponent: searchFieldComponent
}
Controls.ToolButton {
Layout.alignment: Qt.AlignRight
visible: !root.wideScreen && !root.showSearch
text: i18n("Search")
icon.name: "search"
display: Controls.ToolButton.TextBesideIcon
onClicked: {
root.showSearch = true
root.searchField.forceActiveFocus();
root.searchField.popup.open();
onFocusChanged: {
if (focus)
popup.open()
}
onTextChanged: {
if (!popup.opened) {
popup.open()
}
}
Controls.Popup {
id: popup
x: searchField.y
y: searchField.y + searchField.height
visible: true
width: searchField.width
height: contentItem.implicitHeight
contentItem: Controls.ScrollView {
Controls.ScrollBar.horizontal.policy: Controls.ScrollBar.AlwaysOff
ListView {
id: completionList
model: Library.searches
delegate: Controls.ItemDelegate {
width: parent.width
text: modelData
onClicked: {
searchField.text = modelData
searchField.accepted()
}
}
}
}
}
onAccepted: {
pageStack.clear()
if (text) {
Library.addSearch(text)
}
pageStack.push("qrc:/SearchPage.qml", {
"searchQuery": text})
popup.close()
}
}
Item {
Layout.fillWidth: true
}
}
}
title: i18n("AudioTube")
controlsVisible: !footer.maximized
contextDrawer: Kirigami.ContextDrawer {
id: contextDrawer
}
@@ -111,76 +118,6 @@ Kirigami.ApplicationWindow {
showPassiveNotification(error)
}
}
Component {
id: searchFieldComponent
Kirigami.SearchField {
id: searchField
delaySearch: true
selectByMouse: true
onPressed: {
popup.open()
}
property alias popup: popup
Controls.Popup {
id: popup
x: searchField.y
y: searchField.y + searchField.height
width: searchField.width
height: completionList
? Math.min(completionList.count * Kirigami.Units.gridUnit * 2 + Kirigami.Units.gridUnit * 2, Kirigami.Units.gridUnit * 20)
: Kirigami.Units.gridUnit * 20
contentItem: Controls.ScrollView {
Controls.ScrollBar.horizontal.policy: Controls.ScrollBar.AlwaysOff
ListView {
id: completionList
model: Library.searches
delegate: Controls.ItemDelegate {
Kirigami.Theme.colorSet: Kirigami.Theme.Window
Kirigami.Theme.inherit: false
id: completionDelegate
width: parent.width
height: Kirigami.Units.gridUnit * 2
text: model.display
onClicked: {
searchField.text = model.display
searchField.accepted()
}
}
}
}
}
onAccepted: {
pageStack.clear()
pageStack.layers.clear()
if (text) {
Library.addSearch(text)
pageStack.push("qrc:/SearchPage.qml", {
"searchQuery": text})
} else {
pageStack.replace("qrc:/LibraryPage.qml")
}
popup.close()
}
}
}
pageStack.anchors.bottomMargin: playerFooter.minimizedPlayerHeight + 1
// media player
PlayerFooter {
id: playerFooter
anchors.topMargin: -root.header.height
anchors.fill: parent
// only expand flicking area to full screen when it is open
z: (contentY === 0) ? -1 : 999
}
footer: PlayerFooter {}
}
+37 -176
View File
@@ -1,98 +1,79 @@
// SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "library.h"
#include "library.h"
#include <QStandardPaths>
#include <QDebug>
#include <QDir>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QStringBuilder>
#include "asyncdatabase.h"
namespace ranges = std::ranges;
#include <qpersistentdata.h>
Library::Library(QObject *parent)
: QObject{parent}
, m_database(ThreadedDatabase::establishConnection([]() -> DatabaseConfiguration {
const auto databaseDirectory = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
// Make sure the database directory exists
QDir(databaseDirectory).mkpath(QStringLiteral("."));
DatabaseConfiguration config;
config.setDatabaseName(databaseDirectory % QDir::separator() % "library.sqlite");
config.setType(DATABASE_TYPE_SQLITE);
return config;
}()))
, m_storage("library")
, m_cachedVideoTitles("videoTitles")
{
m_database->runMigrations(":/migrations/");
connect(this, &Library::favouritesChanged, this, []() {
qDebug() << "Favs changed" ;
});
}
Library::~Library() = default;
Library &Library::instance()
{
static Library inst;
return inst;
}
FavouritesModel *Library::favourites()
QStringList Library::favourites() const
{
auto future = m_database->getResults<Song>("select * from favourites natural join songs");
return new FavouritesModel(std::move(future), this);
return m_storage.value<QStringList>("favourites");
}
void Library::addFavourite(const QString &videoId, const QString &title)
void Library::addFavourite(const QString &videoId)
{
connectFuture(addSong(videoId, title), this, [=, this] {
connectFuture(m_database->execute("insert or ignore into favourites (video_id) values (?)", videoId), this, &Library::favouritesChanged);
});
auto favs = favourites();
favs.push_front(videoId);
m_storage.insert("favourites", favs);
Q_EMIT favouritesChanged();
}
void Library::removeFavourite(const QString &videoId)
QStringList Library::searches() const
{
connectFuture(m_database->execute("delete from favourites where video_id = ?", videoId), this, &Library::favouritesChanged);
}
FavouriteWatcher *Library::favouriteWatcher(const QString &videoId)
{
if (videoId.isEmpty()) {
return nullptr;
}
return new FavouriteWatcher(this, videoId);
}
SearchHistoryModel *Library::searches()
{
return new SearchHistoryModel(m_database->getResults<SingleValue<QString>>("select (search_query) from searches order by search_id desc"), this);
auto s = m_storage.value<QStringList>("searches");
qDebug() << "searches" << s;
return s;
}
void Library::addSearch(const QString &text)
{
connectFuture(m_database->execute("insert into searches (search_query) values (?)", text), this, &Library::searchesChanged);
m_storage.insert("searches", searches() << text);
Q_EMIT searchesChanged();
}
PlaybackHistoryModel *Library::playbackHistory()
QStringList Library::playbackHistory() const
{
auto future = m_database->getResults<PlayedSong>("select * from played_songs natural join songs");
return new PlaybackHistoryModel(std::move(future), this);
auto h = m_storage.value<QStringList>("playbackHistory");
return h;
}
void Library::addPlaybackHistoryItem(const QString &videoId, const QString &title)
void Library::addPlaybackHistoryItem(const QString &videoId)
{
connectFuture(addSong(videoId, title), this, [=, this] {
connectFuture(m_database->execute("insert or ignore into played_songs (video_id, plays) values (?, ?)", videoId, 0), this, [=, this] {
connectFuture(m_database->execute("update played_songs set plays = plays + 1 where video_id = ? ", videoId), this, &Library::playbackHistoryChanged);
});
});
m_storage.insert("playbackHistory", playbackHistory() << videoId);
Q_EMIT playbackHistoryChanged();
}
PlaybackHistoryModel *Library::mostPlayed()
QString Library::videoTitle(const QString &videoId)
{
auto future = m_database->getResults<PlayedSong>("select * from played_songs natural join songs order by plays desc limit 10");
return new PlaybackHistoryModel(std::move(future), this);
qDebug() << "Fetching video title" << videoId;
auto t = m_cachedVideoTitles.value<QString>(videoId);
qDebug() << "title" << t;
return t;
}
void Library::addVideoTitle(const QString &videoId, const QString &title)
{
m_cachedVideoTitles.insert(videoId, title);
}
QNetworkAccessManager &Library::nam()
@@ -100,11 +81,6 @@ QNetworkAccessManager &Library::nam()
return m_networkImageCacher;
}
QFuture<void> Library::addSong(const QString &videoId, const QString &title)
{
return m_database->execute("insert or ignore into songs (video_id, title, artist, album) values (?, ?, null, null)", videoId, title);
}
void ThumbnailSource::setVideoId(const QString &id) {
if (m_videoId == id) {
return;
@@ -133,118 +109,3 @@ void ThumbnailSource::setVideoId(const QString &id) {
});
});
}
PlaybackHistoryModel::PlaybackHistoryModel(QFuture<std::vector<PlayedSong> > &&songs, QObject *parent)
: QAbstractListModel(parent)
{
connectFuture(songs, this, [this](const auto songs) {
beginResetModel();
m_playedSongs = songs;
endResetModel();
});
}
QHash<int, QByteArray> PlaybackHistoryModel::roleNames() const {
return {
{Roles::VideoId, "videoId"},
{Roles::Title, "title"},
{Roles::Artist, "artists"},
{Roles::Plays, "plays"}
};
}
int PlaybackHistoryModel::rowCount(const QModelIndex &parent) const {
return parent.isValid() ? 0 : m_playedSongs.size();
}
QVariant PlaybackHistoryModel::data(const QModelIndex &index, int role) const {
switch (role) {
case Roles::VideoId:
return m_playedSongs.at(index.row()).videoId;
case Roles::Title:
return m_playedSongs.at(index.row()).title;
case Roles::Artist:
return m_playedSongs.at(index.row()).artist;
case Roles::Plays:
return m_playedSongs.at(index.row()).plays;
}
Q_UNREACHABLE();
}
FavouritesModel::FavouritesModel(QFuture<std::vector<Song>> &&songs, QObject *parent)
: QAbstractListModel(parent)
{
connectFuture(songs, this, [this](const auto songs) {
beginResetModel();
m_favouriteSongs = songs;
endResetModel();
});
}
QHash<int, QByteArray> FavouritesModel::roleNames() const {
return {
{Roles::VideoId, "videoId"},
{Roles::Title, "title"},
{Roles::Artist, "artists"}
};
}
int FavouritesModel::rowCount(const QModelIndex &parent) const {
return parent.isValid() ? 0 : m_favouriteSongs.size();
}
QVariant FavouritesModel::data(const QModelIndex &index, int role) const {
switch (role) {
case Roles::VideoId:
return m_favouriteSongs.at(index.row()).videoId;
case Roles::Title:
return m_favouriteSongs.at(index.row()).title;
case Roles::Artist:
return m_favouriteSongs.at(index.row()).artist;
}
Q_UNREACHABLE();
}
FavouriteWatcher::FavouriteWatcher(Library *library, const QString &videoId)
: QObject(library), m_videoId(videoId), m_library(library)
{
auto update = [this] {
connectFuture(m_library->database().getResult<SingleValue<int>>("select count(*) from favourites where video_id = ?", m_videoId), this, [this](auto count) {
if (count) {
m_isFavourite = count->value > 0;
Q_EMIT isFavouriteChanged();
}
});
};
update();
connect(library, &Library::favouritesChanged, this, update);
}
bool FavouriteWatcher::isFavourite() const {
return m_isFavourite;
}
SearchHistoryModel::SearchHistoryModel(QFuture<std::vector<SingleValue<QString>>> &&historyFuture, QObject *parent)
: QAbstractListModel(parent)
{
connectFuture(historyFuture, this, [this](const auto history) {
beginResetModel();
m_history = history;
endResetModel();
});
}
int SearchHistoryModel::rowCount(const QModelIndex &parent) const {
return parent.isValid() ? 0 : m_history.size();
}
QVariant SearchHistoryModel::data(const QModelIndex &index, int role) const {
switch (role) {
case Qt::DisplayRole:
return m_history[index.row()].value;
}
Q_UNREACHABLE();
}
+13 -130
View File
@@ -1,143 +1,45 @@
// SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#pragma once
#include <QObject>
#include <QQuickAsyncImageProvider>
#include <QNetworkAccessManager>
#include <QAbstractListModel>
#include <memory>
#include <qpersistentdata.h>
#include "asyncytmusic.h"
#include "asyncdatabase.h"
class FavouriteWatcher;
struct Song {
using ColumnTypes = std::tuple<QString, QString, QString, QString>;
static Song fromSql(ColumnTypes tuple) {
auto [videoId, title, artist, album] = tuple;
return Song {videoId, title, artist, album};
}
QString videoId;
QString title;
QString artist;
QString album;
};
class FavouritesModel : public QAbstractListModel {
Q_OBJECT
enum Roles {
VideoId = Qt::UserRole + 1,
Title,
Artist,
};
public:
FavouritesModel(QFuture<std::vector<Song>> &&songs, QObject *parent = nullptr);
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
private:
std::vector<Song> m_favouriteSongs;
};
struct PlayedSong {
using ColumnTypes = std::tuple<QString, int, QString, QString, QString>;
static PlayedSong fromSql(ColumnTypes tuple) {
auto [videoId, plays, title, artist, album] = tuple;
return PlayedSong {videoId, title, artist, album, plays};
}
QString videoId;
QString title;
QString artist;
QString album;
int plays;
};
class PlaybackHistoryModel : public QAbstractListModel {
Q_OBJECT
enum Roles {
VideoId = Qt::UserRole + 1,
Title,
Artist,
Plays
};
public:
PlaybackHistoryModel(QFuture<std::vector<PlayedSong>> &&songs, QObject *parent = nullptr);
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
private:
std::vector<PlayedSong> m_playedSongs;
};
class SearchHistoryModel : public QAbstractListModel {
Q_OBJECT
public:
SearchHistoryModel(QFuture<std::vector<SingleValue<QString>>> &&historyFuture, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
private:
std::vector<SingleValue<QString>> m_history;
};
class Library : public QObject
{
Q_OBJECT
Q_PROPERTY(QAbstractListModel *favourites READ favourites NOTIFY favouritesChanged)
Q_PROPERTY(QAbstractListModel *searches READ searches NOTIFY searchesChanged)
Q_PROPERTY(QAbstractListModel *playbackHistory READ playbackHistory NOTIFY playbackHistoryChanged)
Q_PROPERTY(QAbstractListModel *mostPlayed READ mostPlayed NOTIFY playbackHistoryChanged)
Q_PROPERTY(QStringList favourites READ favourites NOTIFY favouritesChanged)
Q_PROPERTY(QStringList searches READ searches NOTIFY searchesChanged)
Q_PROPERTY(QStringList playbackHistory READ playbackHistory NOTIFY playbackHistoryChanged)
public:
explicit Library(QObject *parent = nullptr);
~Library();
static Library &instance();
FavouritesModel *favourites();
QStringList favourites() const;
Q_SIGNAL void favouritesChanged();
Q_INVOKABLE void addFavourite(const QString &videoId, const QString &title);
Q_INVOKABLE void removeFavourite(const QString &videoId);
Q_INVOKABLE FavouriteWatcher *favouriteWatcher(const QString &videoId);
Q_INVOKABLE void addFavourite(const QString &videoId);
SearchHistoryModel *searches();
QStringList searches() const;
Q_SIGNAL void searchesChanged();
Q_INVOKABLE void addSearch(const QString &text);
PlaybackHistoryModel *playbackHistory();
QStringList playbackHistory() const;
Q_SIGNAL void playbackHistoryChanged();
Q_INVOKABLE void addPlaybackHistoryItem(const QString &videoId, const QString &title);
Q_INVOKABLE void addPlaybackHistoryItem(const QString &videoId);
PlaybackHistoryModel *mostPlayed();
Q_INVOKABLE QString videoTitle(const QString &videoId);
Q_INVOKABLE void addVideoTitle(const QString &videoId, const QString &title);
QNetworkAccessManager &nam();
ThreadedDatabase &database() {
return *m_database;
}
private:
QFuture<void> addSong(const QString &videoId, const QString &title);
QNetworkAccessManager m_networkImageCacher;
std::unique_ptr<ThreadedDatabase> m_database;
QPersistentData m_storage;
QPersistentData m_cachedVideoTitles;
};
@@ -166,22 +68,3 @@ private:
QString m_videoId;
QUrl m_cachedPath;
};
class FavouriteWatcher : public QObject {
Q_OBJECT
Q_PROPERTY(bool isFavourite READ isFavourite NOTIFY isFavouriteChanged)
public:
FavouriteWatcher(Library *library, const QString &videoId);
bool isFavourite() const;
Q_SIGNAL void isFavouriteChanged();
Q_SIGNAL void videoIdChanged();
private:
QString m_videoId;
Library *m_library;
bool m_isFavourite = false;
};
+3 -4
View File
@@ -21,8 +21,6 @@
#include "playerutils.h"
#include "library.h"
#include "asyncdatabase.h"
constexpr auto URI = "org.kde.ytmusic";
Q_DECL_EXPORT int main(int argc, char *argv[])
@@ -54,9 +52,10 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
qmlRegisterSingletonType<PlayerUtils>(URI, 1, 0, "PlayerUtils", [](QQmlEngine *, QJSEngine *) {
return new PlayerUtils();
});
qmlRegisterSingletonInstance<Library>(URI, 1, 0, "Library", &Library::instance());
qmlRegisterSingletonType<Library>(URI, 1, 0, "Library", [](QQmlEngine *, QJSEngine *) {
return new Library();
});
qmlRegisterType<ThumbnailSource>(URI, 1, 0, "ThumbnailSource");
qmlRegisterAnonymousType<FavouriteWatcher>(URI, 1);
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
View File
Whitespace-only changes.
@@ -1,8 +0,0 @@
-- SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
--
-- SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
drop table songs;
drop table played_songs;
drop table favourites;
drop table searches;
@@ -1,26 +0,0 @@
-- SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
--
-- SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
create table songs (
video_id Text primary key not null,
title Text not null,
artist Text,
album Text
);
create table played_songs (
video_id Text primary key not null,
plays Int not null,
foreign key (video_id) references songs(video_id)
);
create table favourites (
video_id Text primary key not null,
foreign key (video_id) references songs(video_id)
);
create table searches (
search_id integer primary key autoincrement not null,
search_query Text not null
);
-11
View File
@@ -1,9 +1,3 @@
<!--
SPDX-FileCopyrightText: 2021 Jonah Brüchert <[email protected]>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<RCC>
<qresource prefix="/">
<file alias="main.qml">contents/ui/main.qml</file>
@@ -14,10 +8,5 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<file alias="PlaylistPage.qml">contents/ui/PlaylistPage.qml</file>
<file alias="ConfirmationMessage.qml">contents/ui/ConfirmationMessage.qml</file>
<file alias="LibraryPage.qml">contents/ui/LibraryPage.qml</file>
<file alias="MinimizedPlayerControls.qml">contents/ui/MinimizedPlayerControls.qml</file>
<file alias="MaximizedPlayerPage.qml">contents/ui/MaximizedPlayerPage.qml</file>
<file>migrations/2022-05-20-194850_init/down.sql</file>
<file>migrations/2022-05-20-194850_init/up.sql</file>
<file alias="PlaybackHistory.qml">contents/ui/PlaybackHistory.qml</file>
</qresource>
</RCC>
+1 -14
View File
@@ -17,8 +17,6 @@ VideoInfoExtractor::VideoInfoExtractor(QObject *parent)
m_videoInfo = {};
Q_EMIT audioUrlChanged();
Q_EMIT titleChanged();
Q_EMIT artistChanged();
Q_EMIT channelChanged();
Q_EMIT songChanged();
Q_EMIT thumbnailChanged();
return;
@@ -30,10 +28,9 @@ VideoInfoExtractor::VideoInfoExtractor(QObject *parent)
connectFuture(future, this, [this](const video_info::VideoInfo &videoInfo) {
m_videoInfo = videoInfo;
setLoading(false);
Library::instance().addVideoTitle(m_videoId, QString::fromStdString(m_videoInfo.title));
Q_EMIT audioUrlChanged();
Q_EMIT titleChanged();
Q_EMIT artistChanged();
Q_EMIT channelChanged();
Q_EMIT songChanged();
Q_EMIT thumbnailChanged();
});
@@ -85,16 +82,6 @@ QString VideoInfoExtractor::title() const
return QString::fromStdString(m_videoInfo.title);
}
QString VideoInfoExtractor::artist() const
{
return QString::fromStdString(m_videoInfo.artist);
}
QString VideoInfoExtractor::channel() const
{
return QString::fromStdString(m_videoInfo.channel);
}
QString VideoInfoExtractor::thumbnail() const
{
return QString::fromStdString(m_videoInfo.thumbnail);
-8
View File
@@ -17,8 +17,6 @@ class VideoInfoExtractor : public QObject
Q_PROPERTY(QUrl audioUrl READ audioUrl NOTIFY audioUrlChanged)
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(QString artist READ artist NOTIFY artistChanged) // may be empty if it is a video
Q_PROPERTY(QString channel READ channel NOTIFY channelChanged)
Q_PROPERTY(QString thumbnail READ thumbnail NOTIFY thumbnailChanged)
Q_PROPERTY(bool loading READ loading WRITE setLoading NOTIFY loadingChanged)
@@ -34,12 +32,6 @@ public:
QString title() const;
Q_SIGNAL void titleChanged();
QString artist() const;
Q_SIGNAL void artistChanged();
QString channel() const;
Q_SIGNAL void channelChanged();
QString thumbnail() const;
Q_SIGNAL void thumbnailChanged();
+2 -4
View File
@@ -21,7 +21,7 @@ void pyPrintPretty(py::handle obj) {
#define UNEXPORT __attribute__ ((visibility("hidden")))
constexpr auto TESTED_YTMUSICAPI_VERSION = "0.22.0";
constexpr auto TESTED_YTMUSICAPI_VERSION = "0.20.0";
struct UNEXPORT YTMusicPrivate {
py::scoped_interpreter guard {};
@@ -460,12 +460,10 @@ video_info::VideoInfo YTMusic::extract_video_info(const std::string &video_id) c
using namespace pybind11::literals;
const auto info = d->get_ytdl().attr("extract_info")(video_id, "download"_a=py::bool_(false));
return {
info["id"].cast<std::string>(),
info["title"].cast<std::string>(),
info.contains("artist") ? info["artist"].cast<std::string>() : "",
info.contains("channel") ? info["channel"].cast<std::string>() : "",
extract_py_list<video_info::Format>(info["formats"]),
info["thumbnail"].cast<std::string>()
};
-2
View File
@@ -241,8 +241,6 @@ struct Format {
struct VideoInfo {
std::string id;
std::string title;
std::string artist;
std::string channel;
std::vector<Format> formats;
std::string thumbnail;