From 1289f84985c48019fdb994de3ab2355d387ff18b Mon Sep 17 00:00:00 2001 From: lyswhut Date: Tue, 10 May 2022 17:31:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AE=BE=E7=BD=AE-=E6=92=AD?= =?UTF-8?q?=E6=94=BE=E8=AE=BE=E7=BD=AE-=E6=98=BE=E7=A4=BA=E6=AD=8C?= =?UTF-8?q?=E8=AF=8D=E7=BD=97=E9=A9=AC=E9=9F=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/build.gradle | 3 +- .../cn/toside/music/mobile/lyric/Lyric.java | 39 ++- .../music/mobile/lyric/LyricModule.java | 15 +- .../music/mobile/lyric/LyricPlayer.java | 50 +-- .../toside/music/mobile/lyric/LyricView.java | 17 +- android/build.gradle | 4 - index.js | 3 +- package-lock.json | 326 +++++++++--------- package.json | 16 +- publish/changeLog.md | 4 + src/config/defaultSetting.js | 3 +- src/lang/en_us.json | 3 +- src/lang/zh_cn.json | 3 +- src/plugins/lyric.js | 20 +- .../Home/Setting/Player/IsShowLyricRoma.js | 20 ++ src/screens/Home/Setting/Player/index.js | 2 + src/screens/PlayDetail/Landscape/Lyric.js | 12 +- src/screens/PlayDetail/Portrait/Lyric.js | 10 +- src/store/modules/common/action.js | 11 + src/store/modules/common/getter.js | 1 + src/store/modules/common/reducer.js | 12 + src/store/modules/player/action.js | 38 +- src/utils/lyric.js | 17 +- src/utils/lyricDesktop.js | 14 +- src/utils/music/wy/lyric.js | 8 +- src/utils/tools.js | 2 +- 26 files changed, 396 insertions(+), 257 deletions(-) create mode 100644 src/screens/Home/Setting/Player/IsShowLyricRoma.js diff --git a/android/app/build.gradle b/android/app/build.gradle index 3a42114..637d70e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -174,8 +174,7 @@ android { // Fix for windows limit on number of character in file paths and in command lines if (Os.isFamily(Os.FAMILY_WINDOWS)) { - arguments "NDK_OUT=${rootProject.projectDir.getParent()}\\.cxx", - "NDK_APP_SHORT_COMMANDS=true" + arguments "NDK_APP_SHORT_COMMANDS=true" } } } diff --git a/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java b/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java index 96cdaa9..bdf0fe4 100644 --- a/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java +++ b/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java @@ -23,13 +23,16 @@ public class Lyric extends LyricPlayer { // String lastText = "LX Music ^-^"; int lastLine = 0; List lines = new ArrayList(); - boolean isShowTranslation = false; + boolean isShowTranslation; + boolean isShowRoma; String lyricText = ""; - String lyricTransText = ""; + String translationText = ""; + String romaLyricText = ""; - Lyric(ReactApplicationContext reactContext, boolean isShowTranslation) { + Lyric(ReactApplicationContext reactContext, boolean isShowTranslation, boolean isShowRoma) { this.reactAppContext = reactContext; this.isShowTranslation = isShowTranslation; + this.isShowRoma = isShowRoma; registerScreenBroadcastReceiver(); } @@ -93,9 +96,9 @@ public class Lyric extends LyricPlayer { if (lineNum < 0 || lineNum > lines.size() - 1) return; HashMap line = (HashMap) lines.get(lineNum); if (line == null) { - lyricView.setLyric("", ""); + lyricView.setLyric("", new ArrayList<>(0)); } else { - lyricView.setLyric((String) line.get("text"), (String) line.get("translation")); + lyricView.setLyric((String) line.get("text"), (ArrayList) line.get("extendedLyrics")); } } @@ -122,19 +125,26 @@ public class Lyric extends LyricPlayer { isShowLyric = false; } - @Override - public void setLyric(String lyric, String translationLyric) { + private void refreshLyric() { + ArrayList extendedLyrics = new ArrayList<>(2); + if (isShowTranslation && !"".equals(translationText)) extendedLyrics.add(translationText); + if (isShowRoma && !"".equals(romaLyricText)) extendedLyrics.add(romaLyricText); + if (lyricView != null) super.setLyric(lyricText, extendedLyrics); + } + + public void setLyric(String lyric, String translation, String romaLyric) { lyricText = lyric; - lyricTransText = translationLyric; - if (lyricView != null) super.setLyric(lyric, isShowTranslation ? translationLyric : ""); + translationText = translation; + romaLyricText = romaLyric; + refreshLyric(); } @Override public void onSetLyric(List lines) { this.lines = lines; // for (int i = 0; i < lines.size(); i++) { - // HashMap line = (HashMap) lines.get(i); - // Log.d("Lyric", (String) line.get("text") + " " + (String) line.get("translation")); + // HashMap line = (HashMap) lines.get(i); + // Log.d("Lyric", "onSetLyric: " +(String) line.get("text") + " " + line.get("extendedLyrics")); // } } @@ -156,7 +166,12 @@ public class Lyric extends LyricPlayer { public void toggleTranslation(boolean isShowTranslation) { this.isShowTranslation = isShowTranslation; - if (lyricView != null) super.setLyric(lyricText, isShowTranslation ? lyricTransText : ""); + refreshLyric(); + } + + public void toggleRoma(boolean isShowRoma) { + this.isShowRoma = isShowRoma; + refreshLyric(); } public void setColor(String color) { diff --git a/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricModule.java b/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricModule.java index b47048d..bf6498b 100644 --- a/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricModule.java +++ b/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricModule.java @@ -19,6 +19,7 @@ public class LyricModule extends ReactContextBaseJavaModule { // final Map constants = new HashMap<>(); boolean isShowTranslation = false; + boolean isShowRoma = false; LyricModule(ReactApplicationContext reactContext) { super(reactContext); @@ -46,7 +47,7 @@ public class LyricModule extends ReactContextBaseJavaModule { @ReactMethod public void showLyric(ReadableMap data, Promise promise) { - if (lyric == null) lyric = new Lyric(reactContext, isShowTranslation); + if (lyric == null) lyric = new Lyric(reactContext, isShowTranslation, isShowRoma); lyric.showLyric(Arguments.toBundle(data), promise); } @@ -58,10 +59,10 @@ public class LyricModule extends ReactContextBaseJavaModule { @ReactMethod - public void setLyric(String lyric, String translation, Promise promise) { + public void setLyric(String lyric, String translation, String romaLyric, Promise promise) { // Log.d("Lyric", "set lyric: " + lyric); // Log.d("Lyric", "set lyric translation: " + translation); - this.lyric.setLyric(lyric, translation); + this.lyric.setLyric(lyric, translation, romaLyric); promise.resolve(null); } @@ -73,6 +74,14 @@ public class LyricModule extends ReactContextBaseJavaModule { promise.resolve(null); } + @ReactMethod + public void toggleRoma(boolean isShowRoma, Promise promise) { + this.isShowRoma = isShowRoma; + if (lyric == null) return; + lyric.toggleRoma(isShowRoma); + promise.resolve(null); + } + @ReactMethod public void play(int time, Promise promise) { Log.d("Lyric", "play lyric: " + time); diff --git a/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricPlayer.java b/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricPlayer.java index 321a92d..7b694e1 100644 --- a/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricPlayer.java +++ b/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricPlayer.java @@ -17,8 +17,8 @@ public class LyricPlayer { Pattern timePattern; String lyric = ""; - String translationLyric = ""; - List lines = new ArrayList(); + ArrayList extendedLyrics = new ArrayList<>(); + List lines = new ArrayList<>(); HashMap tags = new HashMap(); boolean isPlay = false; int curLineNum = 0; @@ -109,9 +109,28 @@ public class LyricPlayer { } } + private void parseExtendedLyric(HashMap linesMap, String extendedLyric) { + String[] extendedLyricLines = extendedLyric.split("\r\n|\n|\r"); + for (String translationLine : extendedLyricLines) { + String line = translationLine.trim(); + Matcher result = timePattern.matcher(line); + if (result.find()) { + String text = line.replaceAll(timeExp, "").trim(); + if (text.length() > 0) { + String timeStr = result.group(1); + if (timeStr != null) { + timeStr = timeStr.replace("(\\.\\d\\d)0$", "$1"); + HashMap targetLine = (HashMap) linesMap.get(timeStr); + if (targetLine != null) ((ArrayList) targetLine.get("extendedLyrics")).add(text); + } + } + } + } + } + private void initLines() { String[] linesStr = lyric.split("\r\n|\n|\r"); - lines = new ArrayList(); + lines = new ArrayList<>(); HashMap linesMap = new HashMap(); HashMap timeMap = new HashMap(); @@ -124,6 +143,7 @@ public class LyricPlayer { if (text.length() > 0) { String timeStr = result.group(1); if (timeStr == null) continue; + timeStr = timeStr.replace("(\\.\\d\\d)0$", "$1"); String[] timeArr = timeStr.split(":"); String hours; String minutes; @@ -148,32 +168,22 @@ public class LyricPlayer { seconds = timeArr[0]; milliseconds = timeArr[1]; } - HashMap lineInfo = new HashMap(); + HashMap lineInfo = new HashMap<>(); int time = Integer.parseInt(hours) * 60 * 60 * 1000 + Integer.parseInt(minutes) * 60 * 1000 + Integer.parseInt(seconds) * 1000 + Integer.parseInt(milliseconds); lineInfo.put("time", time); lineInfo.put("text", text); - lineInfo.put("translation", ""); + lineInfo.put("extendedLyrics", new ArrayList(extendedLyrics.size())); timeMap.put(timeStr, time); linesMap.put(timeStr, lineInfo); } } } - String[] translationLines = translationLyric.split("\r\n|\n|\r"); - for (String translationLine : translationLines) { - String line = translationLine.trim(); - Matcher result = timePattern.matcher(line); - if (result.find()) { - String text = line.replaceAll(timeExp, "").trim(); - if (text.length() > 0) { - String timeStr = result.group(1); - HashMap targetLine = (HashMap) linesMap.get(timeStr); - if (targetLine != null) targetLine.put("translation", text); - } - } + for (String extendedLyric : extendedLyrics) { + parseExtendedLyric(linesMap, extendedLyric); } Set> set = timeMap.entrySet(); @@ -195,7 +205,7 @@ public class LyricPlayer { private void init() { if (lyric == null) lyric = ""; - if (translationLyric == null) translationLyric = ""; + if (extendedLyrics == null) extendedLyrics = new ArrayList<>(); initTag(); initLines(); onSetLyric(lines); @@ -294,10 +304,10 @@ public class LyricPlayer { refresh(); } - public void setLyric(String lyric, String translationLyric) { + public void setLyric(String lyric, ArrayList extendedLyrics) { if (isPlay) pause(); this.lyric = lyric; - this.translationLyric = translationLyric; + this.extendedLyrics = extendedLyrics; init(); } diff --git a/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricView.java b/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricView.java index 2203153..5ba0ffe 100644 --- a/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricView.java +++ b/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricView.java @@ -21,6 +21,8 @@ import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.WritableMap; +import java.util.ArrayList; + import cn.toside.music.mobile.R; public class LyricView extends Activity implements View.OnTouchListener { @@ -52,7 +54,7 @@ public class LyricView extends Activity implements View.OnTouchListener { private float alpha = 1f; private float textSize = 18f; - private int maxLineNum = 4; + private final int maxLineNum = 5; // private float lineHeight = 1; LyricView(ReactApplicationContext reactContext, LyricEvent lyricEvent) { @@ -217,13 +219,16 @@ public class LyricView extends Activity implements View.OnTouchListener { windowManager.addView(textView, layoutParams); } - public void setLyric(String text, String transText) { + public void setLyric(String text, ArrayList extendedLyrics) { if (textView == null) return; - if (transText.equals("")) { - textView.setText(text); - } else { - textView.setText(text + "\n" + transText); + if (extendedLyrics.size() > 0) { + StringBuilder textBuilder = new StringBuilder(text); + for (String lrc : extendedLyrics) { + textBuilder.append("\n").append(lrc); + } + text = textBuilder.toString(); } + textView.setText(text); } @Override diff --git a/android/build.gradle b/android/build.gradle index e075b18..74d5bfe 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -15,10 +15,6 @@ buildscript { if (System.properties['os.arch'] == "aarch64") { // For M1 Users we need to use the NDK 24 which added support for aarch64 ndkVersion = "24.0.8215888" - } else if (Os.isFamily(Os.FAMILY_WINDOWS)) { - // For Android Users, we need to use NDK 23, otherwise the build will - // fail due to paths longer than the OS limit - ndkVersion = "23.1.7779620" } else { // Otherwise we default to the side-by-side NDK version from AGP. ndkVersion = "21.4.7075529" diff --git a/index.js b/index.js index ac1684e..348a328 100644 --- a/index.js +++ b/index.js @@ -16,7 +16,7 @@ import { action as commonAction } from '@/store/modules/common' import { action as playerAction } from '@/store/modules/player' import { action as listAction } from '@/store/modules/list' import { init as initMusicTools } from '@/utils/music' -import { init as initLyric, toggleTranslation } from '@/utils/lyric' +import { init as initLyric, toggleTranslation, toggleRoma } from '@/utils/lyric' import { showLyric, onPositionChange } from '@/utils/lyricDesktop' import { init as initI18n, supportedLngs } from '@/plugins/i18n' import { deviceLanguage, getPlayInfo, toast, onAppearanceChange, getIsSupportedAutoTheme, getAppearance } from '@/utils/tools' @@ -50,6 +50,7 @@ const init = () => { } toggleTranslation(setting.player.isShowLyricTranslation) + toggleRoma(setting.player.isShowLyricRoma) if (setting.sync.enable) { connect().catch(err => { if (err.message == SYNC_CODE.unknownServiceAddress) { diff --git a/package-lock.json b/package-lock.json index 8e05635..bcdc05f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,26 +10,26 @@ "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@react-native-async-storage/async-storage": "^1.17.3", + "@react-native-async-storage/async-storage": "^1.17.4", "@react-native-clipboard/clipboard": "^1.10.0", "@react-native-community/checkbox": "^0.5.12", "@react-native-community/slider": "^4.2.2", "buffer": "^6.0.3", "console-browserify": "^1.2.0", "events": "^3.3.0", - "i18next": "^21.6.16", + "i18next": "^21.8.0", "js-htmlencode": "^0.3.0", - "lrc-file-parser": "^1.2.7", + "lrc-file-parser": "^2.0.0", "pako": "^2.0.4", "process": "^0.11.10", "prop-types": "^15.8.1", "react": "17.0.2", - "react-i18next": "^11.16.7", - "react-native": "0.68.1", + "react-i18next": "^11.16.9", + "react-native": "0.68.2", "react-native-background-timer": "^2.4.1", "react-native-crypto": "^2.2.0", "react-native-exception-handler": "^2.10.10", - "react-native-fs": "^2.19.0", + "react-native-fs": "^2.20.0", "react-native-navigation": "^7.27.1", "react-native-pager-view": "^5.4.15", "react-native-randombytes": "^3.6.1", @@ -56,7 +56,7 @@ "babel-plugin-module-resolver": "^4.1.0", "changelog-parser": "^2.8.1", "cross-env": "^7.0.3", - "eslint": "^8.14.0", + "eslint": "^8.15.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-html": "^6.2.0", "eslint-plugin-import": "^2.26.0", @@ -1417,12 +1417,12 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", - "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.10.tgz", + "integrity": "sha512-v54O6yLaJySCs6mGzaVOUw9T967GnH38T6CQSAtnzdNPwu84l2qAjssKzo/WSO8Yi7NF+7ekm5cVbF/5qiIgNA==", "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -1730,27 +1730,27 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", - "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.17.10.tgz", + "integrity": "sha512-YNgyBHZQpeoBSRBg0xixsZzfT58Ze1iZrajvv0lJc70qDDGuGfonEnMGfWeSY0mQ3JTuCWFbMkzFRVafOyJx4g==", "peer": true, "dependencies": { - "@babel/compat-data": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-validator-option": "^7.16.7", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", "@babel/plugin-proposal-async-generator-functions": "^7.16.8", "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.17.6", "@babel/plugin-proposal-dynamic-import": "^7.16.7", "@babel/plugin-proposal-export-namespace-from": "^7.16.7", "@babel/plugin-proposal-json-strings": "^7.16.7", "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.17.3", "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", "@babel/plugin-proposal-optional-chaining": "^7.16.7", "@babel/plugin-proposal-private-methods": "^7.16.11", @@ -1776,7 +1776,7 @@ "@babel/plugin-transform-block-scoping": "^7.16.7", "@babel/plugin-transform-classes": "^7.16.7", "@babel/plugin-transform-computed-properties": "^7.16.7", - "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.17.7", "@babel/plugin-transform-dotall-regex": "^7.16.7", "@babel/plugin-transform-duplicate-keys": "^7.16.7", "@babel/plugin-transform-exponentiation-operator": "^7.16.7", @@ -1785,15 +1785,15 @@ "@babel/plugin-transform-literals": "^7.16.7", "@babel/plugin-transform-member-expression-literals": "^7.16.7", "@babel/plugin-transform-modules-amd": "^7.16.7", - "@babel/plugin-transform-modules-commonjs": "^7.16.8", - "@babel/plugin-transform-modules-systemjs": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.17.9", + "@babel/plugin-transform-modules-systemjs": "^7.17.8", "@babel/plugin-transform-modules-umd": "^7.16.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.10", "@babel/plugin-transform-new-target": "^7.16.7", "@babel/plugin-transform-object-super": "^7.16.7", "@babel/plugin-transform-parameters": "^7.16.7", "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.17.9", "@babel/plugin-transform-reserved-words": "^7.16.7", "@babel/plugin-transform-shorthand-properties": "^7.16.7", "@babel/plugin-transform-spread": "^7.16.7", @@ -1803,11 +1803,11 @@ "@babel/plugin-transform-unicode-escapes": "^7.16.7", "@babel/plugin-transform-unicode-regex": "^7.16.7", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.8", + "@babel/types": "^7.17.10", "babel-plugin-polyfill-corejs2": "^0.3.0", "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.20.2", + "core-js-compat": "^3.22.1", "semver": "^6.3.0" }, "engines": { @@ -2053,19 +2053,19 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", - "integrity": "sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", + "espree": "^9.3.2", "globals": "^13.9.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { @@ -2096,9 +2096,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.14.0.tgz", + "integrity": "sha512-ERO68sOYwm5UuLvSJTY7w7NP2c8S4UcXs3X1GBX8cwOr+ShOcDBbCY5mH4zxz0jsYCdJ8ve8Mv9n2YGJMB1aeg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2630,9 +2630,9 @@ } }, "node_modules/@react-native-async-storage/async-storage": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.3.tgz", - "integrity": "sha512-2dxdlGwBjBP2qYu6F72U7cRRFshISYiNEWCaQNOJtxUERCMaYRWcniYqhL248KSbGUMpRhFCEtliztsiGoYYMA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.4.tgz", + "integrity": "sha512-c6GglKBRaWkjNyYd0FM8f0/neQEcwQom4MjZNqYSsIz55LcddJb7W8GM/n2dkzZ0JnaMylMX3+Vo+fpmkFEGTQ==", "dependencies": { "merge-options": "^3.0.4" }, @@ -4234,9 +4234,9 @@ ] }, "node_modules/browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", "funding": [ { "type": "opencollective", @@ -4248,10 +4248,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.2", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" }, "bin": { @@ -4406,9 +4406,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001331", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001331.tgz", - "integrity": "sha512-Y1xk6paHpUXKP/P6YjQv1xqyTbgAP05ycHBcRdQjTcyXlWol868sJJPlmk5ylOekw2BrucWes5jk+LvVd7WZ5Q==", + "version": "1.0.30001338", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001338.tgz", + "integrity": "sha512-1gLHWyfVoRDsHieO+CaeYe7jSo/MT7D7lhaXUiwwbuR5BwQxORs0f1tAwUSQr3YbxRXJvxHM/PA5FfPQRnsPeQ==", "funding": [ { "type": "opencollective", @@ -4744,11 +4744,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", - "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.4.tgz", + "integrity": "sha512-dIWcsszDezkFZrfm1cnB4f/J85gyhiCpxbgBdohWCDtSVuAaChTSpPV7ldOQf/Xds2U5xCIJZOK82G4ZPAIswA==", "dependencies": { - "browserslist": "^4.19.1", + "browserslist": "^4.20.3", "semver": "7.0.0" }, "funding": { @@ -5306,9 +5306,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.4.107", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.107.tgz", - "integrity": "sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg==" + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -5661,12 +5661,12 @@ } }, "node_modules/eslint": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.14.0.tgz", - "integrity": "sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.2", + "@eslint/eslintrc": "^1.2.3", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -5677,7 +5677,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -5693,7 +5693,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -6397,13 +6397,13 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -7455,9 +7455,9 @@ } }, "node_modules/i18next": { - "version": "21.6.16", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.16.tgz", - "integrity": "sha512-xJlzrVxG9CyAGsbMP1aKuiNr1Ed2m36KiTB7hjGMG2Zo4idfw3p9THUEu+GjBwIgEZ7F11ZbCzJcfv4uyfKNuw==", + "version": "21.8.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.0.tgz", + "integrity": "sha512-opNd7cQj0PDlUX15hPjtzReRxy5/Rn405YvHTBEm1nf1YJhsqYFFFhHMwuU4NEHZNlrepHk5uK+CJbFtB+KO3w==", "funding": [ { "type": "individual", @@ -9488,9 +9488,9 @@ } }, "node_modules/lrc-file-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/lrc-file-parser/-/lrc-file-parser-1.2.7.tgz", - "integrity": "sha512-z2+1tUH3N054vFNXvF8F6g0vXWXf66IWJC1cdue8tfdYlK6FXKPsE3ReUmbzHDber+gmSHt1kDlkCJISZ4BBDQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lrc-file-parser/-/lrc-file-parser-2.0.0.tgz", + "integrity": "sha512-h7cPj6D0R/7Wsy2F9UhTQNqWCZisl7GmaDhwDKAINruOsryadNJnrDJpCj+HUHioNxtziuw+yPs8FEazqZlRNA==" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -11446,9 +11446,9 @@ } }, "node_modules/react-i18next": { - "version": "11.16.7", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.7.tgz", - "integrity": "sha512-7yotILJLnKfvUfrl/nt9eK9vFpVFjZPLWAwBzWL6XppSZZEvlmlKk0GBGDCAPfLfs8oND7WAbry8wGzdoiW5Nw==", + "version": "11.16.9", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.9.tgz", + "integrity": "sha512-euXxWvcEAvsY7ZVkwx9ztCq4butqtsGHEkpkuo0RMj8Ru09IF9o2KxCyN+zyv51Nr0aBh/elaTIiR6fMb8YfVg==", "dependencies": { "@babel/runtime": "^7.14.5", "html-escaper": "^2.0.2", @@ -11478,9 +11478,9 @@ "integrity": "sha512-txfpPCQYiazVdcbMRhatqWKcAxJweUu2wDXvts5/7Wyp6+Y9cHojqXHsLPEckzutfHlxZhG8Oiundbmp8Fd6eQ==" }, "node_modules/react-native": { - "version": "0.68.1", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.68.1.tgz", - "integrity": "sha512-5gfvslo5NO2Ece2k/q41eVOK3ca4u1QAOf+qM+auvOiUA4/QR5Yr0WfSGbRpUr2GaFgv7qP11F4+elCravg7uQ==", + "version": "0.68.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.68.2.tgz", + "integrity": "sha512-qNMz+mdIirCEmlrhapAtAG+SWVx6MAiSfCbFNhfHqiqu1xw1OKXdzIrjaBEPihRC2pcORCoCHduHGQe/Pz9Yuw==", "dependencies": { "@jest/create-cache-key-function": "^27.0.1", "@react-native-community/cli": "^7.0.3", @@ -11504,7 +11504,7 @@ "pretty-format": "^26.5.2", "promise": "^8.0.3", "react-devtools-core": "^4.23.0", - "react-native-codegen": "^0.0.13", + "react-native-codegen": "^0.0.17", "react-native-gradle-plugin": "^0.0.6", "react-refresh": "^0.4.0", "react-shallow-renderer": "16.14.1", @@ -11546,9 +11546,9 @@ } }, "node_modules/react-native-codegen": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.13.tgz", - "integrity": "sha512-rCh1P+s0Q4N6vNgS97ckafbhJRztz22+0l0VZoyQC06F07J98kI5cUByH0ATypPRIdpkMbAZc59DoPdDFc01bg==", + "version": "0.0.17", + "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.17.tgz", + "integrity": "sha512-7GIEUmAemH9uWwB6iYXNNsPoPgH06pxzGRmdBzK98TgFBdYJZ7CBuZFPMe4jmHQTPOkQazKZ/w5O6/71JBixmw==", "dependencies": { "@babel/parser": "^7.14.0", "flow-parser": "^0.121.0", @@ -11589,9 +11589,9 @@ } }, "node_modules/react-native-fs": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.19.0.tgz", - "integrity": "sha512-Yl09IbETkV5UJcBtVtBLttyTmiAhJIHpGA/LvredI5dYiw3MXMMVu42bzELiuH2Bwj7F+qd0fMNvgfBDiDxd2A==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.20.0.tgz", + "integrity": "sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ==", "dependencies": { "base-64": "^0.1.0", "utf8": "^3.0.0" @@ -13572,9 +13572,9 @@ } }, "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/type-check": { "version": "0.4.0", @@ -15088,12 +15088,12 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", - "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.10.tgz", + "integrity": "sha512-v54O6yLaJySCs6mGzaVOUw9T967GnH38T6CQSAtnzdNPwu84l2qAjssKzo/WSO8Yi7NF+7ekm5cVbF/5qiIgNA==", "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.17.0" } }, "@babel/plugin-transform-new-target": { @@ -15275,27 +15275,27 @@ } }, "@babel/preset-env": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", - "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.17.10.tgz", + "integrity": "sha512-YNgyBHZQpeoBSRBg0xixsZzfT58Ze1iZrajvv0lJc70qDDGuGfonEnMGfWeSY0mQ3JTuCWFbMkzFRVafOyJx4g==", "peer": true, "requires": { - "@babel/compat-data": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-validator-option": "^7.16.7", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", "@babel/plugin-proposal-async-generator-functions": "^7.16.8", "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.17.6", "@babel/plugin-proposal-dynamic-import": "^7.16.7", "@babel/plugin-proposal-export-namespace-from": "^7.16.7", "@babel/plugin-proposal-json-strings": "^7.16.7", "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.17.3", "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", "@babel/plugin-proposal-optional-chaining": "^7.16.7", "@babel/plugin-proposal-private-methods": "^7.16.11", @@ -15321,7 +15321,7 @@ "@babel/plugin-transform-block-scoping": "^7.16.7", "@babel/plugin-transform-classes": "^7.16.7", "@babel/plugin-transform-computed-properties": "^7.16.7", - "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.17.7", "@babel/plugin-transform-dotall-regex": "^7.16.7", "@babel/plugin-transform-duplicate-keys": "^7.16.7", "@babel/plugin-transform-exponentiation-operator": "^7.16.7", @@ -15330,15 +15330,15 @@ "@babel/plugin-transform-literals": "^7.16.7", "@babel/plugin-transform-member-expression-literals": "^7.16.7", "@babel/plugin-transform-modules-amd": "^7.16.7", - "@babel/plugin-transform-modules-commonjs": "^7.16.8", - "@babel/plugin-transform-modules-systemjs": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.17.9", + "@babel/plugin-transform-modules-systemjs": "^7.17.8", "@babel/plugin-transform-modules-umd": "^7.16.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.10", "@babel/plugin-transform-new-target": "^7.16.7", "@babel/plugin-transform-object-super": "^7.16.7", "@babel/plugin-transform-parameters": "^7.16.7", "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.17.9", "@babel/plugin-transform-reserved-words": "^7.16.7", "@babel/plugin-transform-shorthand-properties": "^7.16.7", "@babel/plugin-transform-spread": "^7.16.7", @@ -15348,11 +15348,11 @@ "@babel/plugin-transform-unicode-escapes": "^7.16.7", "@babel/plugin-transform-unicode-regex": "^7.16.7", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.8", + "@babel/types": "^7.17.10", "babel-plugin-polyfill-corejs2": "^0.3.0", "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.20.2", + "core-js-compat": "^3.22.1", "semver": "^6.3.0" }, "dependencies": { @@ -15529,19 +15529,19 @@ } }, "@eslint/eslintrc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", - "integrity": "sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", + "espree": "^9.3.2", "globals": "^13.9.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { @@ -15561,9 +15561,9 @@ } }, "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.14.0.tgz", + "integrity": "sha512-ERO68sOYwm5UuLvSJTY7w7NP2c8S4UcXs3X1GBX8cwOr+ShOcDBbCY5mH4zxz0jsYCdJ8ve8Mv9n2YGJMB1aeg==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -15993,9 +15993,9 @@ } }, "@react-native-async-storage/async-storage": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.3.tgz", - "integrity": "sha512-2dxdlGwBjBP2qYu6F72U7cRRFshISYiNEWCaQNOJtxUERCMaYRWcniYqhL248KSbGUMpRhFCEtliztsiGoYYMA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.4.tgz", + "integrity": "sha512-c6GglKBRaWkjNyYd0FM8f0/neQEcwQom4MjZNqYSsIz55LcddJb7W8GM/n2dkzZ0JnaMylMX3+Vo+fpmkFEGTQ==", "requires": { "merge-options": "^3.0.4" } @@ -17290,14 +17290,14 @@ } }, "browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", "requires": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.2", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" } }, @@ -17407,9 +17407,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001331", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001331.tgz", - "integrity": "sha512-Y1xk6paHpUXKP/P6YjQv1xqyTbgAP05ycHBcRdQjTcyXlWol868sJJPlmk5ylOekw2BrucWes5jk+LvVd7WZ5Q==" + "version": "1.0.30001338", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001338.tgz", + "integrity": "sha512-1gLHWyfVoRDsHieO+CaeYe7jSo/MT7D7lhaXUiwwbuR5BwQxORs0f1tAwUSQr3YbxRXJvxHM/PA5FfPQRnsPeQ==" }, "capture-exit": { "version": "2.0.0", @@ -17669,11 +17669,11 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js-compat": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", - "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.4.tgz", + "integrity": "sha512-dIWcsszDezkFZrfm1cnB4f/J85gyhiCpxbgBdohWCDtSVuAaChTSpPV7ldOQf/Xds2U5xCIJZOK82G4ZPAIswA==", "requires": { - "browserslist": "^4.19.1", + "browserslist": "^4.20.3", "semver": "7.0.0" }, "dependencies": { @@ -18126,9 +18126,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.4.107", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.107.tgz", - "integrity": "sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg==" + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==" }, "elliptic": { "version": "6.5.4", @@ -18386,12 +18386,12 @@ } }, "eslint": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.14.0.tgz", - "integrity": "sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.2", + "@eslint/eslintrc": "^1.2.3", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -18402,7 +18402,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -18418,7 +18418,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -18905,13 +18905,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "dependencies": { @@ -19709,9 +19709,9 @@ "dev": true }, "i18next": { - "version": "21.6.16", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.16.tgz", - "integrity": "sha512-xJlzrVxG9CyAGsbMP1aKuiNr1Ed2m36KiTB7hjGMG2Zo4idfw3p9THUEu+GjBwIgEZ7F11ZbCzJcfv4uyfKNuw==", + "version": "21.8.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.0.tgz", + "integrity": "sha512-opNd7cQj0PDlUX15hPjtzReRxy5/Rn405YvHTBEm1nf1YJhsqYFFFhHMwuU4NEHZNlrepHk5uK+CJbFtB+KO3w==", "requires": { "@babel/runtime": "^7.17.2" } @@ -21225,9 +21225,9 @@ } }, "lrc-file-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/lrc-file-parser/-/lrc-file-parser-1.2.7.tgz", - "integrity": "sha512-z2+1tUH3N054vFNXvF8F6g0vXWXf66IWJC1cdue8tfdYlK6FXKPsE3ReUmbzHDber+gmSHt1kDlkCJISZ4BBDQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lrc-file-parser/-/lrc-file-parser-2.0.0.tgz", + "integrity": "sha512-h7cPj6D0R/7Wsy2F9UhTQNqWCZisl7GmaDhwDKAINruOsryadNJnrDJpCj+HUHioNxtziuw+yPs8FEazqZlRNA==" }, "lru-cache": { "version": "6.0.0", @@ -22765,9 +22765,9 @@ } }, "react-i18next": { - "version": "11.16.7", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.7.tgz", - "integrity": "sha512-7yotILJLnKfvUfrl/nt9eK9vFpVFjZPLWAwBzWL6XppSZZEvlmlKk0GBGDCAPfLfs8oND7WAbry8wGzdoiW5Nw==", + "version": "11.16.9", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.9.tgz", + "integrity": "sha512-euXxWvcEAvsY7ZVkwx9ztCq4butqtsGHEkpkuo0RMj8Ru09IF9o2KxCyN+zyv51Nr0aBh/elaTIiR6fMb8YfVg==", "requires": { "@babel/runtime": "^7.14.5", "html-escaper": "^2.0.2", @@ -22785,9 +22785,9 @@ "integrity": "sha512-txfpPCQYiazVdcbMRhatqWKcAxJweUu2wDXvts5/7Wyp6+Y9cHojqXHsLPEckzutfHlxZhG8Oiundbmp8Fd6eQ==" }, "react-native": { - "version": "0.68.1", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.68.1.tgz", - "integrity": "sha512-5gfvslo5NO2Ece2k/q41eVOK3ca4u1QAOf+qM+auvOiUA4/QR5Yr0WfSGbRpUr2GaFgv7qP11F4+elCravg7uQ==", + "version": "0.68.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.68.2.tgz", + "integrity": "sha512-qNMz+mdIirCEmlrhapAtAG+SWVx6MAiSfCbFNhfHqiqu1xw1OKXdzIrjaBEPihRC2pcORCoCHduHGQe/Pz9Yuw==", "requires": { "@jest/create-cache-key-function": "^27.0.1", "@react-native-community/cli": "^7.0.3", @@ -22811,7 +22811,7 @@ "pretty-format": "^26.5.2", "promise": "^8.0.3", "react-devtools-core": "^4.23.0", - "react-native-codegen": "^0.0.13", + "react-native-codegen": "^0.0.17", "react-native-gradle-plugin": "^0.0.6", "react-refresh": "^0.4.0", "react-shallow-renderer": "16.14.1", @@ -22836,9 +22836,9 @@ "dev": true }, "react-native-codegen": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.13.tgz", - "integrity": "sha512-rCh1P+s0Q4N6vNgS97ckafbhJRztz22+0l0VZoyQC06F07J98kI5cUByH0ATypPRIdpkMbAZc59DoPdDFc01bg==", + "version": "0.0.17", + "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.17.tgz", + "integrity": "sha512-7GIEUmAemH9uWwB6iYXNNsPoPgH06pxzGRmdBzK98TgFBdYJZ7CBuZFPMe4jmHQTPOkQazKZ/w5O6/71JBixmw==", "requires": { "@babel/parser": "^7.14.0", "flow-parser": "^0.121.0", @@ -22870,9 +22870,9 @@ "requires": {} }, "react-native-fs": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.19.0.tgz", - "integrity": "sha512-Yl09IbETkV5UJcBtVtBLttyTmiAhJIHpGA/LvredI5dYiw3MXMMVu42bzELiuH2Bwj7F+qd0fMNvgfBDiDxd2A==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.20.0.tgz", + "integrity": "sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ==", "requires": { "base-64": "^0.1.0", "utf8": "^3.0.0" @@ -24442,9 +24442,9 @@ } }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "type-check": { "version": "0.4.0", diff --git a/package.json b/package.json index 400db2d..8968362 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-mobile", - "version": "0.12.1-beta", + "version": "0.13.0-beta", "versionCode": 41, "scripts": { "ar": "react-native run-android", @@ -38,26 +38,26 @@ }, "homepage": "https://github.com/lyswhut/lx-music-mobile#readme", "dependencies": { - "@react-native-async-storage/async-storage": "^1.17.3", + "@react-native-async-storage/async-storage": "^1.17.4", "@react-native-clipboard/clipboard": "^1.10.0", "@react-native-community/checkbox": "^0.5.12", "@react-native-community/slider": "^4.2.2", "buffer": "^6.0.3", "console-browserify": "^1.2.0", "events": "^3.3.0", - "i18next": "^21.6.16", + "i18next": "^21.8.0", "js-htmlencode": "^0.3.0", - "lrc-file-parser": "^1.2.7", + "lrc-file-parser": "^2.0.0", "pako": "^2.0.4", "process": "^0.11.10", "prop-types": "^15.8.1", "react": "17.0.2", - "react-i18next": "^11.16.7", - "react-native": "0.68.1", + "react-i18next": "^11.16.9", + "react-native": "0.68.2", "react-native-background-timer": "^2.4.1", "react-native-crypto": "^2.2.0", "react-native-exception-handler": "^2.10.10", - "react-native-fs": "^2.19.0", + "react-native-fs": "^2.20.0", "react-native-navigation": "^7.27.1", "react-native-pager-view": "^5.4.15", "react-native-randombytes": "^3.6.1", @@ -84,7 +84,7 @@ "babel-plugin-module-resolver": "^4.1.0", "changelog-parser": "^2.8.1", "cross-env": "^7.0.3", - "eslint": "^8.14.0", + "eslint": "^8.15.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-html": "^6.2.0", "eslint-plugin-import": "^2.26.0", diff --git a/publish/changeLog.md b/publish/changeLog.md index e67d0d3..d5373a8 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,3 +1,7 @@ +### 新增 + +- 新增设置-播放设置-显示歌词罗马音,默认关闭,注:目前只有网易源能获取到罗马音歌词,如果你知道其他源的歌词罗马音获取方式,欢迎PR! + ### 修复 - 修复潜在的桌面歌词导致应用崩溃问题 diff --git a/src/config/defaultSetting.js b/src/config/defaultSetting.js index 2b72059..08b4d87 100644 --- a/src/config/defaultSetting.js +++ b/src/config/defaultSetting.js @@ -4,7 +4,7 @@ import { MUSIC_TOGGLE_MODE } from './constant' const defaultSetting = { - version: '1.19', + version: '1.20', player: { togglePlayMethod: MUSIC_TOGGLE_MODE.listLoop, highQuality: false, @@ -14,6 +14,7 @@ const defaultSetting = { timeoutExitPlayed: true, isHandleAudioFocus: true, isShowLyricTranslation: false, + isShowLyricRoma: false, isShowNotificationImage: true, portrait: { style: { diff --git a/src/lang/en_us.json b/src/lang/en_us.json index 948a1f6..002bf62 100644 --- a/src/lang/en_us.json +++ b/src/lang/en_us.json @@ -176,7 +176,8 @@ "setting_play_quality": "Play 320K quality songs first (if supported)", "setting_play_save_play_time": "Remember playback progress", "setting_play_show_notification_image": "Show song picture in notification bar", - "setting_play_show_translation": "Show lyrics translation", + "setting_play_show_roma": "Show lyrics roman (if available)", + "setting_play_show_translation": "Show lyrics translation (if available)", "setting_sync": "Synchronization [It is recommended to back up the playlist before using it for the first time]", "setting_sync_address": "Local IP address: {{address}}", "setting_sync_code_fail": "Invalid connection code", diff --git a/src/lang/zh_cn.json b/src/lang/zh_cn.json index 47e96e3..d7b4baf 100644 --- a/src/lang/zh_cn.json +++ b/src/lang/zh_cn.json @@ -177,7 +177,8 @@ "setting_play_quality": "优先播放320K品质的歌曲(如果支持)", "setting_play_save_play_time": "记住播放进度", "setting_play_show_notification_image": "在通知栏显示歌曲图片", - "setting_play_show_translation": "显示歌词翻译", + "setting_play_show_roma": "显示歌词罗马音(如果可用)", + "setting_play_show_translation": "显示歌词翻译(如果可用)", "setting_sync": "同步 [首次使用前建议先备份一次歌单]", "setting_sync_address": "本机IP地址:{{address}}", "setting_sync_code_fail": "连接码无效", diff --git a/src/plugins/lyric.js b/src/plugins/lyric.js index 7da6c27..caf733f 100644 --- a/src/plugins/lyric.js +++ b/src/plugins/lyric.js @@ -11,8 +11,10 @@ const lrcTools = { setLyricHooks: [], isPlay: false, isShowTranslation: false, + isShowRoma: false, lyricText: '', translationText: '', + romaText: '', init() { if (this.isInited) return this.isInited = true @@ -47,6 +49,12 @@ const lrcTools = { removeSetLyricHook(callback) { this.setLyricHooks.splice(this.setLyricHooks.indexOf(callback), 1) }, + setLyric() { + const extendedLyrics = [] + if (this.isShowTranslation && this.translationText) extendedLyrics.push(this.translationText) + if (this.isShowRoma && this.romaText) extendedLyrics.push(this.romaText) + this.lrc.setLyric(this.lyricText, extendedLyrics) + }, } @@ -54,16 +62,22 @@ export const init = async() => { lrcTools.init() } -export const setLyric = (lyric, translation = '') => { +export const setLyric = (lyric, translation, romalrc) => { lrcTools.isPlay = false lrcTools.lyricText = lyric lrcTools.translationText = translation - lrcTools.lrc.setLyric(lrcTools.lyricText, lrcTools.isShowTranslation ? lrcTools.translationText : '') + lrcTools.romaText = romalrc + lrcTools.setLyric() } export const toggleTranslation = isShow => { lrcTools.isShowTranslation = isShow if (!lrcTools.lyricText) return - lrcTools.lrc.setLyric(lrcTools.lyricText, isShow ? lrcTools.translationText : '') + lrcTools.setLyric() +} +export const toggleRoma = isShow => { + lrcTools.isShowRoma = isShow + if (!lrcTools.lyricText) return + lrcTools.setLyric() } export const play = time => { // console.log(time) diff --git a/src/screens/Home/Setting/Player/IsShowLyricRoma.js b/src/screens/Home/Setting/Player/IsShowLyricRoma.js new file mode 100644 index 0000000..c13f84e --- /dev/null +++ b/src/screens/Home/Setting/Player/IsShowLyricRoma.js @@ -0,0 +1,20 @@ +import React, { memo } from 'react' +import { View } from 'react-native' + +import { useGetter, useDispatch } from '@/store' + +import CheckBoxItem from '../components/CheckBoxItem' +import { useTranslation } from '@/plugins/i18n' + +export default memo(() => { + const { t } = useTranslation() + const isShowLyricRoma = useGetter('common', 'isShowLyricRoma') + const setIsShowLyricRoma = useDispatch('common', 'setIsShowLyricRoma') + + + return ( + + + + ) +}) diff --git a/src/screens/Home/Setting/Player/index.js b/src/screens/Home/Setting/Player/index.js index bdbdc3c..df57d33 100644 --- a/src/screens/Home/Setting/Player/index.js +++ b/src/screens/Home/Setting/Player/index.js @@ -5,6 +5,7 @@ import IsPlayHighQuality from './IsPlayHighQuality' import IsHandleAudioFocus from './IsHandleAudioFocus' import IsShowNotificationImage from './IsShowNotificationImage' import IsShowLyricTranslation from './IsShowLyricTranslation' +import IsShowLyricRoma from './IsShowLyricRoma' import MaxCache from './MaxCache' import { useTranslation } from '@/plugins/i18n' @@ -43,6 +44,7 @@ export default memo(() => { + {/* 播放歌曲切换方式 diff --git a/src/screens/PlayDetail/Landscape/Lyric.js b/src/screens/PlayDetail/Landscape/Lyric.js index 6d64e9e..3a37c9d 100644 --- a/src/screens/PlayDetail/Landscape/Lyric.js +++ b/src/screens/PlayDetail/Landscape/Lyric.js @@ -17,17 +17,17 @@ const LrcLine = memo(({ lrc, line, activeLine }) => { ...styles.lineText, fontSize: playerLandscapeStyle.lrcFontSize / 10, lineHeight: playerLandscapeStyle.lrcFontSize / 10 * 1.25, - color: activeLine == line ? theme.secondary : theme.normal30, + color: activeLine == line ? theme.secondary : theme.normal50, }}>{lrc.text} { - lrc.translation - ? { + return ({lrc.translation} - : null + color: activeLine == line ? theme.secondary : theme.normal50, + }} key={index}>{lrc}) + }) } ) diff --git a/src/screens/PlayDetail/Portrait/Lyric.js b/src/screens/PlayDetail/Portrait/Lyric.js index c10ab21..468a965 100644 --- a/src/screens/PlayDetail/Portrait/Lyric.js +++ b/src/screens/PlayDetail/Portrait/Lyric.js @@ -1,6 +1,6 @@ import React, { memo, useMemo, useCallback, useEffect, useRef } from 'react' import { View, Text, StyleSheet, FlatList } from 'react-native' -import { useGetter, useDispatch } from '@/store' +import { useGetter } from '@/store' // import { useLayout } from '@/utils/hooks' import { useLrcPlay, useLrcSet } from '@/plugins/lyric' // import { log } from '@/utils/log' @@ -19,14 +19,14 @@ const LrcLine = memo(({ lrc, line, activeLine }) => { color: activeLine == line ? theme.secondary : theme.normal50, }}>{lrc.text} { - lrc.translation - ? { + return ({lrc.translation} - : null + }} key={index}>{lrc}) + }) } ) diff --git a/src/store/modules/common/action.js b/src/store/modules/common/action.js index b1467c5..61f7924 100644 --- a/src/store/modules/common/action.js +++ b/src/store/modules/common/action.js @@ -38,6 +38,7 @@ export const TYPES = { setIsHandleAudioFocus: null, setAddMusicLocationType: null, setIsShowLyricTranslation: null, + setIsShowLyricRoma: null, setIsEnableSync: null, setSyncStatus: null, setIsClickPlayList: null, @@ -320,6 +321,16 @@ export const setIsShowLyricTranslation = flag => async(dispatch, getState) => { await setData(settingKey, common.setting) } +export const setIsShowLyricRoma = flag => async(dispatch, getState) => { + dispatch(playerAction.toggleRoma(flag)) + dispatch({ + type: TYPES.setIsShowLyricRoma, + payload: flag, + }) + const { common } = getState() + await setData(settingKey, common.setting) +} + export const setIsShowDesktopLyric = flag => async(dispatch, getState) => { await dispatch(playerAction.toggleDesktopLyric(flag)) dispatch({ diff --git a/src/store/modules/common/getter.js b/src/store/modules/common/getter.js index de03a78..f99b1ff 100644 --- a/src/store/modules/common/getter.js +++ b/src/store/modules/common/getter.js @@ -61,6 +61,7 @@ export const desktopLyricStyle = state => state.common.setting.desktopLyric.styl export const timeoutExit = state => state.common.setting.player.timeoutExit export const timeoutExitPlayed = state => state.common.setting.player.timeoutExitPlayed export const isShowLyricTranslation = state => state.common.setting.player.isShowLyricTranslation +export const isShowLyricRoma = state => state.common.setting.player.isShowLyricRoma export const activeApiSourceId = state => state.common.setting.apiSource diff --git a/src/store/modules/common/reducer.js b/src/store/modules/common/reducer.js index 74c698a..7c58e37 100644 --- a/src/store/modules/common/reducer.js +++ b/src/store/modules/common/reducer.js @@ -306,6 +306,18 @@ const mutations = { }, } }, + [TYPES.setIsShowLyricRoma](state, isShowLyricRoma) { + return { + ...state, + setting: { + ...state.setting, + player: { + ...state.setting.player, + isShowLyricRoma, + }, + }, + } + }, [TYPES.setIsShowDesktopLyric](state, isShowDesktopLyric) { return { ...state, diff --git a/src/store/modules/player/action.js b/src/store/modules/player/action.js index 900b535..2a72040 100644 --- a/src/store/modules/player/action.js +++ b/src/store/modules/player/action.js @@ -20,7 +20,7 @@ import { import { getRandom } from '@/utils' import { getMusicUrl, saveMusicUrl, getLyric, saveLyric, assertApiSupport, savePlayInfo, saveList, checkNotificationPermission } from '@/utils/tools' import { playInfo as playInfoGetter } from './getter' -import { play as lrcPlay, setLyric, pause as lrcPause, toggleTranslation as lrcToggleTranslation } from '@/utils/lyric' +import { play as lrcPlay, setLyric, pause as lrcPause, toggleTranslation as lrcToggleTranslation, toggleRoma as lrcToggleRoma } from '@/utils/lyric' import { showLyric, hideLyric, setLyric as lrcdSetLyric, toggleLock, setTheme, setLyricTextPosition, setAlpha, setTextSize } from '@/utils/lyricDesktop' import { action as listAction } from '@/store/modules/list' import { LIST_ID_PLAY_LATER, MUSIC_TOGGLE_MODE } from '@/config/constant' @@ -142,10 +142,10 @@ const handlePlayMusic = async({ getState, dispatch, playMusicInfo, musicInfo, is } }) } - dispatch(getLrc(musicInfo)).then(({ lyric, tlyric }) => { + dispatch(getLrc(musicInfo)).then(({ lyric, tlyric, rlyric }) => { if (playMusicId != id) return const player = getState().player - setLyric(lyric, tlyric) + setLyric(lyric, tlyric, rlyric) if (player.status == STATUS.playing && !player.isGettingUrl) { getPosition().then(position => { lrcPlay(position * 1000) @@ -201,10 +201,10 @@ const handlePlayMusic = async({ getState, dispatch, playMusicInfo, musicInfo, is delayUpdateMusicInfo(buildTrack({ musicInfo, type })) }) } - dispatch(getLrc(musicInfo)).then(({ lyric, tlyric }) => { + dispatch(getLrc(musicInfo)).then(({ lyric, tlyric, rlyric }) => { if (playMusicId != id) return const player = getState().player - setLyric(lyric, tlyric) + setLyric(lyric, tlyric, rlyric) if (player.status == STATUS.playing && !player.isGettingUrl) { getPosition().then(position => { lrcPlay(position * 1000) @@ -513,11 +513,15 @@ export const getPic = musicInfo => (dispatch, getState) => { } export const getLrc = musicInfo => async(dispatch, getState) => { let lyricInfo = await getLyric(musicInfo) - if (lyricInfo.lyric && lyricInfo.tlyric != null) return lyricInfo + if (lyricInfo.lyric && lyricInfo.tlyric != null) { + if (lyricInfo.rlyric == null) { + if (musicInfo.source != 'wy') return lyricInfo + } return lyricInfo + } - return handleGetLyric(dispatch, getState().player.listInfo.id, musicInfo).then(({ lyric, tlyric }) => { + return handleGetLyric(dispatch, getState().player.listInfo.id, musicInfo).then(({ lyric, tlyric, rlyric }) => { // picRequest = null - lyricInfo = { lyric, tlyric } + lyricInfo = { lyric, tlyric, rlyric } saveLyric(musicInfo, lyricInfo) return lyricInfo }).catch(err => { @@ -799,14 +803,24 @@ export const toggleTranslation = isShow => async(dispatch, getState) => { } } +export const toggleRoma = isShow => async(dispatch, getState) => { + lrcToggleRoma(isShow) + const player = getState().player + if (player.status == STATUS.playing && !player.isGettingUrl) { + getPosition().then(position => { + lrcPlay(position * 1000) + }) + } +} + export const toggleDesktopLyric = isShow => async(dispatch, getState) => { if (isShow) { const { common, player } = getState() const desktopLyric = common.setting.desktopLyric - const [{ lyric, tlyric }] = await Promise.all([ + const [{ lyric, tlyric, rlyric }] = await Promise.all([ _playMusicInfo - ? getLyric(_playMusicInfo).catch(() => ({ lyric: '', tlyric: '' })) - : Promise.resolve({ lyric: '', tlyric: '' }), + ? getLyric(_playMusicInfo).catch(() => ({ lyric: '', tlyric: '', rlyric: '' })) + : Promise.resolve({ lyric: '', tlyric: '', rlyric: '' }), showLyric({ isLock: desktopLyric.isLock, themeId: desktopLyric.theme, @@ -818,7 +832,7 @@ export const toggleDesktopLyric = isShow => async(dispatch, getState) => { textPositionY: desktopLyric.textPosition.y, }), ]) - await lrcdSetLyric(lyric, tlyric) + await lrcdSetLyric(lyric, tlyric, rlyric) if (player.status == STATUS.playing && !player.isGettingUrl) { getPosition().then(position => { lrcPlay(position * 1000) diff --git a/src/utils/lyric.js b/src/utils/lyric.js index 92cc751..ecaac64 100644 --- a/src/utils/lyric.js +++ b/src/utils/lyric.js @@ -3,6 +3,7 @@ import { setLyric as lrcSetLyric, pause as lrcPause, toggleTranslation as lrcToggleTranslation, + toggleRoma as lrcToggleRoma, init as lrcInit, } from '@/plugins/lyric' import { @@ -10,6 +11,7 @@ import { setLyric as lrcdSetLyric, pause as lrcdPause, toggleTranslation as lrcdToggleTranslation, + toggleRoma as lrcdToggleRoma, } from '@/utils/lyricDesktop' /** @@ -25,9 +27,9 @@ export const init = () => { * @param {String} lyric lyric str * @param {String} translation lyric translation */ -export const setLyric = (lyric, translation) => { - lrcdSetLyric(lyric, translation) - lrcSetLyric(lyric, translation) +export const setLyric = (lyric, translation = '', romalrc = '') => { + lrcdSetLyric(lyric, translation, romalrc) + lrcSetLyric(lyric, translation, romalrc) } /** @@ -56,3 +58,12 @@ export const toggleTranslation = isShowTranslation => { lrcdToggleTranslation(isShowTranslation) } +/** + * toggle show roma lyric + * @param {Boolean} isShowLyricRoma is show roma lyric + */ +export const toggleRoma = isShowLyricRoma => { + lrcToggleRoma(isShowLyricRoma) + lrcdToggleRoma(isShowLyricRoma) +} + diff --git a/src/utils/lyricDesktop.js b/src/utils/lyricDesktop.js index e2b63c5..a51e691 100644 --- a/src/utils/lyricDesktop.js +++ b/src/utils/lyricDesktop.js @@ -92,9 +92,9 @@ export const pause = () => { * @param {String} translation lyric translation * @returns {Promise} Promise */ -export const setLyric = (lyric, translation) => { +export const setLyric = (lyric, translation, romalrc) => { if (!isShowLyric) return Promise.resolve() - return LyricModule.setLyric(lyric, translation) + return LyricModule.setLyric(lyric, translation || '', romalrc || '') } /** @@ -107,6 +107,16 @@ export const toggleTranslation = isShowTranslation => { return LyricModule.toggleTranslation(isShowTranslation) } +/** + * toggle show roma lyric + * @param {Boolean} isShowRoma is show roma lyric + * @returns {Promise} Promise + */ +export const toggleRoma = isShowRoma => { + // if (!isShowLyric) return Promise.resolve() + return LyricModule.toggleRoma(isShowRoma) +} + /** * toggle is lock lyric window * @param {Boolean} isLock is lock lyric window diff --git a/src/utils/music/wy/lyric.js b/src/utils/music/wy/lyric.js index f9b4f57..33c4089 100644 --- a/src/utils/music/wy/lyric.js +++ b/src/utils/music/wy/lyric.js @@ -40,12 +40,13 @@ export default songmid => { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36', form: linuxapi({ method: 'POST', - url: 'https://music.163.com/api/song/lyric', + url: 'https://music.163.com/api/song/lyric?_nmclfl=1', params: { id: songmid, - lv: -1, - kv: -1, tv: -1, + lv: -1, + rv: -1, + kv: -1, }, }), }) @@ -54,6 +55,7 @@ export default songmid => { return { lyric: body.lrc.lyric, tlyric: body.tlyric.lyric, + rlyric: body.romalrc?.lyric ?? '', // lxlyric: parseLyric(body.klyric.lyric), } }) diff --git a/src/utils/tools.js b/src/utils/tools.js index d7862a7..015732b 100644 --- a/src/utils/tools.js +++ b/src/utils/tools.js @@ -187,7 +187,7 @@ export const clearMusicUrl = async() => { } export const getLyric = musicInfo => getData(`${storageDataPrefix.lyric}${musicInfo.source}_${musicInfo.songmid}`).then(lrcInfo => lrcInfo || {}) -export const saveLyric = (musicInfo, { lyric, tlyric, lxlyric }) => setData(`${storageDataPrefix.lyric}${musicInfo.source}_${musicInfo.songmid}`, { lyric, tlyric, lxlyric }) +export const saveLyric = (musicInfo, { lyric, tlyric, rlyric, lxlyric }) => setData(`${storageDataPrefix.lyric}${musicInfo.source}_${musicInfo.songmid}`, { lyric, tlyric, rlyric, lxlyric }) export const clearLyric = async() => { let keys = (await getAllKeys()).filter(key => key.startsWith(storageDataPrefix.lyric)) await removeDataMultiple(keys)