安卓用户提取密钥需要 root 权限,或注入文件提供器。
diff --git a/src/faq/OtherFAQ.tsx b/src/faq/OtherFAQ.tsx
index d6a0331..0304b45 100644
--- a/src/faq/OtherFAQ.tsx
+++ b/src/faq/OtherFAQ.tsx
@@ -1,20 +1,18 @@
import { ExtLink } from '~/components/ExtLink';
-import { Header4, Header5 } from '~/components/HelpText/Headers';
-import { VQuote } from '~/components/HelpText/VQuote';
+import { Header2, Header3, Header4 } from '~/components/HelpText/Headers';
import { ProjectIssue } from '~/components/ProjectIssue';
-import { RiErrorWarningLine } from 'react-icons/ri';
-import LdPlayerSettingsMisc2x from './assets/ld_settings_misc@2x.webp';
-import MumuSettingsMisc2x from './assets/mumu_settings_misc@2x.webp';
+import { NavLink } from 'react-router';
export function OtherFAQ() {
return (
<>
-
解密后没有封面等信息
+
其它问题
+
解密后没有封面等信息
该项目进行解密处理。如果加密前的资源没有内嵌元信息或封面,解密的文件也没有。
请使用第三方工具进行编辑或管理元信息。
-
批量下载
+
批量下载
{'暂时没有实现,不过你可以在 '}
@@ -23,11 +21,11 @@ export function OtherFAQ() {
{' 追踪该问题。'}
-
安卓: 浏览器支持说明
+
安卓: 浏览器支持说明
⚠️ 手机端浏览器支持有限,请使用最新版本的 Chrome 或 Firefox 官方浏览器。
-
已知有问题的浏览器
+
已知有问题的浏览器
- Via 浏览器
- 夸克浏览器
@@ -36,7 +34,7 @@ export function OtherFAQ() {
-
可能会遇到的问题包括
+
可能会遇到的问题包括
- 网页白屏
- 无法下载解密后内容
@@ -45,70 +43,20 @@ export function OtherFAQ() {
-
安卓: root 相关说明
+
安卓 root
对安卓设备获取 root 特权通常会破坏系统的完整性并导致部分功能无法使用。
例如部分厂商的安卓设备会在解锁后丧失保修资格,或导致无法使用 NFC 移动支付等限制。
-
如果希望不破坏系统完整性,你可以考虑在电脑上使用安卓模拟器。
- 很多安卓模拟器都提供了 root 特权支持,可以很方便的启用,例如
-
- 网易 MuMu 模拟器(安卓 12,推荐)
-
- 或
-
- 雷电模拟器(安卓 9)
-
+ 如果希望不破坏系统完整性,你可以考虑在电脑上使用
+
+ 安卓模拟器
+
。
-
-
-
-
- 根据应用的风控策略,使用模拟器登录的账号有可能会导致账号被封锁。
-
-
使用前请自行评估风险。
-
-
-
-
以下是为上述模拟器启用 root 的方式:
-
-
-
网易 MuMu模拟器
-
- -
- 打开设置中心
-
- -
- 选择其他
-
- -
- 勾选开启手机Root权限
-
-
-
![]()
-
-
-
-
雷电模拟器
-
- -
- 打开模拟器设置
-
- -
- 选择其他
-
- -
- 设置ROOT 权限为开启状态
-
-
-
![]()
-
-
-
-
相关项目
+
相关项目
-
有更多问题?
+
有更多问题?
欢迎加入
“音乐解锁-交流” 交流群
diff --git a/src/faq/QQMusicFAQ.tsx b/src/faq/QQMusicFAQ.tsx
index b1e0391..08e93ae 100644
--- a/src/faq/QQMusicFAQ.tsx
+++ b/src/faq/QQMusicFAQ.tsx
@@ -1,17 +1,24 @@
-import { Header4 } from '~/components/HelpText/Headers';
+import { Header2, Header3 } from '~/components/HelpText/Headers';
import { SegmentTryOfficialPlayer } from './SegmentTryOfficialPlayer';
import { QMCv2QQMusicAllInstructions } from '~/features/settings/panels/QMCv2/QMCv2QQMusicAllInstructions';
export function QQMusicFAQ() {
return (
<>
- 解锁失败
+ QQ 音乐
+ 解锁失败
-
重复下载同一首的歌曲不重复扣下载配额,但是同一首歌的两个版本会重复扣下载配额,请仔细分辨。
-
+
新版本的 QQ 音乐客户端下载的文件通常都需要导入密钥数据库。
+
每一个资源(即一首歌的某个音质)都有独立的密钥,下载音乐时会被写出到密钥数据库中。
+
因此若是解密失败,很有可能是因为你需要导入密钥,或降级客户端。
+
+
关于下载
+
重复下载同一首的歌曲不重复扣下载配额,但是同一首歌的两个版本会重复扣下载配额,请仔细分辨。
+
部分平台获取的加密文件未包含密钥。选择你下载文件时使用的客户端来查看说明。
+
导入密钥或降级客户端
>
);
diff --git a/src/faq/SegmentTryOfficialPlayer.tsx b/src/faq/SegmentTryOfficialPlayer.tsx
index f67efee..ef8bc93 100644
--- a/src/faq/SegmentTryOfficialPlayer.tsx
+++ b/src/faq/SegmentTryOfficialPlayer.tsx
@@ -2,7 +2,7 @@ import { RiErrorWarningLine } from 'react-icons/ri';
export function SegmentTryOfficialPlayer({ className = '' }: { className?: string }) {
return (
-
+
尝试用下载音乐的设备播放一次看看,如果官方客户端都无法播放,那解锁肯定会失败哦。
diff --git a/src/features/nav/ResponsiveNav.tsx b/src/features/nav/ResponsiveNav.tsx
index 0a15ab2..b92bb29 100644
--- a/src/features/nav/ResponsiveNav.tsx
+++ b/src/features/nav/ResponsiveNav.tsx
@@ -20,7 +20,7 @@ export function ResponsiveNav({
className={`@container/nav grow grid grid-cols-1 grid-rows-[auto_1fr] md:grid-rows-1 md:grid-cols-[10rem_1fr] ${className}`}
>
{/* Sidebar */}
-
+
{/* Main content */}
{children}
diff --git a/src/features/nav/TabNavLink.tsx b/src/features/nav/TabNavLink.tsx
new file mode 100644
index 0000000..517c7c6
--- /dev/null
+++ b/src/features/nav/TabNavLink.tsx
@@ -0,0 +1,21 @@
+import classNames from 'classnames';
+import type { RefAttributes } from 'react';
+import { NavLink, type NavLinkProps } from 'react-router';
+
+const tabClassNames = ({ isActive }: { isActive: boolean }) =>
+ classNames(
+ 'link inline-flex text-nowrap mb-[-2px] no-underline w-full',
+ 'border-b-2 md:border-b-0 md:border-r-2',
+ 'tab md:grow',
+ {
+ 'tab-active bg-accent/10 border-accent': isActive,
+ },
+ );
+
+export function TabNavLink({ children, ...props }: NavLinkProps & RefAttributes
) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/features/settings/Settings.tsx b/src/features/settings/Settings.tsx
index a1cff80..ea3af14 100644
--- a/src/features/settings/Settings.tsx
+++ b/src/features/settings/Settings.tsx
@@ -1,12 +1,12 @@
import { useAppDispatch, useAppSelector } from '~/hooks';
import { commitStagingChange, discardStagingChanges } from './settingsSlice';
import { selectIsSettingsNotSaved } from './settingsSelector';
-import { NavLink, Outlet } from 'react-router';
+import { Outlet } from 'react-router';
import { SETTINGS_TABS } from '~/features/settings/settingsTabs.tsx';
import { MdOutlineSettingsBackupRestore } from 'react-icons/md';
import { toast } from 'react-toastify';
import { ResponsiveNav } from '../nav/ResponsiveNav';
-import classNames from 'classnames';
+import { TabNavLink } from '../nav/TabNavLink';
export function Settings() {
const dispatch = useAppDispatch();
@@ -27,16 +27,6 @@ export function Settings() {
};
const isSettingsNotSaved = useAppSelector(selectIsSettingsNotSaved);
- const tabClassNames = ({ isActive }: { isActive: boolean }) =>
- classNames(
- 'link inline-flex text-nowrap mb-[-2px] no-underline w-full',
- 'border-b-2 md:border-b-0 md:border-r-2',
- 'tab md:grow',
- {
- 'tab-active bg-accent/10 border-accent': isActive,
- },
- );
-
return (
{Object.entries(SETTINGS_TABS).map(([id, { name }]) => (
-
+
{name}
-
+
))}
}
diff --git a/src/features/settings/panels/QMCv2/QMCv2QQMusicAllInstructions.tsx b/src/features/settings/panels/QMCv2/QMCv2QQMusicAllInstructions.tsx
index ba46b77..df483d6 100644
--- a/src/features/settings/panels/QMCv2/QMCv2QQMusicAllInstructions.tsx
+++ b/src/features/settings/panels/QMCv2/QMCv2QQMusicAllInstructions.tsx
@@ -4,7 +4,7 @@ import { InstructionsMac } from './InstructionsMac';
import { InstructionsPC } from './InstructionsPC';
import { InstructionsTabs, InstructionTab } from '~/components/InstructionsTabs.tsx';
-export function QMCv2QQMusicAllInstructions() {
+export function QMCv2QQMusicAllInstructions({ limitHeight }: { limitHeight?: boolean }) {
const tabs: InstructionTab[] = [
{
id: 'android',
@@ -16,5 +16,5 @@ export function QMCv2QQMusicAllInstructions() {
{ id: 'windows', label: 'Windows', content: },
];
- return ;
+ return ;
}
diff --git a/src/tabs/FaqTab.tsx b/src/tabs/FaqTab.tsx
index d3352e5..aeaaf1f 100644
--- a/src/tabs/FaqTab.tsx
+++ b/src/tabs/FaqTab.tsx
@@ -1,43 +1,27 @@
-import { ComponentType, Fragment } from 'react';
-import { Header3 } from '~/components/HelpText/Headers';
-import { KuwoFAQ } from '~/faq/KuwoFAQ';
-import { OtherFAQ } from '~/faq/OtherFAQ';
-import { QQMusicFAQ } from '~/faq/QQMusicFAQ';
-import { KugouFAQ } from '~/faq/KugouFAQ.tsx';
-
-type FAQEntry = {
- id: string;
- title: string;
- Help: ComponentType;
-};
-
-const faqEntries: FAQEntry[] = [
- { id: 'qqmusic', title: 'QQ 音乐', Help: QQMusicFAQ },
- { id: 'kuwo', title: '酷我音乐', Help: KuwoFAQ },
- { id: 'kugou', title: '酷狗音乐', Help: KugouFAQ },
- { id: 'other', title: '其它问题', Help: OtherFAQ },
-];
+import { Outlet } from 'react-router';
+import { FAQ_PAGES } from '~/faq/FAQPages';
+import { ResponsiveNav } from '~/features/nav/ResponsiveNav';
+import { TabNavLink } from '~/features/nav/TabNavLink';
export function FaqTab() {
return (
-
- 常见问题解答
- 答疑目录
-
- {faqEntries.map(({ id, title }) => (
- -
-
- {title}
-
-
- ))}
-
- {faqEntries.map(({ id, title, Help }) => (
-
- {title}
-
-
- ))}
-
+
+
+ {FAQ_PAGES.map(({ id, name }) => (
+
+ {name}
+
+ ))}
+
+ }
+ >
+
+
+
);
}