Merge branch 'upcoming' of https://github.com/ciderapp/Cider into upcoming
This commit is contained in:
commit
40cafaeeaa
16 changed files with 573 additions and 194 deletions
|
@ -134,6 +134,13 @@
|
||||||
"publisherDisplayName": "Cider Collective",
|
"publisherDisplayName": "Cider Collective",
|
||||||
"backgroundColor": "transparent",
|
"backgroundColor": "transparent",
|
||||||
"setBuildNumber": true
|
"setBuildNumber": true
|
||||||
|
},
|
||||||
|
"nsis": {
|
||||||
|
"oneClick": false,
|
||||||
|
"perMachine": false,
|
||||||
|
"allowToChangeInstallationDirectory": true,
|
||||||
|
"license": "LICENSE",
|
||||||
|
"deleteAppDataOnUninstall": true
|
||||||
},
|
},
|
||||||
"win": {
|
"win": {
|
||||||
"target": [
|
"target": [
|
||||||
|
|
95
src/i18n/el_GR.jsonc
Normal file
95
src/i18n/el_GR.jsonc
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
// App info
|
||||||
|
"app.name": "Cider",
|
||||||
|
// Dialogs
|
||||||
|
"dialog.cancel": "Ακύρωση",
|
||||||
|
"dialog.ok": "ΟΚ",
|
||||||
|
// Terms
|
||||||
|
"term.appleMusic": "Apple Music",
|
||||||
|
"term.applePodcasts": "Apple Podcasts",
|
||||||
|
"term.itunes": "iTunes",
|
||||||
|
"term.github": "GitHub",
|
||||||
|
"term.discord": "Discord",
|
||||||
|
"term.learnMore": "Μάθετε Περισσότερα",
|
||||||
|
"term.accountSettings": "Ρυθμίσεις Λογαριασμού",
|
||||||
|
"term.logout": "Αποσύνδεση",
|
||||||
|
"term.login": "Σύνδεση",
|
||||||
|
"term.about": "Σχετικά με",
|
||||||
|
"term.privateSession": "Ιδιωτική Περίοδος Λειτουργίας",
|
||||||
|
"term.queue": "Ουρά",
|
||||||
|
"term.search": "Εύρεση",
|
||||||
|
"term.library": "Βιβλιοθήκη",
|
||||||
|
"term.recentlyAdded": "Πρόσφατες Προσθήκες",
|
||||||
|
"term.songs": "Τραγούδια",
|
||||||
|
"term.albums": "Άλμπουμ",
|
||||||
|
"term.artists": "Καλλιτέχνες",
|
||||||
|
"term.podcasts": "Podcast",
|
||||||
|
"term.playlists": "Λίστες Αναπαραγωγής",
|
||||||
|
"term.playlist": "Λίστα Αναπαραγωγής",
|
||||||
|
"term.play": "Αναπαραγωγή",
|
||||||
|
"term.pause": "Παύση",
|
||||||
|
"term.previous": "Προηγούμενο",
|
||||||
|
"term.next": "Επόμενο",
|
||||||
|
"term.shuffle": "Τυχαία Σειρά",
|
||||||
|
"term.repeat": "Επανάληψη",
|
||||||
|
"term.volume": "Ένταση",
|
||||||
|
"term.mute": "Σίγαση",
|
||||||
|
"term.unmute": "Κατάργηση Σίγασης",
|
||||||
|
"term.share": "Κοινή Χρήση",
|
||||||
|
"term.settings": "Ρυθμίσεις",
|
||||||
|
"term.seeAll": "Προβολή Όλων",
|
||||||
|
// Home
|
||||||
|
"home.title": "Αρχική",
|
||||||
|
"home.recentlyPlayed": "Έπαιξαν Πρόσφατα",
|
||||||
|
"home.recentlyAdded": "Πρόσφατες Προσθήκες",
|
||||||
|
"home.artistsFeed": "Ροή των Καλλιτεχνών σου",
|
||||||
|
"home.madeForYou": "Δημιουργήθηκε Για Εσάς",
|
||||||
|
"home.friendsListeningTo": "Οι Φίλοι σου Ακούν",
|
||||||
|
"home.followedArtists": "Καλλιτέχνες που Ακολουθείτε",
|
||||||
|
// Errors
|
||||||
|
"error.appleMusicSubRequired": "Το Apple Music απαιτεί μια συνδρομή.",
|
||||||
|
// Actions
|
||||||
|
"action.addToLibrary": "Προσθήκη στη Βιβλιοθήκη",
|
||||||
|
"action.addToLibrary.success": "Προστέθηκε στη Βιβλιοθήκη",
|
||||||
|
"action.addToLibrary.error": "Σφάλμα Προσθήκης στη Βιβλιοθήκης",
|
||||||
|
"action.removeFromLibrary": "Αφαίρεση από τη Βιβλιοθήκη",
|
||||||
|
"action.removeFromLibrary.success": "Αφαιρέθηκε από τη Βιβλιοθήκη",
|
||||||
|
"action.addToQueue": "Προσθήκη στην Ουρά",
|
||||||
|
"action.addToQueue.success": "Προστέθηκε στην Ουρά",
|
||||||
|
"action.addToQueue.error": "Προστέθηκε στην Ουρά",
|
||||||
|
"action.removeFromQueue": "Αφαίρεση από την Ουρά",
|
||||||
|
"action.removeFromQueue.success": "Αφαιρέθηκε από την Ουρά",
|
||||||
|
"action.removeFromQueue.error": "Σφάλμα Αφαίρεσης από την Ουρά",
|
||||||
|
"action.follow": "Ακολούθηση",
|
||||||
|
"action.follow.success": "Ακολουθήθηκε",
|
||||||
|
"action.follow.error": "Σφάλμα Ακολούθησης",
|
||||||
|
"action.unfollow": "Διακοπή Ακολούθησης",
|
||||||
|
"action.unfollow.success": "Έγινε Διακοπή Ακολούθησης",
|
||||||
|
"action.unfollow.error": "Σφάλμα Διακοπής Ακολούθησης ",
|
||||||
|
"action.playNext": "Αναπαραγωγή ως Επόμενου",
|
||||||
|
"action.playLater": "Αναπαραγωγή Αργότερα",
|
||||||
|
"action.startRadio": "Έναρξη Σταθμού",
|
||||||
|
"action.goToArtist": "Μετάβαση σε Καλλιτέχνη",
|
||||||
|
"action.goToAlbum": "Μετάβαση σε Άλμπουμ",
|
||||||
|
"action.share": "Κοινή Χρήση",
|
||||||
|
"action.love": "Μου αρέσει πολύ",
|
||||||
|
"action.unlove": "Αναίρεση \"Μου Αρέσει\"",
|
||||||
|
"action.dislike": "Δεν μου αρέσει",
|
||||||
|
"action.undoDislike": "Αναίρεση \"Δεν μου αρέσει\"",
|
||||||
|
// Settings
|
||||||
|
"settings.header.audio": "Ήχος",
|
||||||
|
"settings.header.audio.description": "Προσαρμογή ρυθμίσεων ήχου για το Cider.",
|
||||||
|
"settings.header.audio.quality.high": "Υψηλή",
|
||||||
|
"settings.header.audio.quality.low": "Χαμηλή",
|
||||||
|
"settings.header.audio.quality.auto": "Αυτόματη",
|
||||||
|
"settings.header.visual": "Οπτικά",
|
||||||
|
"settings.header.visual.description": "Προσαρμογή οπτικών ρυθμίσεων για το Cider.",
|
||||||
|
"settings.header.general": "Γενικά",
|
||||||
|
"settings.header.general.description": "Προσαρμογή γενικών ρυθμίσεων για το Cider.",
|
||||||
|
"settings.header.lyrics": "Στίχοι",
|
||||||
|
"settings.header.lyrics.description": "Προσαρμογή ρυθμίσεων στίχων για το Cider.",
|
||||||
|
"settings.header.connectivity": "Σύνδεση",
|
||||||
|
"settings.header.connectivity.description": "Προσαρμογή ρυθμίσεων σύνδεσης για το Cider.",
|
||||||
|
"settings.header.experimental": "Πειραματικές",
|
||||||
|
"settings.header.experimental.description": "Προσαρμογή πειραματικών ρυθμίσεων για το Cider."
|
||||||
|
}
|
95
src/i18n/ja_JP.jsonc
Normal file
95
src/i18n/ja_JP.jsonc
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
// App info
|
||||||
|
"app.name": "Cider",
|
||||||
|
// Dialogs
|
||||||
|
"dialog.cancel": "キャンセル",
|
||||||
|
"dialog.ok": "OK",
|
||||||
|
// Terms
|
||||||
|
"term.appleMusic": "Apple Music", // Follows brand term
|
||||||
|
"term.applePodcasts": "Apple Podcasts", // Follows brand term
|
||||||
|
"term.itunes": "iTunes", // Follows brand term
|
||||||
|
"term.github": "GitHub", // Follows brand term
|
||||||
|
"term.discord": "Discord", // Follows brand term
|
||||||
|
"term.learnMore": "詳しい情報",
|
||||||
|
"term.accountSettings": "アカウント設定",
|
||||||
|
"term.logout": "サインアウト",
|
||||||
|
"term.login": "サインイン",
|
||||||
|
"term.about": "アプリについて",
|
||||||
|
"term.privateSession": "プライベートセッション",
|
||||||
|
"term.queue": "次はこちら",
|
||||||
|
"term.search": "検索",
|
||||||
|
"term.library": "ライブラリ",
|
||||||
|
"term.recentlyAdded": "最近追加した項目",
|
||||||
|
"term.songs": "曲",
|
||||||
|
"term.albums": "アルバム",
|
||||||
|
"term.artists": "アーティスト",
|
||||||
|
"term.podcasts": "Podcast",
|
||||||
|
"term.playlists": "プレイリスト",
|
||||||
|
"term.playlist": "プレイリスト",
|
||||||
|
"term.play": "再生",
|
||||||
|
"term.pause": "停止",
|
||||||
|
"term.previous": "戻る",
|
||||||
|
"term.next": "次へ",
|
||||||
|
"term.shuffle": "シャッフル",
|
||||||
|
"term.repeat": "リピート",
|
||||||
|
"term.volume": "音量",
|
||||||
|
"term.mute": "ミュート",
|
||||||
|
"term.unmute": "ミュート解除",
|
||||||
|
"term.share": "共有",
|
||||||
|
"term.settings": "設定",
|
||||||
|
"term.seeAll": "全部表示",
|
||||||
|
// Home
|
||||||
|
"home.title": "ホーム",
|
||||||
|
"home.recentlyPlayed": "最近の再生",
|
||||||
|
"home.recentlyAdded": "最近追加した項目",
|
||||||
|
"home.artistsFeed": "アーティストのフィード",
|
||||||
|
"home.madeForYou": "あなたにおすすめ",
|
||||||
|
"home.friendsListeningTo": "友達が聴いている",
|
||||||
|
"home.followedArtists": "フォローしているアーティスト",
|
||||||
|
// Errors
|
||||||
|
"error.appleMusicSubRequired": "Apple Musicのサブスクリプションが必要です。",
|
||||||
|
// Actions
|
||||||
|
"action.addToLibrary": "ライブラリに追加",
|
||||||
|
"action.addToLibrary.success": "ライブラリに追加されました",
|
||||||
|
"action.addToLibrary.error": "ついか",
|
||||||
|
"action.removeFromLibrary": "ライブラリから削除",
|
||||||
|
"action.removeFromLibrary.success": "ライブラリから削除されました",
|
||||||
|
"action.addToQueue": "キューに追加",
|
||||||
|
"action.addToQueue.success": "キューに追加されました",
|
||||||
|
"action.addToQueue.error": "操作を完了できませんでした",
|
||||||
|
"action.removeFromQueue": "キューから削除",
|
||||||
|
"action.removeFromQueue.success": "キューから削除されました",
|
||||||
|
"action.removeFromQueue.error": "操作を完了できませんでした",
|
||||||
|
"action.follow": "フォロー",
|
||||||
|
"action.follow.success": "フォロー中",
|
||||||
|
"action.follow.error": "操作を完了できませんでした",
|
||||||
|
"action.unfollow": "フォロー解除",
|
||||||
|
"action.unfollow.success": "フォローをやめました",
|
||||||
|
"action.unfollow.error": "操作を完了できませんでした",
|
||||||
|
"action.playNext": "次に再生",
|
||||||
|
"action.playLater": "最後に再生",
|
||||||
|
"action.startRadio": "ステーションを作成",
|
||||||
|
"action.goToArtist": "アーティストへ移動",
|
||||||
|
"action.goToAlbum": "アルバムへ移動",
|
||||||
|
"action.share": "曲を共有",
|
||||||
|
"action.love": "ラブ",
|
||||||
|
"action.unlove": "ラブを解除",
|
||||||
|
"action.dislike": "これに似たものをすすめない",
|
||||||
|
"action.undoDislike": "「これと似た曲のおすすめを減らす」を取り消す",
|
||||||
|
// Settings
|
||||||
|
"settings.header.audio": "オーディオ",
|
||||||
|
"settings.header.audio.description": "Ciderのオーディオ設定",
|
||||||
|
"settings.header.audio.quality.high": "高品質",
|
||||||
|
"settings.header.audio.quality.low": "高効率",
|
||||||
|
"settings.header.audio.quality.auto": "自動",
|
||||||
|
"settings.header.visual": "ビジュアル",
|
||||||
|
"settings.header.visual.description": "Ciderのビジュアル設定",
|
||||||
|
"settings.header.general": "一般",
|
||||||
|
"settings.header.general.description": "Ciderの一般設定",
|
||||||
|
"settings.header.lyrics": "歌詞",
|
||||||
|
"settings.header.lyrics.description": "歌詞の表示設定",
|
||||||
|
"settings.header.connectivity": "アプリと連携",
|
||||||
|
"settings.header.connectivity.description": "Ciderの連携設定",
|
||||||
|
"settings.header.experimental": "試験的な機能",
|
||||||
|
"settings.header.experimental.description": "Ciderの試験的な機能",
|
||||||
|
}
|
95
src/i18n/zh_CN.jsonc
Normal file
95
src/i18n/zh_CN.jsonc
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
// App info
|
||||||
|
"app.name": "Cider",
|
||||||
|
// Dialogs
|
||||||
|
"dialog.cancel": "取消",
|
||||||
|
"dialog.ok": "确定",
|
||||||
|
// Terms
|
||||||
|
"term.appleMusic": "Apple Music", // Follows brand term
|
||||||
|
"term.applePodcasts": "Apple Podcasts", // Follows brand term
|
||||||
|
"term.itunes": "iTunes", // Follows brand term
|
||||||
|
"term.github": "GitHub", // Follows brand term
|
||||||
|
"term.discord": "Discord", // Follows brand term
|
||||||
|
"term.learnMore": "更多信息",
|
||||||
|
"term.accountSettings": "账户设置",
|
||||||
|
"term.logout": "登出",
|
||||||
|
"term.login": "登录",
|
||||||
|
"term.about": "关于",
|
||||||
|
"term.privateSession": "私人聆听",
|
||||||
|
"term.queue": "队列",
|
||||||
|
"term.search": "搜索",
|
||||||
|
"term.library": "音乐库",
|
||||||
|
"term.recentlyAdded": "最近添加",
|
||||||
|
"term.songs": "歌曲",
|
||||||
|
"term.albums": "专辑",
|
||||||
|
"term.artists": "歌手",
|
||||||
|
"term.podcasts": "播客",
|
||||||
|
"term.playlists": "播放列表",
|
||||||
|
"term.playlist": "播放列表",
|
||||||
|
"term.play": "播放",
|
||||||
|
"term.pause": "暂停",
|
||||||
|
"term.previous": "上一首",
|
||||||
|
"term.next": "下一首",
|
||||||
|
"term.shuffle": "随机播放",
|
||||||
|
"term.repeat": "重复播放",
|
||||||
|
"term.volume": "音量",
|
||||||
|
"term.mute": "静音",
|
||||||
|
"term.unmute": "解除静音",
|
||||||
|
"term.share": "分享",
|
||||||
|
"term.settings": "设置",
|
||||||
|
"term.seeAll": "查看全部",
|
||||||
|
// Home
|
||||||
|
"home.title": "主页",
|
||||||
|
"home.recentlyPlayed": "最近播放",
|
||||||
|
"home.recentlyAdded": "最近添加",
|
||||||
|
"home.artistsFeed": "您的歌手推荐",
|
||||||
|
"home.madeForYou": "为您量身定制",
|
||||||
|
"home.friendsListeningTo": "朋友正在听",
|
||||||
|
"home.followedArtists": "关注的歌手",
|
||||||
|
// Errors
|
||||||
|
"error.appleMusicSubRequired": "需要订阅Apple Music以使用Cider",
|
||||||
|
// Actions
|
||||||
|
"action.addToLibrary": "加入音乐库",
|
||||||
|
"action.addToLibrary.success": "成功加入音乐库",
|
||||||
|
"action.addToLibrary.error": "加入音乐库的过程发生了错误",
|
||||||
|
"action.removeFromLibrary": "从音乐库中移除",
|
||||||
|
"action.removeFromLibrary.success": "已从音乐库中移除",
|
||||||
|
"action.addToQueue": "加入队列",
|
||||||
|
"action.addToQueue.success": "成功加入队列",
|
||||||
|
"action.addToQueue.error": "加入队列的过程发生了错误",
|
||||||
|
"action.removeFromQueue": "从队列中移除",
|
||||||
|
"action.removeFromQueue.success": "已从队列中移除",
|
||||||
|
"action.removeFromQueue.error": "从队列中移除的过程发生了错误",
|
||||||
|
"action.follow": "关注",
|
||||||
|
"action.follow.success": "已关注",
|
||||||
|
"action.follow.error": "尝试关注的过程发生了错误",
|
||||||
|
"action.unfollow": "取消关注",
|
||||||
|
"action.unfollow.success": "已取消关注",
|
||||||
|
"action.unfollow.error": "尝试取消关注的过程发生了错误",
|
||||||
|
"action.playNext": "下一首播放",
|
||||||
|
"action.playLater": "最后播放",
|
||||||
|
"action.startRadio": "开始电台",
|
||||||
|
"action.goToArtist": "前往歌手",
|
||||||
|
"action.goToAlbum": "前往专辑",
|
||||||
|
"action.share": "分享歌曲",
|
||||||
|
"action.love": "喜欢",
|
||||||
|
"action.unlove": "取消喜欢",
|
||||||
|
"action.dislike": "减少此类建议",
|
||||||
|
"action.undoDislike": "撤销减少此类建议",
|
||||||
|
// Settings
|
||||||
|
"settings.header.audio": "音频",
|
||||||
|
"settings.header.audio.description": "调整Cider的音质",
|
||||||
|
"settings.header.audio.quality.high": "高音质",
|
||||||
|
"settings.header.audio.quality.low": "高效率",
|
||||||
|
"settings.header.audio.quality.auto": "自动",
|
||||||
|
"settings.header.visual": "外观",
|
||||||
|
"settings.header.visual.description": "调整Cider的外观",
|
||||||
|
"settings.header.general": "通用",
|
||||||
|
"settings.header.general.description": "调整Cider的通用设置",
|
||||||
|
"settings.header.lyrics": "歌词",
|
||||||
|
"settings.header.lyrics.description": "调整Cider的歌词设置",
|
||||||
|
"settings.header.connectivity": "外部连接",
|
||||||
|
"settings.header.connectivity.description": "调整Cider与外部的连接",
|
||||||
|
"settings.header.experimental": "实验性功能",
|
||||||
|
"settings.header.experimental.description": "调整Cider的实验性功能",
|
||||||
|
}
|
95
src/i18n/zh_TW.jsonc
Normal file
95
src/i18n/zh_TW.jsonc
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
// App info
|
||||||
|
"app.name": "Cider",
|
||||||
|
// Dialogs
|
||||||
|
"dialog.cancel": "取消",
|
||||||
|
"dialog.ok": "OK",
|
||||||
|
// Terms
|
||||||
|
"term.appleMusic": "Apple Music", // Follows brand term
|
||||||
|
"term.applePodcasts": "Apple Podcasts", // Follows brand term
|
||||||
|
"term.itunes": "iTunes", // Follows brand term
|
||||||
|
"term.github": "GitHub", // Follows brand term
|
||||||
|
"term.discord": "Discord", // Follows brand term
|
||||||
|
"term.learnMore": "更多内容",
|
||||||
|
"term.accountSettings": "賬戶設定",
|
||||||
|
"term.logout": "登出",
|
||||||
|
"term.login": "登入",
|
||||||
|
"term.about": "關於",
|
||||||
|
"term.privateSession": "私人時段",
|
||||||
|
"term.queue": "待播清單",
|
||||||
|
"term.search": "搜尋",
|
||||||
|
"term.library": "資料庫",
|
||||||
|
"term.recentlyAdded": "最近加入",
|
||||||
|
"term.songs": "歌曲",
|
||||||
|
"term.albums": "專輯",
|
||||||
|
"term.artists": "藝人",
|
||||||
|
"term.podcasts": "Podcasts",
|
||||||
|
"term.playlists": "播放列表",
|
||||||
|
"term.playlist": "播放列表",
|
||||||
|
"term.play": "播放",
|
||||||
|
"term.pause": "暫停",
|
||||||
|
"term.previous": "上一首",
|
||||||
|
"term.next": "下一首",
|
||||||
|
"term.shuffle": "隨機播放",
|
||||||
|
"term.repeat": "重複播放",
|
||||||
|
"term.volume": "音量",
|
||||||
|
"term.mute": "靜音",
|
||||||
|
"term.unmute": "取消靜音",
|
||||||
|
"term.share": "分享",
|
||||||
|
"term.settings": "設定",
|
||||||
|
"term.seeAll": "顯示全部",
|
||||||
|
// Home
|
||||||
|
"home.title": "主頁",
|
||||||
|
"home.recentlyPlayed": "最近播放",
|
||||||
|
"home.recentlyAdded": "最近加入",
|
||||||
|
"home.artistsFeed": "藝人追蹤",
|
||||||
|
"home.madeForYou": "為您推薦",
|
||||||
|
"home.friendsListeningTo": "朋友正在聆聽",
|
||||||
|
"home.followedArtists": "追蹤的藝人",
|
||||||
|
// Errors
|
||||||
|
"error.appleMusicSubRequired": "需要訂閱Apple Music以使用Cider",
|
||||||
|
// Actions
|
||||||
|
"action.addToLibrary": "加入資料庫",
|
||||||
|
"action.addToLibrary.success": "成功加入資料庫",
|
||||||
|
"action.addToLibrary.error": "加入資料庫的過程發生錯誤",
|
||||||
|
"action.removeFromLibrary": "從資料庫刪除",
|
||||||
|
"action.removeFromLibrary.success": "已從資料庫刪除",
|
||||||
|
"action.addToQueue": "加入待播清單",
|
||||||
|
"action.addToQueue.success": "成功加入待播清單",
|
||||||
|
"action.addToQueue.error": "加入待播清單的過程發生錯誤",
|
||||||
|
"action.removeFromQueue": "從代播清單刪除",
|
||||||
|
"action.removeFromQueue.success": "已從代播清單刪除",
|
||||||
|
"action.removeFromQueue.error": "從代播清單刪除的過程發生錯誤",
|
||||||
|
"action.follow": "追蹤",
|
||||||
|
"action.follow.success": "追蹤中",
|
||||||
|
"action.follow.error": "追蹤的過程發生錯誤",
|
||||||
|
"action.unfollow": "取消追蹤",
|
||||||
|
"action.unfollow.success": "已取消追蹤",
|
||||||
|
"action.unfollow.error": "取消追蹤的過程發生錯誤",
|
||||||
|
"action.playNext": "插播",
|
||||||
|
"action.playLater": "最後播放",
|
||||||
|
"action.startRadio": "建立電台",
|
||||||
|
"action.goToArtist": "前往藝人",
|
||||||
|
"action.goToAlbum": "前往專輯",
|
||||||
|
"action.share": "分享歌曲",
|
||||||
|
"action.love": "喜愛",
|
||||||
|
"action.unlove": "取消喜愛",
|
||||||
|
"action.dislike": "減少此類建議",
|
||||||
|
"action.undoDislike": "還原減小此類建議",
|
||||||
|
// Settings
|
||||||
|
"settings.header.audio": "音訊",
|
||||||
|
"settings.header.audio.description": "調整Cider的音訊設定",
|
||||||
|
"settings.header.audio.quality.high": "高品質",
|
||||||
|
"settings.header.audio.quality.low": "高效率",
|
||||||
|
"settings.header.audio.quality.auto": "自動",
|
||||||
|
"settings.header.visual": "外觀",
|
||||||
|
"settings.header.visual.description": "調整Cider的外觀",
|
||||||
|
"settings.header.general": "一般",
|
||||||
|
"settings.header.general.description": "調整Cider的一般設定",
|
||||||
|
"settings.header.lyrics": "歌詞",
|
||||||
|
"settings.header.lyrics.description": "調整Cider的歌詞設定",
|
||||||
|
"settings.header.connectivity": "外部連接",
|
||||||
|
"settings.header.connectivity.description": "調整Cider與外部的連接",
|
||||||
|
"settings.header.experimental": "實驗性功能",
|
||||||
|
"settings.header.experimental.description": "調整Cider的實驗性功能",
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ export class AppEvents {
|
||||||
"musics",
|
"musics",
|
||||||
"music"
|
"music"
|
||||||
]
|
]
|
||||||
|
private static plugin: any = null;
|
||||||
private static store: any = null;
|
private static store: any = null;
|
||||||
|
|
||||||
constructor(store: any) {
|
constructor(store: any) {
|
||||||
|
@ -88,27 +88,34 @@ export class AppEvents {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
electron.app.on('open-url', (event, url) => {
|
|
||||||
event.preventDefault()
|
|
||||||
if (this.protocols.some((protocol: string) => url.includes(protocol))) {
|
|
||||||
AppEvents.LinkHandler(url)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public quit() {
|
public quit() {
|
||||||
console.log('App stopped');
|
console.log('App stopped');
|
||||||
}
|
}
|
||||||
|
|
||||||
public ready() {
|
public ready(plug: any) {
|
||||||
|
AppEvents.plugin = plug
|
||||||
console.log('App ready');
|
console.log('App ready');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bwCreated(win: Electron.BrowserWindow) {
|
||||||
|
electron.app.on('open-url', (event, url) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if (AppEvents.protocols.some((protocol: string) => url.includes(protocol))) {
|
||||||
|
AppEvents.LinkHandler(url, win)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
AppEvents.InstanceHandler(win)
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
||||||
* Private methods
|
* Private methods
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
private static LinkHandler(arg: string) {
|
private static LinkHandler(arg: any, win: Electron.BrowserWindow) {
|
||||||
if (!arg) return;
|
if (!arg) return;
|
||||||
|
|
||||||
// LastFM Auth URL
|
// LastFM Auth URL
|
||||||
|
@ -118,8 +125,8 @@ export class AppEvents {
|
||||||
const authKey = authURI.split('lastfm?token=')[1];
|
const authKey = authURI.split('lastfm?token=')[1];
|
||||||
AppEvents.store.set('lastfm.enabled', true);
|
AppEvents.store.set('lastfm.enabled', true);
|
||||||
AppEvents.store.set('lastfm.auth_token', authKey);
|
AppEvents.store.set('lastfm.auth_token', authKey);
|
||||||
// AppEvents.window.webContents.send('LastfmAuthenticated', authKey);
|
win.webContents.send('LastfmAuthenticated', authKey);
|
||||||
// lastfm.authenticate()
|
AppEvents.plugin.callPlugin('lastfm', 'authenticate', authKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Play
|
// Play
|
||||||
|
@ -148,4 +155,28 @@ export class AppEvents {
|
||||||
electron.ipcRenderer.send('play', 'url', url)
|
electron.ipcRenderer.send('play', 'url', url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static InstanceHandler(win: Electron.BrowserWindow) {
|
||||||
|
|
||||||
|
// Detects of an existing instance is running (So if the lock has been achieved, no existing instance has been found)
|
||||||
|
const gotTheLock = electron.app.requestSingleInstanceLock()
|
||||||
|
|
||||||
|
if (!gotTheLock) { // Runs on the new instance if another instance has been found
|
||||||
|
console.log('[Cider] Another instance has been found, quitting.')
|
||||||
|
electron.app.quit()
|
||||||
|
} else { // Runs on the first instance if no other instance has been found
|
||||||
|
electron.app.on('second-instance', (_event, startArgs) => {
|
||||||
|
if (startArgs.includes("--force-quit")) {
|
||||||
|
console.warn('[InstanceHandler][SecondInstanceHandler] Force Quit found. Quitting App.');
|
||||||
|
electron.app.quit()
|
||||||
|
} else if (startArgs.includes("cider://")) {
|
||||||
|
AppEvents.LinkHandler(startArgs, win)
|
||||||
|
} else if (win) {
|
||||||
|
if (win.isMinimized()) win.restore()
|
||||||
|
win.focus()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -34,6 +34,7 @@ export default class PluginHandler {
|
||||||
fs.readdirSync(this.userPluginsPath).forEach(file => {
|
fs.readdirSync(this.userPluginsPath).forEach(file => {
|
||||||
if (file.endsWith('.ts') || file.endsWith('.js')) {
|
if (file.endsWith('.ts') || file.endsWith('.js')) {
|
||||||
const plugin = require(path.join(this.userPluginsPath, file)).default;
|
const plugin = require(path.join(this.userPluginsPath, file)).default;
|
||||||
|
file = file.replace('.ts', '').replace('.js', '');
|
||||||
if (plugins[file] || plugin in plugins) {
|
if (plugins[file] || plugin in plugins) {
|
||||||
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
|
console.log(`[${plugin.name}] Plugin already loaded / Duplicate Class Name`);
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,4 +55,10 @@ export default class PluginHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public callPlugin(plugin: string, event: string, ...args: any[]) {
|
||||||
|
if (this.pluginsList[plugin][event]) {
|
||||||
|
this.pluginsList[plugin][event](...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import * as yt from "youtube-search-without-api-key";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Stream } from "stream";
|
import { Stream } from "stream";
|
||||||
import * as qrcode from "qrcode-terminal";
|
import * as qrcode from "qrcode-terminal";
|
||||||
import * as qrcode2 from "qrcode";
|
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
import {wsapi} from "./wsapi";
|
import {wsapi} from "./wsapi";
|
||||||
|
|
||||||
|
@ -62,7 +61,6 @@ export class Win {
|
||||||
sandbox: true,
|
sandbox: true,
|
||||||
allowRunningInsecureContent: true,
|
allowRunningInsecureContent: true,
|
||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
|
|
||||||
webviewTag: true,
|
webviewTag: true,
|
||||||
plugins: true,
|
plugins: true,
|
||||||
nodeIntegrationInWorker: false,
|
nodeIntegrationInWorker: false,
|
||||||
|
@ -74,7 +72,7 @@ export class Win {
|
||||||
/**
|
/**
|
||||||
* Creates the browser window
|
* Creates the browser window
|
||||||
*/
|
*/
|
||||||
async createWindow(): Promise<void> {
|
async createWindow(): Promise<Electron.BrowserWindow> {
|
||||||
this.clientPort = await getPort({ port: 9000 });
|
this.clientPort = await getPort({ port: 9000 });
|
||||||
this.verifyFiles();
|
this.verifyFiles();
|
||||||
|
|
||||||
|
@ -91,9 +89,6 @@ export class Win {
|
||||||
this.startWebServer();
|
this.startWebServer();
|
||||||
|
|
||||||
this.win = new electron.BrowserWindow(this.options);
|
this.win = new electron.BrowserWindow(this.options);
|
||||||
this.win.on("ready-to-show", () => {
|
|
||||||
this.win.show();
|
|
||||||
});
|
|
||||||
const ws = new wsapi(this.win)
|
const ws = new wsapi(this.win)
|
||||||
ws.InitWebSockets()
|
ws.InitWebSockets()
|
||||||
// and load the renderer.
|
// and load the renderer.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
require('v8-compile-cache');
|
require('v8-compile-cache');
|
||||||
|
|
||||||
// Analytics for debugging fun yeah.
|
// Analytics for debugging fun yeah.
|
||||||
const ElectronSentry = require("@sentry/electron");
|
import * as sentry from '@sentry/electron';
|
||||||
ElectronSentry.init({dsn: "https://68c422bfaaf44dea880b86aad5a820d2@o954055.ingest.sentry.io/6112214"});
|
sentry.init({dsn: "https://68c422bfaaf44dea880b86aad5a820d2@o954055.ingest.sentry.io/6112214"});
|
||||||
|
|
||||||
import * as electron from 'electron';
|
import * as electron from 'electron';
|
||||||
import {Win} from "./base/win";
|
import {Win} from "./base/win";
|
||||||
|
@ -10,18 +10,19 @@ import {ConfigStore} from "./base/store";
|
||||||
import {AppEvents} from "./base/app";
|
import {AppEvents} from "./base/app";
|
||||||
import PluginHandler from "./base/plugins";
|
import PluginHandler from "./base/plugins";
|
||||||
|
|
||||||
// const test = new PluginHandler();
|
|
||||||
const config = new ConfigStore();
|
const config = new ConfigStore();
|
||||||
const App = new AppEvents(config.store);
|
const App = new AppEvents(config.store);
|
||||||
const Cider = new Win(electron.app, config.store)
|
const Cider = new Win(electron.app, config.store)
|
||||||
const plug = new PluginHandler();
|
const plug = new PluginHandler();
|
||||||
|
|
||||||
|
let win: Electron.BrowserWindow;
|
||||||
|
|
||||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
* App Event Handlers
|
* App Event Handlers
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||||
|
|
||||||
electron.app.on('ready', () => {
|
electron.app.on('ready', () => {
|
||||||
App.ready();
|
App.ready(plug);
|
||||||
|
|
||||||
console.log('[Cider] Application is Ready. Creating Window.')
|
console.log('[Cider] Application is Ready. Creating Window.')
|
||||||
if (!electron.app.isPackaged) {
|
if (!electron.app.isPackaged) {
|
||||||
|
@ -30,13 +31,13 @@ electron.app.on('ready', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
electron.components.whenReady().then(async () => {
|
electron.components.whenReady().then(async () => {
|
||||||
await Cider.createWindow()
|
win = await Cider.createWindow()
|
||||||
plug.callPlugins('onReady', Cider);
|
App.bwCreated(win);
|
||||||
|
win.on("ready-to-show", () => {
|
||||||
|
win.show();
|
||||||
})
|
});
|
||||||
|
});
|
||||||
|
plug.callPlugins('onReady', win);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -51,57 +52,31 @@ electron.ipcMain.on('nowPlayingItemDidChange', (event, attributes) => {
|
||||||
plug.callPlugins('onNowPlayingItemDidChange', attributes);
|
plug.callPlugins('onNowPlayingItemDidChange', attributes);
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
|
||||||
electron.app.on('before-quit', () => {
|
electron.app.on('before-quit', () => {
|
||||||
plug.callPlugins('onBeforeQuit');
|
plug.callPlugins('onBeforeQuit');
|
||||||
console.warn(`${electron.app.getName()} exited.`);
|
console.warn(`${electron.app.getName()} exited.`);
|
||||||
});
|
});
|
||||||
//
|
|
||||||
// // @ts-ignore
|
|
||||||
// // Widevine Stuff
|
|
||||||
// electron.app.on('widevine-ready', (version, lastVersion) => {
|
|
||||||
// if (null !== lastVersion) {
|
|
||||||
// console.log('[Cider][Widevine] Widevine ' + version + ', upgraded from ' + lastVersion + ', is ready to be used!')
|
|
||||||
// } else {
|
|
||||||
// console.log('[Cider][Widevine] Widevine ' + version + ' is ready to be used!')
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// // @ts-ignore
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// electron.app.on('widevine-update-pending', (currentVersion, pendingVersion) => {
|
* Widevine Event Handlers
|
||||||
// console.log('[Cider][Widevine] Widevine ' + currentVersion + ' is ready to be upgraded to ' + pendingVersion + '!')
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||||
// })
|
|
||||||
|
|
||||||
// // @ts-ignore
|
// @ts-ignore
|
||||||
// electron.app.on('widevine-error', (error) => {
|
electron.app.on('widevine-ready', (version, lastVersion) => {
|
||||||
// console.log('[Cider][Widevine] Widevine installation encountered an error: ' + error)
|
if (null !== lastVersion) {
|
||||||
// electron.app.exit()
|
console.log('[Cider][Widevine] Widevine ' + version + ', upgraded from ' + lastVersion + ', is ready to be used!')
|
||||||
// })
|
} else {
|
||||||
|
console.log('[Cider][Widevine] Widevine ' + version + ' is ready to be used!')
|
||||||
//
|
|
||||||
//
|
|
||||||
// app.on('open-url', (event, url) => {
|
|
||||||
// event.preventDefault()
|
|
||||||
// if (url.includes('ame://') || url.includes('itms://') || url.includes('itmss://') || url.includes('musics://') || url.includes('music://')) {
|
|
||||||
// CiderBase.LinkHandler(url)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
electron.app.on('second-instance', (_e, argv) => {
|
|
||||||
console.warn(`[InstanceHandler][SecondInstanceHandler] Second Instance Started with args: [${argv.join(', ')}]`)
|
|
||||||
|
|
||||||
// Checks if first instance is authorized and if second instance has protocol args
|
|
||||||
if (argv.includes("--force-quit")) {
|
|
||||||
console.warn('[InstanceHandler][SecondInstanceHandler] Force Quit found. Quitting App.');
|
|
||||||
electron.app.quit()
|
|
||||||
} else if (Cider.win) { // If a Second Instance has Been Started
|
|
||||||
console.warn('[InstanceHandler][SecondInstanceHandler] Showing window.');
|
|
||||||
Cider.win.show()
|
|
||||||
Cider.win.focus()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!electron.app.requestSingleInstanceLock()) {
|
// @ts-ignore
|
||||||
console.warn("[InstanceHandler] Existing Instance is Blocking Second Instance.");
|
electron.app.on('widevine-update-pending', (currentVersion, pendingVersion) => {
|
||||||
electron.app.quit();
|
console.log('[Cider][Widevine] Widevine ' + currentVersion + ' is ready to be upgraded to ' + pendingVersion + '!')
|
||||||
}
|
})
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
electron.app.on('widevine-error', (error) => {
|
||||||
|
console.log('[Cider][Widevine] Widevine installation encountered an error: ' + error)
|
||||||
|
electron.app.exit()
|
||||||
|
})
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import * as electron from 'electron';
|
import * as electron from 'electron';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {resolve} from 'path';
|
import {resolve} from 'path';
|
||||||
|
@ -10,12 +9,13 @@ export default class LastFMPlugin {
|
||||||
key: "f9986d12aab5a0fe66193c559435ede3",
|
key: "f9986d12aab5a0fe66193c559435ede3",
|
||||||
secret: "acba3c29bd5973efa38cc2f0b63cc625"
|
secret: "acba3c29bd5973efa38cc2f0b63cc625"
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Private variables for interaction in plugins
|
* Private variables for interaction in plugins
|
||||||
*/
|
*/
|
||||||
private _win: any;
|
private _win: any;
|
||||||
private _app: any;
|
private _app: any;
|
||||||
private _lastfm: any;
|
private _lastfm: any;
|
||||||
|
|
||||||
private authenticateFromFile() {
|
private authenticateFromFile() {
|
||||||
let sessionData = require(this.sessionPath)
|
let sessionData = require(this.sessionPath)
|
||||||
console.log("[LastFM][authenticateFromFile] Logging in with Session Info.")
|
console.log("[LastFM][authenticateFromFile] Logging in with Session Info.")
|
||||||
|
@ -24,64 +24,64 @@ export default class LastFMPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private authenticate() {
|
authenticate() {
|
||||||
try{
|
try {
|
||||||
if (this._win.store.store.lastfm.auth_token) {
|
if (this._win.store.store.lastfm.auth_token) {
|
||||||
this._win.store.store.lastfm.enabled = true;
|
this._win.store.store.lastfm.enabled = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._win.store.store.lastfm.enabled || !this._win.store.store.lastfm.auth_token) {
|
|
||||||
this._win.store.store.lastfm.enabled = false;
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/// dont move this require to top , app wont load
|
|
||||||
const LastfmAPI = require('lastfmapi');
|
|
||||||
const lfmAPI = new LastfmAPI({
|
|
||||||
'api_key': this.apiCredentials.key,
|
|
||||||
'secret': this.apiCredentials.secret
|
|
||||||
});
|
|
||||||
|
|
||||||
this._lastfm = Object.assign(lfmAPI, {cachedAttributes: false, cachedNowPlayingAttributes: false});
|
|
||||||
|
|
||||||
fs.stat(this.sessionPath, (err : any) => {
|
|
||||||
if (err) {
|
|
||||||
console.error("[LastFM][Session] Session file couldn't be opened or doesn't exist,", err)
|
|
||||||
console.log("[LastFM][Auth] Beginning authentication from configuration")
|
|
||||||
console.log("[LastFM][tk]", this._win.store.store.lastfm.auth_token)
|
|
||||||
this._lastfm.authenticate(this._win.store.store.lastfm.auth_token, (err: any, session: any) => {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
console.log("[LastFM] Successfully obtained LastFM session info,", session); // {"name": "LASTFM_USERNAME", "key": "THE_USER_SESSION_KEY"}
|
|
||||||
console.log("[LastFM] Saving session info to disk.")
|
|
||||||
let tempData = JSON.stringify(session)
|
|
||||||
fs.writeFile(this.sessionPath, tempData, (err: any) => {
|
|
||||||
if (err)
|
|
||||||
console.log("[LastFM][fs]", err)
|
|
||||||
else {
|
|
||||||
console.log("[LastFM][fs] File was written successfully.")
|
|
||||||
this.authenticateFromFile()
|
|
||||||
new electron.Notification({
|
|
||||||
title: electron.app.getName(),
|
|
||||||
body: "Successfully logged into LastFM using Authentication Key."
|
|
||||||
}).show()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.authenticateFromFile()
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
if (!this._win.store.store.lastfm.enabled || !this._win.store.store.lastfm.auth_token) {
|
||||||
|
this._win.store.store.lastfm.enabled = false;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/// dont move this require to top , app wont load
|
||||||
|
const LastfmAPI = require('lastfmapi');
|
||||||
|
const lfmAPI = new LastfmAPI({
|
||||||
|
'api_key': this.apiCredentials.key,
|
||||||
|
'secret': this.apiCredentials.secret
|
||||||
|
});
|
||||||
|
|
||||||
|
this._lastfm = Object.assign(lfmAPI, {cachedAttributes: false, cachedNowPlayingAttributes: false});
|
||||||
|
|
||||||
|
fs.stat(this.sessionPath, (err: any) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("[LastFM][Session] Session file couldn't be opened or doesn't exist,", err)
|
||||||
|
console.log("[LastFM][Auth] Beginning authentication from configuration")
|
||||||
|
console.log("[LastFM][tk]", this._win.store.store.lastfm.auth_token)
|
||||||
|
this._lastfm.authenticate(this._win.store.store.lastfm.auth_token, (err: any, session: any) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
console.log("[LastFM] Successfully obtained LastFM session info,", session); // {"name": "LASTFM_USERNAME", "key": "THE_USER_SESSION_KEY"}
|
||||||
|
console.log("[LastFM] Saving session info to disk.")
|
||||||
|
let tempData = JSON.stringify(session)
|
||||||
|
fs.writeFile(this.sessionPath, tempData, (err: any) => {
|
||||||
|
if (err)
|
||||||
|
console.log("[LastFM][fs]", err)
|
||||||
|
else {
|
||||||
|
console.log("[LastFM][fs] File was written successfully.")
|
||||||
|
this.authenticateFromFile()
|
||||||
|
new electron.Notification({
|
||||||
|
title: electron.app.getName(),
|
||||||
|
body: "Successfully logged into LastFM using Authentication Key."
|
||||||
|
}).show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.authenticateFromFile()
|
||||||
|
}
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async scrobbleSong(attributes : any) {
|
private async scrobbleSong(attributes: any) {
|
||||||
await new Promise(resolve => setTimeout(resolve, Math.round(attributes.durationInMillis * (this._win.store.store.lastfm.scrobble_after / 100))));
|
await new Promise(resolve => setTimeout(resolve, Math.round(attributes.durationInMillis * (this._win.store.store.lastfm.scrobble_after / 100))));
|
||||||
const currentAttributes = attributes;
|
const currentAttributes = attributes;
|
||||||
|
|
||||||
if (!this._lastfm || this._lastfm.cachedAttributes === attributes ) {
|
if (!this._lastfm || this._lastfm.cachedAttributes === attributes) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +112,11 @@ export default class LastFMPlugin {
|
||||||
this.authenticate();
|
this.authenticate();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return console.log('[LastFM] Did not add ', attributes.name , '—' , this.filterArtistName(attributes.artistName), 'because now playing a other song.');
|
return console.log('[LastFM] Did not add ', attributes.name, '—', this.filterArtistName(attributes.artistName), 'because now playing a other song.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private filterArtistName(artist :any) {
|
private filterArtistName(artist: any) {
|
||||||
if (!this._win.store.store.lastfm.enabledRemoveFeaturingArtists) return artist;
|
if (!this._win.store.store.lastfm.enabledRemoveFeaturingArtists) return artist;
|
||||||
|
|
||||||
artist = artist.split(' ');
|
artist = artist.split(' ');
|
||||||
|
@ -134,8 +134,8 @@ export default class LastFMPlugin {
|
||||||
return artist.charAt(0).toUpperCase() + artist.slice(1);
|
return artist.charAt(0).toUpperCase() + artist.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateNowPlayingSong(attributes : any) {
|
private updateNowPlayingSong(attributes: any) {
|
||||||
if (!this._lastfm ||this._lastfm.cachedNowPlayingAttributes === attributes || !this._win.store.store.lastfm.NowPlaying) {
|
if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._win.store.store.lastfm.NowPlaying) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,20 +147,20 @@ export default class LastFMPlugin {
|
||||||
// update Now Playing
|
// update Now Playing
|
||||||
if (attributes.status === true) {
|
if (attributes.status === true) {
|
||||||
this._lastfm.track.updateNowPlaying({
|
this._lastfm.track.updateNowPlaying({
|
||||||
'artist': this.filterArtistName(attributes.artistName),
|
'artist': this.filterArtistName(attributes.artistName),
|
||||||
'track': attributes.name,
|
'track': attributes.name,
|
||||||
'album': attributes.albumName,
|
'album': attributes.albumName,
|
||||||
'albumArtist': this.filterArtistName(attributes.artistName)
|
'albumArtist': this.filterArtistName(attributes.artistName)
|
||||||
}, function (err : any, nowPlaying :any) {
|
}, function (err: any, nowPlaying: any) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return console.error('[LastFM] An error occurred while updating nowPlayingSong', err);
|
return console.error('[LastFM] An error occurred while updating nowPlayingSong', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[LastFM] Successfully updated nowPlayingSong', nowPlaying);
|
console.log('[LastFM] Successfully updated nowPlayingSong', nowPlaying);
|
||||||
});
|
});
|
||||||
this._lastfm.cachedNowPlayingAttributes = attributes
|
this._lastfm.cachedNowPlayingAttributes = attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.authenticate()
|
this.authenticate()
|
||||||
}
|
}
|
||||||
|
@ -178,10 +178,10 @@ export default class LastFMPlugin {
|
||||||
* Runs on plugin load (Currently run on application start)
|
* Runs on plugin load (Currently run on application start)
|
||||||
*/
|
*/
|
||||||
constructor(app: any) {
|
constructor(app: any) {
|
||||||
this._app = app;
|
this._app = app;
|
||||||
electron.app.on('second-instance', (_e:any, argv:any) => {
|
electron.app.on('second-instance', (_e: any, argv: any) => {
|
||||||
// Checks if first instance is authorized and if second instance has protocol args
|
// Checks if first instance is authorized and if second instance has protocol args
|
||||||
argv.forEach((value: any) => {
|
argv.forEach((value: any) => {
|
||||||
if (value.includes('auth')) {
|
if (value.includes('auth')) {
|
||||||
console.log('[LastFMPlugin ok]')
|
console.log('[LastFMPlugin ok]')
|
||||||
let authURI = String(argv).split('/auth/')[1];
|
let authURI = String(argv).split('/auth/')[1];
|
||||||
|
@ -193,10 +193,10 @@ export default class LastFMPlugin {
|
||||||
this._win.win.webContents.send('LastfmAuthenticated', authKey);
|
this._win.win.webContents.send('LastfmAuthenticated', authKey);
|
||||||
this.authenticate();
|
this.authenticate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
electron.app.on('open-url', (event :any, arg:any) => {
|
electron.app.on('open-url', (event: any, arg: any) => {
|
||||||
console.log('[LastFMPlugin] yes')
|
console.log('[LastFMPlugin] yes')
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (arg.includes('auth')) {
|
if (arg.includes('auth')) {
|
||||||
|
@ -211,13 +211,13 @@ export default class LastFMPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs on app ready
|
* Runs on app ready
|
||||||
*/
|
*/
|
||||||
onReady(win: any): void {
|
onReady(win: any): void {
|
||||||
this._win = win;
|
this._win = win;
|
||||||
this.authenticate();
|
this.authenticate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 14 KiB |
|
@ -3306,7 +3306,7 @@ const app = new Vue({
|
||||||
this.tmpWidth = window.innerWidth;
|
this.tmpWidth = window.innerWidth;
|
||||||
this.tmpHeight = window.innerHeight;
|
this.tmpHeight = window.innerHeight;
|
||||||
ipcRenderer.send('setFullScreen', false);
|
ipcRenderer.send('setFullScreen', false);
|
||||||
ipcRenderer.send('windowresize', 250, 250, false)
|
ipcRenderer.send('windowresize', 364, 364, false)
|
||||||
app.appMode = 'mini';
|
app.appMode = 'mini';
|
||||||
} else {
|
} else {
|
||||||
ipcRenderer.send('windowresize', this.tmpWidth, this.tmpHeight, false)
|
ipcRenderer.send('windowresize', this.tmpWidth, this.tmpHeight, false)
|
||||||
|
|
|
@ -2493,8 +2493,8 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
backdrop-filter: blur(16px) saturate(180%);
|
backdrop-filter: blur(32px);
|
||||||
box-shadow: 0px 1px 0px rgba(185, 185, 185, 0.08);
|
//box-shadow: 0px 1px 0px rgba(185, 185, 185, 0.08);
|
||||||
mix-blend-mode: hard-light;
|
mix-blend-mode: hard-light;
|
||||||
|
|
||||||
.nav-item {
|
.nav-item {
|
||||||
|
@ -2604,7 +2604,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
background: black;
|
background: black;
|
||||||
padding: 0px 2em;
|
padding: 0px 2em;
|
||||||
backdrop-filter: blur(32px);
|
backdrop-filter: blur(32px);
|
||||||
background: rgba(24, 24, 24, 0.15);
|
background: rgba(0, 0, 0, 0.25);
|
||||||
top: var(--navigationBarHeight);
|
top: var(--navigationBarHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2806,6 +2806,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
|
|
||||||
.playlist-body {
|
.playlist-body {
|
||||||
padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
|
padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
|
||||||
|
margin-top: -75px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floating-header {
|
.floating-header {
|
||||||
|
@ -2816,7 +2817,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
padding: 0px 1em;
|
padding: 0px 1em;
|
||||||
backdrop-filter: blur(32px);
|
backdrop-filter: blur(32px);
|
||||||
background: rgba(24, 24, 24, 0.15);
|
background: rgba(0, 0, 0, 0.25);
|
||||||
top: var(--navigationBarHeight);
|
top: var(--navigationBarHeight);
|
||||||
transition: opacity 0.1s var(--appleEase);
|
transition: opacity 0.1s var(--appleEase);
|
||||||
}
|
}
|
||||||
|
@ -2833,6 +2834,8 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
margin-top: calc(var(--navigationBarHeight) * -1);
|
||||||
|
margin-bottom: -10px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
-webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%);
|
-webkit-mask-image: radial-gradient(at top left, black, transparent 70%), radial-gradient(at top right, black, transparent 70%), linear-gradient(180deg, rgb(200 200 200), transparent 98%);
|
||||||
opacity: .7;
|
opacity: .7;
|
||||||
|
@ -3062,7 +3065,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
padding: 0px 1em;
|
padding: 0px 1em;
|
||||||
backdrop-filter: blur(32px);
|
backdrop-filter: blur(32px);
|
||||||
background: rgba(24, 24, 24, 0.15);
|
background: rgba(0, 0, 0, 0.25);
|
||||||
top: var(--navigationBarHeight);
|
top: var(--navigationBarHeight);
|
||||||
transition: opacity 0.1s var(--appleEase);
|
transition: opacity 0.1s var(--appleEase);
|
||||||
}
|
}
|
||||||
|
@ -3104,8 +3107,8 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
|
|
||||||
.more-btn-round {
|
.more-btn-round {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 26px;
|
bottom: 84px;
|
||||||
right: 32px;
|
right: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.animated {
|
.animated {
|
||||||
|
@ -3137,6 +3140,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
margin: 32px;
|
margin: 32px;
|
||||||
|
margin-top: -5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.overlay-play {
|
.overlay-play {
|
||||||
|
@ -3173,9 +3177,10 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
}
|
}
|
||||||
|
|
||||||
.artist-play {
|
.artist-play {
|
||||||
width: 36px;
|
width: 32px;
|
||||||
height: 36px;
|
height: 32px;
|
||||||
background: var(--keyColor);
|
background: rgba(100, 100, 100, 0.5);
|
||||||
|
box-shadow: var(--ciderShadow-Generic);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
box-shadow: var(--mediaItemShadow);
|
box-shadow: var(--mediaItemShadow);
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -3185,14 +3190,18 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--keyColor-rollover);
|
filter: brightness(125%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
background: var(--keyColor-pressed);
|
filter: brightness(75%);
|
||||||
|
transform: scale(0.98);
|
||||||
|
transition: transform 0s var(--appleEase), box-shadow 0.2s var(--appleEase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.artist-title {
|
.artist-title {
|
||||||
|
position: relative;
|
||||||
|
top: -19px;
|
||||||
|
|
||||||
.artist-play {
|
.artist-play {
|
||||||
transform: translateY(3px);
|
transform: translateY(3px);
|
||||||
|
@ -3215,7 +3224,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
|
|
||||||
.artist-body {
|
.artist-body {
|
||||||
padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
|
padding: 0px var(--contentInnerPadding) 0px var(--contentInnerPadding);
|
||||||
margin-top: -48px;
|
margin-top: -137px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.showmoreless {
|
.showmoreless {
|
||||||
|
@ -4754,7 +4763,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
.mini-view {
|
.mini-view {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: black;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -5005,7 +5013,8 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
.controls-parents {
|
.controls-parents {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: black;
|
background: #0000009e;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="background">
|
<div class="background">
|
||||||
</div>
|
</div>
|
||||||
<div class="player-exit" title="Close" @click="app.miniPlayer(false)">
|
<div class="player-exit" title="Close" @click="app.miniPlayer(false)">
|
||||||
<svg fill="white" xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21"
|
<svg fill="#323232e3" xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21"
|
||||||
aria-role="presentation" focusable="false">
|
aria-role="presentation" focusable="false">
|
||||||
<path
|
<path
|
||||||
d="M10.5 21C4.724 21 0 16.275 0 10.5S4.724 0 10.5 0 21 4.725 21 10.5 16.276 21 10.5 21zm-3.543-5.967a.96.96 0 00.693-.295l2.837-2.842 2.85 2.842c.167.167.41.295.693.295.552 0 1.001-.461 1.001-1.012 0-.281-.115-.512-.295-.704L11.899 10.5l2.85-2.855a.875.875 0 00.295-.68c0-.55-.45-.998-1.001-.998a.871.871 0 00-.668.295l-2.888 2.855-2.862-2.843a.891.891 0 00-.668-.281.99.99 0 00-1.001.986c0 .269.116.512.295.678L9.088 10.5l-2.837 2.843a.926.926 0 00-.295.678c0 .551.45 1.012 1.001 1.012z"
|
d="M10.5 21C4.724 21 0 16.275 0 10.5S4.724 0 10.5 0 21 4.725 21 10.5 16.276 21 10.5 21zm-3.543-5.967a.96.96 0 00.693-.295l2.837-2.842 2.85 2.842c.167.167.41.295.693.295.552 0 1.001-.461 1.001-1.012 0-.281-.115-.512-.295-.704L11.899 10.5l2.85-2.855a.875.875 0 00.295-.68c0-.55-.45-.998-1.001-.998a.871.871 0 00-.668.295l-2.888 2.855-2.862-2.843a.891.891 0 00-.668-.281.99.99 0 00-1.001.986c0 .269.116.512.295.678L9.088 10.5l-2.837 2.843a.926.926 0 00-.295.678c0 .551.45 1.012 1.001 1.012z"
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
{{ app.mk.nowPlayingItem["attributes"]["name"] }}
|
{{ app.mk.nowPlayingItem["attributes"]["name"] }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap; margin-top: 0.25vh; overflow: hidden;">
|
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap; margin-top: 0.25vh; overflow: hidden; margin-bottom: 5px;">
|
||||||
<div class="item-navigate song-artist" style="display: inline-block;"
|
<div class="item-navigate song-artist" style="display: inline-block;"
|
||||||
@click="app.getNowPlayingItemDetailed(`artist`)">
|
@click="app.getNowPlayingItemDetailed(`artist`)">
|
||||||
{{ app.mk.nowPlayingItem["attributes"]["artistName"] }}
|
{{ app.mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="song-progress">
|
<div class="song-progress">
|
||||||
<div class="song-duration" style="justify-content: space-between; height: 1px;"
|
<div class="song-duration" style="justify-content: space-between; height: 1px; margin-bottom: 1px;"
|
||||||
:style="[app.chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
|
:style="[app.chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
|
||||||
<p style="width: auto">{{ app.convertToMins(app.getSongProgress()) }}</p>
|
<p style="width: auto">{{ app.convertToMins(app.getSongProgress()) }}</p>
|
||||||
<p style="width: auto">{{ app.convertToMins(app.mk.currentPlaybackDuration) }}</p>
|
<p style="width: auto">{{ app.convertToMins(app.mk.currentPlaybackDuration) }}</p>
|
||||||
|
|
BIN
src/web-remote/cider-icon.png
Normal file
BIN
src/web-remote/cider-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
BIN
src/web-remote/launch.png
Normal file
BIN
src/web-remote/launch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Loading…
Add table
Add a link
Reference in a new issue