404
9 |10 | 访问的页面不存在 11 |
12 |13 | 您似乎访问了一片荒漠QwQ~ 14 |
15 |├── .editorconfig
├── .gitignore
├── .npmrc
├── .prettierignore
├── README.md
├── env.d.ts
├── index.html
├── package.json
├── pnpm-lock.yaml
├── public
├── data
│ ├── custom
│ │ ├── dot_black_list.json
│ │ ├── embedded_rules_list.xml
│ │ ├── embedded_setting_config.xml
│ │ ├── fixed_orientation_list.xml
│ │ └── third_party_app_optimize.prop
│ ├── origin
│ │ ├── autoui_list.xml
│ │ ├── embedded_rules_list.xml
│ │ ├── embedded_setting_config.xml
│ │ ├── fixed_orientation_list.xml
│ │ ├── package_info.json
│ │ ├── system_app_optimize.prop
│ │ ├── teg_config.db
│ │ └── third_party_app_optimize.prop
│ └── system
│ │ ├── DisplayModeRecord.json
│ │ ├── app.txt
│ │ ├── dot_black_list.json
│ │ ├── embedded_rules_list.xml
│ │ ├── fixed_orientation_list.xml
│ │ └── gamebooster_table.json
├── favicon.ico
└── images
│ ├── ai_cover_dark_bg.webp
│ ├── ai_cover_pc.png
│ ├── ai_footer_animation.webp
│ ├── apps
│ ├── bodian.webp
│ ├── brainmusic.jpg
│ ├── btremote.png
│ ├── egggame.png
│ ├── filmlytv.webp
│ ├── flipaclip.png
│ ├── flix.png
│ ├── freenote.png
│ ├── gamecores.webp
│ ├── habicat.webp
│ ├── honor_music.png
│ ├── iunistoolsdisplay.png
│ ├── kingdee.webp
│ ├── liuzhoufile.png
│ ├── magisk.webp
│ ├── mi_device_connect.jpg
│ ├── mi_home.png
│ ├── mi_music.png
│ ├── mi_note.png
│ ├── mi_remote.png
│ ├── mi_soundrecorder.webp
│ ├── mi_theme.webp
│ ├── mi_whitenoise.png
│ ├── pianoperfect.webp
│ ├── qinalt.jpg
│ ├── qq_music.jpg
│ ├── samsung_browser.png
│ ├── sspai.png
│ ├── starNote.webp
│ ├── uu_remote.jpg
│ └── youshi.webp
│ ├── happy_new_year_banner.jpg
│ └── icons
│ ├── ai_icon.png
│ ├── aicr.png
│ ├── all_app.png
│ ├── deepseek.png
│ ├── google.png
│ ├── happy_new_year.png
│ ├── miui_content_extension_app.webp
│ ├── qq_doc.png
│ └── win_play_mobile.webp
├── src
├── App.vue
├── apis
│ ├── autouiApi.ts
│ ├── deviceApi.ts
│ ├── dotBlackListApi.ts
│ ├── embeddedApi.ts
│ └── gameBoosterApi.ts
├── assets
│ ├── applicationName.json
│ ├── base.css
│ ├── fonts.css
│ ├── fonts
│ │ ├── HarmonyOS_Sans
│ │ │ ├── HarmonyOS_Sans_Black.woff2
│ │ │ ├── HarmonyOS_Sans_Bold.woff2
│ │ │ ├── HarmonyOS_Sans_Light.woff2
│ │ │ ├── HarmonyOS_Sans_Medium.woff2
│ │ │ ├── HarmonyOS_Sans_Regular.woff2
│ │ │ └── HarmonyOS_Sans_Thin.woff2
│ │ ├── MiSans-Regular.woff2
│ │ └── OPPO-Sans-4.0.woff
│ ├── iconfont.js
│ ├── logo.svg
│ └── main.css
├── components
│ ├── AutoUIAppDrawer.vue
│ ├── DotBlackListAppDrawer.vue
│ ├── EmbeddedActivityRuleDrawer.vue
│ ├── EmbeddedAppDrawer.vue
│ ├── EmbeddedPlaceholderDrawer.vue
│ ├── EmbeddedSplitPairRuleDrawer.vue
│ ├── EmbeddedTransitionRulesDrawer.vue
│ ├── ErrorModal.vue
│ ├── GameBoosterAppDrawer.vue
│ ├── HelloWorld.vue
│ ├── Sidebar
│ │ ├── Sidebar.vue
│ │ └── index.ts
│ ├── SplashScreen.vue
│ ├── TheWelcome.vue
│ ├── WelcomeItem.vue
│ └── icons
│ │ ├── IconCommunity.vue
│ │ ├── IconDocumentation.vue
│ │ ├── IconEcosystem.vue
│ │ ├── IconSupport.vue
│ │ └── IconTooling.vue
├── config
│ ├── blacklistApplications.tsx
│ ├── rulePerceptionApplications.tsx
│ └── whitelistApplications.ts
├── constant
│ └── gameBooster.ts
├── hooks
│ ├── useABTestActivation.tsx
│ ├── useAmktiao.tsx
│ ├── useAutoUI.ts
│ ├── useDevelopmentSettingsEnabled.tsx
│ ├── useDisabledOS2SystemAppOptimize.tsx
│ ├── useDisabledOS2SystemPreStart.tsx
│ ├── useDisplayModeRecord.tsx
│ ├── useDisplaySettings.tsx
│ ├── useEmbedded.ts
│ ├── useFbo.tsx
│ ├── useGameMode.tsx
│ ├── useHideGestureLine.tsx
│ ├── useInVisibleMode.tsx
│ ├── useInstalledAppNames.ts
│ ├── useMIUIContentExtension.tsx
│ ├── useMiuiCursorStyle.tsx
│ ├── useMiuiDesktopMode.tsx
│ ├── useMouseGestureNaturalscroll.tsx
│ ├── useNavigation.tsx
│ ├── useOS2InstallModuleTips.tsx
│ ├── usePointerSpeed.tsx
│ ├── useQQDoc.tsx
│ ├── useRealQuantity.tsx
│ ├── useShowNotificationIconNum.tsx
│ ├── useSidebar.tsx
│ ├── useUFSHealth.ts
│ ├── useVideoWallpaperLoop.tsx
│ └── useZRAMWriteback.tsx
├── main.ts
├── router
│ ├── device_routes
│ │ ├── fold.ts
│ │ ├── phone.ts
│ │ └── tablet.ts
│ └── index.ts
├── stores
│ ├── autoui.ts
│ ├── cloudFeature.ts
│ ├── counter.ts
│ ├── device.ts
│ ├── dotBlackList.ts
│ ├── embedded.ts
│ ├── font.ts
│ ├── gameBooster.ts
│ ├── logs.ts
│ └── package.ts
├── style.css
├── types
│ ├── AutoUIItem.d.ts
│ ├── AutoUIMergeRuleItem.d.ts
│ ├── AutoUIPolicy.ts
│ ├── AutoUISettingRuleItem.d.ts
│ ├── DotBlackListItem.d.ts
│ ├── DotBlackListMergeItem.d.ts
│ ├── EmbeddedMergeRuleItem.d.ts
│ ├── EmbeddedPlaceholder.d.ts
│ ├── EmbeddedRuleItem.d.ts
│ ├── EmbeddedSettingRuleItem.d.ts
│ ├── EmbeddedSplitPairRuleItem.ts
│ ├── ErrorLogging.d.ts
│ ├── FixedOrientationRuleItem.d.ts
│ ├── GameBoosterTableItem.d.ts
│ └── PackageItem.d.ts
├── utils
│ ├── autoUIFun.ts
│ ├── common.ts
│ ├── embeddedFun.ts
│ ├── eventBus.ts
│ ├── format.ts
│ ├── handlePromiseWithLogging.ts
│ ├── kernelsu
│ │ ├── index.d.ts
│ │ └── index.js
│ ├── sqio.ts
│ ├── validateFun.ts
│ └── xmlFormat.ts
└── views
│ ├── AboutView.vue
│ ├── AppStore.vue
│ ├── AutoUIView.vue
│ ├── BatteryHealth.vue
│ ├── DotBlackListView.vue
│ ├── EmbeddedActivityView.vue
│ ├── EmbeddedWebView.vue
│ ├── GameBooster.vue
│ ├── GameTurboConfig.vue
│ ├── HappyNewYearEgg.vue
│ ├── LogView.vue
│ ├── MagicControlView.vue
│ ├── MemoryHealth.vue
│ ├── NotFoundView.vue
│ ├── SettingsView.vue
│ └── SystemExperienceEnhance.vue
├── tailwind.config.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_size = 4
6 | end_of_line = lf
7 | indent_style = tab
8 | spelling_language = zh-CN
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.yml]
13 | indent_style = space
14 |
15 | [*.md]
16 | indent_size = 2
17 | indent_style = space
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | *.log
3 |
4 | # MacOS
5 | .DS_Store
6 |
7 | # Node Module
8 | node_modules
9 |
10 | # Editor Files
11 | .idea
12 | .vscode
13 |
14 | # Vite
15 | *.timestamp-*
16 |
17 | # Build
18 | /dist
19 | /stats.html
20 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.npmmirror.com/
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Node Module
2 | node_modules
3 |
4 | # Build
5 | /dist
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HyperOS 完美横屏应用计划 For Web UI
2 |
3 | ## 模块首页
4 |
5 | 可通过项目首页快速了解本模块:
6 |
7 | [HyperOS 完美横屏应用计划 - MIUI MagicWindow+](https://hyper-magic-window.sothx.com/)
8 |
9 | ## 项目说明
10 |
11 | 本项目为支撑《HyperOS 完美横屏应用计划》模块的 Web UI 端,提供可视化界面修改模块部分配置的能力。
12 |
13 | ## 推荐 IDE
14 |
15 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
16 |
17 | ## 项目安装
18 |
19 | ```sh
20 | pnpm install
21 | ```
22 |
23 | ### 编译和热重载开发
24 |
25 | ```sh
26 | pnpm dev
27 | ```
28 |
29 | ### 编译并构建生产包
30 |
31 | ```sh
32 | pnpm build
33 | ```
34 |
--------------------------------------------------------------------------------
/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
错误描述:无法获取{{ errItem.title }}
48 |错误详情:{{ errItem.msg }}
49 |15 | 完美横屏应用计划 Web UI 管理后台正在建设中,敬请期待~ 16 |
17 |永远相信美好的事情即将发生!!!
25 |让每个人都能享受科技的乐趣!!!
26 |优秀的公司赚取利润,伟大的公司赢得人心!!!
27 |小米为发烧而生!!!
28 |我所有的向往!!!
29 |27 | 已成功参与OS2{' '} 28 | 29 | 应用横屏布局 For Web UI 30 | {' '} 31 | 的Beta测试w。由于小米在OS2新开发的{' '} 32 | 33 | 应用横屏布局 34 | {' '} 35 | 存在较多BUG,模块强制劫持了所有配置,仅能通过Web UI去调整应用横屏适配,在{' '} 36 | 37 | 平板专区 38 | {' '} 39 | 所做的相关修改会在重启后丢失。 40 |
41 |42 | 开发Hyper OS 2.0模块的Web 43 | UI真的消耗了我大量的个人时间和精力QwQ(特别是在小米的BUG加持下),如果对{' '} 44 | 45 | 完美横屏应用计划感到满意 46 | {' '} 47 | ,求个随缘打赏。(打赏入口在Web UI侧边栏) 48 |
49 |62 | 已成功参与Hyper OS{' '} 63 | 64 | 窗口控制器 For Web UI 65 | {' '} 66 | 的Beta测试w。该功能可能会随{' '} 67 | 68 | 小米云控 69 | {' '} 70 | 下发导致失效,失效时可以前往界面查看失效状态,并且选择{' '} 71 | 72 | 热重载应用配置 73 | {' '} 74 | 来恢复模块对窗口控制器的控制权。 75 |
76 |77 | 开发Hyper OS 模块的Web UI真的消耗了我大量的个人时间和精力QwQ,如果对{' '} 78 | 79 | 完美横屏应用计划感到满意 80 | {' '} 81 | ,求个随缘打赏。(打赏入口在Web UI侧边栏) 82 |
83 |96 | 已成功参与{' '} 97 | 98 | 游戏显示布局 2.0 99 | {' '} 100 | 的Beta测试w。该功能调整后会改变游戏的显示比例,获得更大的游戏视野,但并非所有游戏都兼容游戏显示比例调整,且部分游戏可能会对游戏显示比例的修改作为风控管理,可能导致游戏账号被封禁,调整游戏显示布局前,即认可并了解这些须知。 101 |
102 |103 | 开发Hyper OS 模块的Web UI真的消耗了我大量的个人时间和精力QwQ,如果对{' '} 104 | 105 | 完美横屏应用计划感到满意 106 | {' '} 107 | ,求个随缘打赏。(打赏入口在Web UI侧边栏) 108 |
109 |激活自定义游戏比例失败了QwQ,请先激活游戏显示布局2.0的Beta测试!
, 120 | // negativeText: '确定', 121 | // }); 122 | // return; 123 | // } 124 | deviceStore.ABTestInfo.GAME_BOOSTER_CUSTOM_RATIO = true; 125 | modal.create({ 126 | title: '操作成功', 127 | type: 'success', 128 | preset: 'dialog', 129 | content: () => ( 130 |132 | 已成功激活{' '} 133 | 134 | 游戏显示布局 2.0 135 | {' '} 136 | 的自定义游戏比例。自定义游戏比例存在使用风险,如果配置了不恰当的自定义游戏比例,可能会触发部分游戏风控导致游戏账号被封,激活该功能即认可并了解这些须知。 137 |
138 |139 | 开发Hyper OS 模块的Web UI真的消耗了我大量的个人时间和精力QwQ,如果对{' '} 140 | 141 | 完美横屏应用计划感到满意 142 | {' '} 143 | ,求个随缘打赏。(打赏入口在Web UI侧边栏) 144 |
145 |解析激活口令失败了QwQ,请检查激活口令是否有误
, 155 | negativeText: '确定', 156 | }); 157 | } 158 | 159 | loading.value = false; 160 | } 161 | 162 | return { activateABTest, loading }; 163 | } 164 | -------------------------------------------------------------------------------- /src/hooks/useAutoUI.ts: -------------------------------------------------------------------------------- 1 | import { ref, computed, onMounted } from 'vue'; 2 | import { useDeviceStore } from '@/stores/device' 3 | import $to from 'await-to-js' 4 | import AutoUIAppDrawer from '@/components/AutoUIAppDrawer.vue'; 5 | import { NButton, createDiscreteApi, darkTheme, lightTheme, type ConfigProviderProps, type DataTableColumns, type NInput } from 'naive-ui' 6 | import type AutoUIMergeRuleItem from '@/types/AutoUIMergeRuleItem'; 7 | export function useAutoUI() { 8 | const deviceStore = useDeviceStore(); 9 | const configProviderPropsRef = computed即将{value ? '开启': '关闭'}开发者模式,确定要继续吗?
41 |修改失败,详情请查看日志记录~
, 64 | negativeText: '确定', 65 | }); 66 | } else { 67 | isEnabled.value = value === 1 ? true : false 68 | } 69 | } 70 | }; 71 | 72 | const fetchData = async () => { 73 | const [getDevelopmentSettingsEnabledErr, getDevelopmentSettingsEnabledRes] = await $to修改失败,详情请查看日志记录~
, 35 | negativeText: '确定', 36 | }); 37 | return; 38 | } 39 | if (value) { 40 | const [addIsDisabledOS2SystemAppOptimizeErr, addIsDisabledOS2SystemAppOptimizeRes] = await $to( 41 | deviceApi.addIsDisabledOS2SystemAppOptimize(), 42 | ); 43 | if (addIsDisabledOS2SystemAppOptimizeErr) { 44 | modal.create({ 45 | title: '操作失败', 46 | type: 'error', 47 | preset: 'dialog', 48 | content: () =>修改失败,详情请查看日志记录~
, 49 | negativeText: '确定', 50 | }); 51 | return; 52 | } 53 | } 54 | deviceStore.isDisabledOS2SystemAppOptimize = value; 55 | }; 56 | 57 | 58 | onMounted(() => { 59 | }); 60 | 61 | return { 62 | change: changeDisabledOS2SystemAppOptimize 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /src/hooks/useDisabledOS2SystemPreStart.tsx: -------------------------------------------------------------------------------- 1 | import { ref, computed, onMounted } from 'vue'; 2 | import { useDeviceStore } from '@/stores/device'; 3 | import $to from 'await-to-js'; 4 | import { 5 | NButton, 6 | createDiscreteApi, 7 | darkTheme, 8 | lightTheme, 9 | type ConfigProviderProps, 10 | type DataTableColumns, 11 | type NInput, 12 | } from 'naive-ui'; 13 | import * as deviceApi from '@/apis/deviceApi'; 14 | 15 | export function useDisabledOS2SystemPreStart() { 16 | const deviceStore = useDeviceStore(); 17 | const configProviderPropsRef = computed45 | 禁用{' '} 46 | 48 | 应用预加载 49 | {' '} 50 | 后,触摸系统桌面上的{' '} 51 | 53 | 任意应用 54 | {' '} 55 | 不再触发应用预加载,需要设备重启才会生效,确定要继续禁用吗? 56 |
57 | )} 58 | {value && ( 59 |60 | 开启{' '} 61 | 63 | 应用预加载 64 | {' '} 65 | 后,触摸系统桌面上的{' '} 66 | 68 | 任意应用 69 | {' '} 70 | 将会触发应用预加载,需要设备重启才会生效,确定要继续开启吗? 71 |
72 | )} 73 |无法修改应用预加载的配置,详情请查看日志记录~
, 94 | negativeText: '确定', 95 | }); 96 | return; 97 | } 98 | if (!value) { 99 | const [addDisabledPreStartProcErr] = await $to(deviceApi.addDisabledPreStartProc()); 100 | if (addDisabledPreStartProcErr) { 101 | modal.create({ 102 | title: '操作失败', 103 | type: 'error', 104 | preset: 'dialog', 105 | content: () =>无法修改应用预加载的配置,详情请查看日志记录~
, 106 | negativeText: '确定', 107 | }); 108 | return; 109 | } 110 | } 111 | modal.create({ 112 | title: '操作成功', 113 | type: 'success', 114 | preset: 'dialog', 115 | content: () =>好耶w,已{value ? '开启' : '关闭'}应用预加载~实际生效还需要重启设备,确定要重启吗?
, 116 | positiveText: '立即重启', 117 | negativeText: '稍后手动重启', 118 | onPositiveClick() { 119 | deviceApi.rebootDevice().catch(err => { 120 | modal.create({ 121 | title: '操作失败', 122 | type: 'error', 123 | preset: 'dialog', 124 | content: () =>无法重启设备,详情请查看日志记录~
, 125 | negativeText: '确定', 126 | }); 127 | return; 128 | }); 129 | }, 130 | }); 131 | } 132 | }; 133 | 134 | onMounted(() => {}); 135 | 136 | return { 137 | isShow, 138 | change, 139 | }; 140 | } 141 | -------------------------------------------------------------------------------- /src/hooks/useDisplayModeRecord.tsx: -------------------------------------------------------------------------------- 1 | import { ref, computed, onMounted, reactive, h, renderSlot, type CSSProperties } from 'vue'; 2 | import { useDeviceStore } from '@/stores/device' 3 | import * as deviceApi from '@/apis/deviceApi'; 4 | import $to from 'await-to-js'; 5 | import { type ConfigProviderProps, darkTheme, lightTheme, createDiscreteApi, NSwitch } from 'naive-ui'; 6 | 7 | export interface DisplayModeItem { 8 | id: number, 9 | width: number, 10 | height: number, 11 | fps: number, 12 | vsync?: number, 13 | synthetic?: boolean, 14 | alternativeRefreshRates: number[], 15 | supportedHdrTypes: number[] 16 | } 17 | 18 | export function useDisplayModeRecord() { 19 | const railStyle = ({ focused, checked }: { focused: boolean; checked: boolean }) => { 20 | const style: CSSProperties = {}; 21 | if (checked) { 22 | style.background = '#2080f0'; 23 | if (focused) { 24 | style.boxShadow = '0 0 0 2px #2080f040'; 25 | } 26 | } else { 27 | style.background = '#d03050'; 28 | if (focused) { 29 | style.boxShadow = '0 0 0 2px #d0305040'; 30 | } 31 | } 32 | return style; 33 | }; 34 | const deviceStore = useDeviceStore(); 35 | 36 | const configProviderPropsRef = computed修改失败,详情请查看日志记录~
, 95 | negativeText: '确定', 96 | }); 97 | } 98 | if (setDisplayModeRes) { 99 | modal.create({ 100 | title: '操作成功', 101 | type: 'success', 102 | preset: 'dialog', 103 | content: () =>已成功应用该分辨率及刷新率配置,在设备下次重启前将一直维持该配置,如需恢复系统设置内的默认分辨率及刷新率配置,请手动重启设备。
, 104 | negativeText: '确定', 105 | }); 106 | } 107 | } 108 | 109 | 110 | 111 | onMounted(async () => { 112 | }) 113 | 114 | 115 | return { 116 | supportHDRTypes, 117 | formatDisplayModeList, 118 | setDisplayMode, 119 | selectDisplayMode 120 | } 121 | 122 | 123 | } -------------------------------------------------------------------------------- /src/hooks/useDisplaySettings.tsx: -------------------------------------------------------------------------------- 1 | import { ref, computed, onMounted, nextTick } from 'vue'; 2 | import $to from 'await-to-js'; 3 | import { useDeviceStore } from '@/stores/device'; 4 | import { 5 | NButton, 6 | createDiscreteApi, 7 | darkTheme, 8 | lightTheme, 9 | type ConfigProviderProps, 10 | type DataTableColumns, 11 | type NInput, 12 | } from 'naive-ui'; 13 | import * as deviceApi from '@/apis/deviceApi'; 14 | import { useLogsStore } from '@/stores/logs'; 15 | 16 | export function useDisplaySettings() { 17 | const deviceStore = useDeviceStore(); 18 | 19 | const configProviderPropsRef = computed39 | 通过将屏幕亮度调整为0,达到熄灭屏幕但是不影响屏幕的触控操作。可能适合部分特殊场景使用,游戏或者视频场景仍然推荐使用{' '} 40 | 41 | 熄屏挂机 42 | {' '} 43 | 和{' '} 44 | 45 | 熄屏听剧 46 | {' '} 47 | ,使用该功能会自动关闭{' '} 48 | 49 | 自动亮度 50 | {' '} 51 | ,请悉知,如需恢复屏幕显示需要敲击两次{' '} 52 | 53 | 电源键 54 | {' '} 55 | ,确定要继续吗? 56 |
57 |42 | 需要安装{' '} 43 | 45 | 小米平板安卓15澎湃2.0专版(pad-hyperos2-based-on-vanillaIceCream) 46 | {' '} 47 | 才可以正常使用{' '} 48 | 50 | 游戏显示布局 51 | {' '} 52 | ,请先替换模块版本~ 53 |
54 |下载地址:https://caiyun.139.com/m/i?135CdgGlXeVEC
55 |该系统版本尚未适配游戏显示布局,请等待模块后续更新~
, 74 | }); 75 | reject('error'); 76 | } 77 | } else { 78 | resolve('success'); 79 | } 80 | }); 81 | }; 82 | 83 | const changeGameMode = async (value: boolean) => { 84 | if (value) { 85 | const [vaildModuleVersionErr] = await $to(vaildModuleVersion()); 86 | if (vaildModuleVersionErr) { 87 | return; 88 | } 89 | } 90 | const [negativeRes, positiveRes] = await $to( 91 | new Promise((resolve, reject) => { 92 | modal.create({ 93 | title: value ? '想开启游戏显示布局吗?' : '想关闭游戏显示布局吗?', 94 | type: 'info', 95 | preset: 'dialog', 96 | content: () => ( 97 |99 | {value ? '开启' : '关闭'}{' '} 100 | 101 | 游戏显示布局 102 | {' '} 103 | 后需要设备重启才会生效~ 104 |
105 | {value && 106 | deviceStore.deviceType === 'tablet' && 107 | deviceStore.MIOSVersion && 108 | deviceStore.MIOSVersion >= 2 && 109 | deviceStore.androidTargetSdk >= 35 && ( 110 |111 | 从Hyper OS 2.0开始,小米平板需要搭配配套的{' '} 112 | 114 | 修改版平板/手机管家 115 | {' '} 116 | 才能使用游戏显示布局,详情请前往模块首页了解~ 117 |
118 | )} 119 |是否继续{value ? '开启' : '关闭'}游戏显示布局?
120 |无法修改模块配置文件,详情请查看日志记录~
, 141 | negativeText: '确定', 142 | }); 143 | return; 144 | } 145 | if (value) { 146 | const [addGameModeErr] = await $to(deviceApi.addGameMode()); 147 | if (addGameModeErr) { 148 | modal.create({ 149 | title: '操作失败', 150 | type: 'error', 151 | preset: 'dialog', 152 | content: () =>无法修改模块配置文件,详情请查看日志记录~
, 153 | negativeText: '确定', 154 | }); 155 | return; 156 | } 157 | } 158 | modal.create({ 159 | title: '操作成功', 160 | type: 'success', 161 | preset: 'dialog', 162 | content: () => ( 163 |164 | 好耶w,已经成功{value ? '开启' : '关闭'}游戏显示布局~实际生效还需要重启设备,确定要重启吗? 165 |
166 | ), 167 | positiveText: '立即重启', 168 | negativeText: '稍后手动重启', 169 | onPositiveClick() { 170 | deviceApi 171 | .rebootDevice() 172 | .catch(err => { 173 | modal.create({ 174 | title: '操作失败', 175 | type: 'error', 176 | preset: 'dialog', 177 | content: () =>无法重启设备,详情请查看日志记录~
, 178 | negativeText: '确定', 179 | }); 180 | return; 181 | }); 182 | }, 183 | }); 184 | } 185 | }; 186 | 187 | onMounted(() => {}); 188 | 189 | return { 190 | vaildModuleVersion, 191 | changeGameMode, 192 | isSupportGameMode, 193 | }; 194 | } 195 | -------------------------------------------------------------------------------- /src/hooks/useHideGestureLine.tsx: -------------------------------------------------------------------------------- 1 | import { ref, computed, onMounted, nextTick } from 'vue'; 2 | import { useDeviceStore } from '@/stores/device'; 3 | import $to from 'await-to-js'; 4 | import { 5 | NButton, 6 | createDiscreteApi, 7 | darkTheme, 8 | lightTheme, 9 | type ConfigProviderProps, 10 | type DataTableColumns, 11 | type NInput, 12 | } from 'naive-ui'; 13 | import * as deviceApi from '@/apis/deviceApi'; 14 | 15 | export type IsHideGestureLine = 0 | 1; 16 | 17 | export function useHideGestureLine() { 18 | const deviceStore = useDeviceStore(); 19 | const configProviderPropsRef = computed修改失败,详情请查看日志记录~
, 42 | negativeText: '确定', 43 | }); 44 | } else { 45 | if (value) { 46 | const [addIsHideGestureLineErr, addIsHideGestureLineRes] = await $to( 47 | deviceApi.addIsHideGestureLine(), 48 | ); 49 | if (addIsHideGestureLineErr) { 50 | modal.create({ 51 | title: '操作失败', 52 | type: 'error', 53 | preset: 'dialog', 54 | content: () =>修改失败,详情请查看日志记录~
, 55 | negativeText: '确定', 56 | }); 57 | } else { 58 | modal.create({ 59 | title: '修改成功', 60 | type: 'success', 61 | preset: 'dialog', 62 | content: () =>好耶w!隐藏手势提示线(小白条)成功,请知晓,隐藏手势提示线(小白条)的情况下,旋转建议提示按钮也将变成不可用的状态~
, 63 | positiveText: '确定', 64 | }); 65 | currentIsHideGestureLine.value = 1; 66 | } 67 | } else { 68 | const [removeIsHideGestureLineErr, removeIsHideGestureLineRes] = await $to( 69 | deviceApi.removeIsHideGestureLine(), 70 | ); 71 | if (removeIsHideGestureLineErr) { 72 | modal.create({ 73 | title: '操作失败', 74 | type: 'error', 75 | preset: 'dialog', 76 | content: () =>修改失败,详情请查看日志记录~
, 77 | negativeText: '确定', 78 | }); 79 | } else { 80 | modal.create({ 81 | title: '修改成功', 82 | type: 'success', 83 | preset: 'dialog', 84 | content: () =>好耶w!已经将手势提示线(小白条)调整为显示状态~
, 85 | positiveText: '确定', 86 | }); 87 | currentIsHideGestureLine.value = 0; 88 | } 89 | } 90 | } 91 | }; 92 | 93 | const fetchData = async () => { 94 | const [, getHideGestureLineRes] = await $to修改失败,详情请查看日志记录~
, 40 | negativeText: '确定', 41 | }); 42 | } else { 43 | currentIsInVisibleMode.value = value ? 1 : 0; 44 | } 45 | }; 46 | 47 | const fetchData = async () => { 48 | const [, getInVisibleModeRes] = await $to修改失败,详情请查看日志记录~
, 45 | negativeText: '确定', 46 | }); 47 | } else { 48 | currentMiuiCursorStyleType.value = value; 49 | } 50 | }; 51 | 52 | const changeAutoStartMiuiCursorStyleType = async (type: boolean) => { 53 | if (type) { 54 | const [removeMiuiCursorStyleTypeErr, removeMiuiCursorStyleTypeRes] = await $to( 55 | deviceApi.removeAutoStartMiuiCursorStyleType(), 56 | ); 57 | if (removeMiuiCursorStyleTypeErr) { 58 | modal.create({ 59 | title: '操作失败', 60 | type: 'error', 61 | preset: 'dialog', 62 | content: () =>修改失败,详情请查看日志记录~
, 63 | negativeText: '确定', 64 | }); 65 | return; 66 | } else { 67 | const [addMiuiCursorStyleTypeErr, addMiuiCursorStyleTypeRes] = await $to( 68 | deviceApi.addAutoStartMiuiCursorStyleType(currentMiuiCursorStyleType.value), 69 | ); 70 | if (addMiuiCursorStyleTypeErr) { 71 | modal.create({ 72 | title: '操作失败', 73 | type: 'error', 74 | preset: 'dialog', 75 | content: () =>修改失败,详情请查看日志记录~
, 76 | negativeText: '确定', 77 | }); 78 | } else { 79 | modal.create({ 80 | title: '添加自启动成功', 81 | type: 'success', 82 | preset: 'dialog', 83 | content: () =>添加「鼠标光标样式」开机自启动配置成功,后续请通过模块 Web UI 修改「鼠标光标样式」,系统设置内的修改会在重启后失效~
, 84 | positiveText: '确定', 85 | }); 86 | currentAutoStartMiuiCursorStyleType.value = currentMiuiCursorStyleType.value 87 | } 88 | } 89 | } else { 90 | const [removeMiuiCursorStyleTypeErr, removeMiuiCursorStyleTypeRes] = await $to( 91 | deviceApi.removeAutoStartMiuiCursorStyleType(), 92 | ); 93 | if (removeMiuiCursorStyleTypeErr) { 94 | modal.create({ 95 | title: '操作失败', 96 | type: 'error', 97 | preset: 'dialog', 98 | content: () =>修改失败,详情请查看日志记录~
, 99 | negativeText: '确定', 100 | }); 101 | } else { 102 | modal.create({ 103 | title: '取消自启动成功', 104 | type: 'success', 105 | preset: 'dialog', 106 | content: () =>取消「鼠标光标样式」开机自启动配置成功~
, 107 | positiveText: '确定', 108 | }); 109 | currentAutoStartMiuiCursorStyleType.value = undefined 110 | } 111 | } 112 | }; 113 | 114 | const fetchData = async () => { 115 | const [ 116 | [, getMiuiCursorStyleTypeRes], 117 | [, getAutoStartMiuiCursorStyleTypeRes] 118 | ] = await Promise.all([ 119 | $to修改失败,详情请查看日志记录~
, 40 | negativeText: '确定', 41 | }); 42 | } else { 43 | currentMiuiDktMode.value = value; 44 | } 45 | } 46 | 47 | const changeMiuiDesktopModeEnabled = async () => { 48 | const [negativeRes, positiveRes] = await $to( 49 | new Promise((resolve, reject) => { 50 | modal.create({ 51 | title: '想激活工作台模式吗?', 52 | type: 'info', 53 | preset: 'dialog', 54 | content: () => ( 55 |57 | 激活{' '} 58 | 59 | 工作台模式 60 | {' '} 61 | 后需要设备重启才会生效~ 62 |
63 |是否继续激活?
64 |修改失败,详情请查看日志记录~
, 87 | negativeText: '确定', 88 | }); 89 | return; 90 | } 91 | const [addIsAddDesktopModeEnabledErr, addIsAddDesktopModeEnabledRes] = await $to( 92 | deviceApi.addIsAddDesktopModeEnabled(), 93 | ); 94 | if (addIsAddDesktopModeEnabledErr) { 95 | modal.create({ 96 | title: '操作失败', 97 | type: 'error', 98 | preset: 'dialog', 99 | content: () =>修改失败,详情请查看日志记录~
, 100 | negativeText: '确定', 101 | }); 102 | return; 103 | } 104 | const [removeMiuiDesktopModeEnabledErr, removeMiuiDesktopModeEnabledRes] = await $to( 105 | deviceApi.removeMiuiDesktopModeEnabled(), 106 | ); 107 | if (removeMiuiDesktopModeEnabledErr) { 108 | modal.create({ 109 | title: '操作失败', 110 | type: 'error', 111 | preset: 'dialog', 112 | content: () =>修改失败,详情请查看日志记录~
, 113 | negativeText: '确定', 114 | }); 115 | return; 116 | } 117 | const [addMiuiDesktopModeEnabledErr, addMiuiDesktopModeEnabledRes] = await $to( 118 | deviceApi.addMiuiDesktopModeEnabled(), 119 | ); 120 | if (addMiuiDesktopModeEnabledErr) { 121 | modal.create({ 122 | title: '操作失败', 123 | type: 'error', 124 | preset: 'dialog', 125 | content: () =>修改失败,详情请查看日志记录~
, 126 | negativeText: '确定', 127 | }); 128 | return; 129 | } 130 | modal.create({ 131 | title: '操作成功', 132 | type: 'success', 133 | preset: 'dialog', 134 | content: () => ( 135 |136 | 好耶w,已经成功激活工作台模式~实际生效还需要重启设备,确定要重启吗? 137 |
138 | ), 139 | positiveText: '立即重启', 140 | negativeText: '稍后手动重启', 141 | onPositiveClick() { 142 | deviceApi 143 | .rebootDevice() 144 | .catch(err => { 145 | modal.create({ 146 | title: '操作失败', 147 | type: 'error', 148 | preset: 'dialog', 149 | content: () =>无法重启设备,详情请查看日志记录~
, 150 | negativeText: '确定', 151 | }); 152 | return; 153 | }); 154 | }, 155 | }); 156 | } 157 | }; 158 | 159 | const fetchData = async () => { 160 | if (deviceStore.enabledMiuiDesktopMode) { 161 | const [, getCurrentMiuiDktModeResolve] = await $to修改失败,详情请查看日志记录~
, 42 | negativeText: '确定', 43 | }); 44 | } else { 45 | currentMouseGestureNaturalscroll.value = value ? 1 : 0; 46 | } 47 | }; 48 | 49 | const fetchData = async () => { 50 | const [, getMouseGestureNaturalscrollRes] = await $to36 | 开启{' '} 37 | 39 | 模块使用须知 40 | {' '} 41 | 后,模块每次安装过程会带使用须知的{' '} 42 | 44 | 强提醒 45 | {' '} 46 | ,需要设备重启才会生效,确定要继续开启吗? 47 |
48 | )} 49 | {value && ( 50 |51 | 禁用{' '} 52 | 54 | 模块使用须知 55 | {' '} 56 | 后,模块每次安装过程将会{' '} 57 | 59 | 静默安装 60 | {' '} 61 | ,需要设备重启才会生效,确定要继续禁用吗? 62 |
63 | )} 64 |无法修改模块使用须知,详情请查看日志记录~
, 85 | negativeText: '确定', 86 | }); 87 | return; 88 | } 89 | if (value) { 90 | const [addDisabledOS2InstallModuleTipsErr] = await $to(deviceApi.addDisabledOS2InstallModuleTips()); 91 | if (addDisabledOS2InstallModuleTipsErr) { 92 | modal.create({ 93 | title: '操作失败', 94 | type: 'error', 95 | preset: 'dialog', 96 | content: () =>无法修改模块使用须知,详情请查看日志记录~
, 97 | negativeText: '确定', 98 | }); 99 | return; 100 | } 101 | } 102 | modal.create({ 103 | title: '操作成功', 104 | type: 'success', 105 | preset: 'dialog', 106 | content: () => ( 107 |108 | 好耶w,已经成功{value ? '禁用' : '开启'}模块使用须知~实际生效还需要重启设备,确定要重启吗? 109 |
110 | ), 111 | positiveText: '立即重启', 112 | negativeText: '稍后手动重启', 113 | onPositiveClick() { 114 | deviceApi 115 | .rebootDevice() 116 | .catch(err => { 117 | modal.create({ 118 | title: '操作失败', 119 | type: 'error', 120 | preset: 'dialog', 121 | content: () =>无法重启设备,详情请查看日志记录~
, 122 | negativeText: '确定', 123 | }); 124 | return; 125 | }); 126 | }, 127 | }); 128 | } 129 | }; 130 | 131 | onMounted(() => {}); 132 | 133 | return { 134 | change, 135 | }; 136 | } 137 | -------------------------------------------------------------------------------- /src/hooks/usePointerSpeed.tsx: -------------------------------------------------------------------------------- 1 | import { ref, computed, onMounted, nextTick } from 'vue'; 2 | import { useDeviceStore } from '@/stores/device'; 3 | import $to from 'await-to-js'; 4 | import { 5 | NButton, 6 | createDiscreteApi, 7 | darkTheme, 8 | lightTheme, 9 | type ConfigProviderProps, 10 | type DataTableColumns, 11 | type NInput, 12 | } from 'naive-ui'; 13 | import * as deviceApi from '@/apis/deviceApi'; 14 | 15 | export function usePointerSpeed() { 16 | const deviceStore = useDeviceStore(); 17 | const configProviderPropsRef = computed修改失败,详情请查看日志记录~
, 41 | negativeText: '确定', 42 | }); 43 | } else { 44 | currentPointerSpeed.value = value 45 | } 46 | }; 47 | 48 | const fetchData = async () => { 49 | const [, getPointerSpeedRes] = await $to您可以通过收集表提交您的应用适配需求OwO,提交前请认真阅读须知~
29 |https://docs.qq.com/form/page/DRUhJQkhzSnp6dWhm
30 |修改失败,详情请查看日志记录~
, 41 | negativeText: '确定', 42 | }); 43 | return; 44 | } 45 | const [addIsEnableShowNotificationIconNumErr] = await $to修改失败,详情请查看日志记录~
, 54 | negativeText: '确定', 55 | }); 56 | return; 57 | } 58 | deviceStore.isEnableShowNotificationIconNum = true; 59 | } else { 60 | const [removeIsEnableShowNotificationIconNumErr] = await $to修改失败,详情请查看日志记录~
, 69 | negativeText: '确定', 70 | }); 71 | return; 72 | } 73 | deviceStore.isEnableShowNotificationIconNum = false; 74 | } 75 | }; 76 | 77 | const changeNum = async (num: number) => { 78 | const [removeShowNotificationIconNumErr] = await $to修改失败,详情请查看日志记录~
, 85 | negativeText: '确定', 86 | }); 87 | return; 88 | } 89 | 90 | const [addShowNotificationIconNumErr] = await $to修改失败,详情请查看日志记录~
, 98 | negativeText: '确定', 99 | }); 100 | } 101 | 102 | const [putCurrentStatusBarShowNotificationIconErr] = await $to修改失败,详情请查看日志记录~
, 112 | negativeText: '确定', 113 | }); 114 | } 115 | }; 116 | 117 | const fetchData = async () => { 118 | if (deviceStore.isEnableShowNotificationIconNum) { 119 | const [, getIsEnableShowNotificationIconNumResolve] = await $to您可以通过收集表提交您的应用适配需求OwO,提交前请认真阅读须知~
52 |https://docs.qq.com/form/page/DRUhJQkhzSnp6dWhm
53 |发生异常错误,设置动态壁纸循环播放失败QwQ,详细错误请查看日志~
34 | ), 35 | }); 36 | return; 37 | } 38 | const [setLockVideoWallpaperLoopErr,setLockVideoWallpaperLoopRes] = await $to发生异常错误,设置动态壁纸循环播放失败QwQ,详细错误请查看日志~
46 | ), 47 | }); 48 | return; 49 | } 50 | modal.create({ 51 | title: '设置循环播放成功', 52 | type: 'success', 53 | preset: 'dialog', 54 | content: () => ( 55 |56 | 好耶w,已经成功动态壁纸循环播放~实际生效还需要重启{' '} 57 | 58 | 壁纸 59 | {' '} 60 | 的作用域,确定要继续吗? 61 |
62 | ), 63 | positiveText: '确定重启作用域', 64 | negativeText: '稍后手动重启', 65 | onPositiveClick() { 66 | deviceApi 67 | .killMiWallpaper() 68 | .then(async res => { 69 | modal.create({ 70 | title: '重启作用域成功', 71 | type: 'success', 72 | preset: 'dialog', 73 | content: () =>已经成功为你重启对应的作用域,请查看是否生效~
, 74 | }); 75 | }) 76 | .catch(err => { 77 | modal.create({ 78 | title: '重启作用域失败', 79 | type: 'error', 80 | preset: 'dialog', 81 | content: () => ( 82 |发生异常错误,重启系统界面作用域失败QwQ,详细错误请查看日志~
83 | ), 84 | }); 85 | }); 86 | }, 87 | }); 88 | } 89 | 90 | return { 91 | change 92 | }; 93 | } 94 | -------------------------------------------------------------------------------- /src/hooks/useZRAMWriteback.tsx: -------------------------------------------------------------------------------- 1 | import { ref, computed, onMounted, nextTick } from 'vue'; 2 | import { useDeviceStore } from '@/stores/device'; 3 | import $to from 'await-to-js'; 4 | import { 5 | NButton, 6 | createDiscreteApi, 7 | darkTheme, 8 | lightTheme, 9 | type ConfigProviderProps, 10 | type DataTableColumns, 11 | type NInput, 12 | } from 'naive-ui'; 13 | import * as deviceApi from '@/apis/deviceApi'; 14 | export function useZRAMWriteback() { 15 | const deviceStore = useDeviceStore(); 16 | const configProviderPropsRef = computed55 | 在这里可以查看小米的部分云控节点配置 56 |
57 |年从节换,新岁已至,转眼已经迎来了「2025」年。
18 |「2024年3月31日」,我正式接手「完美横屏应用计划」
19 |至今,新版「完美横屏应用计划」共陪伴了大家「246」天。
20 |诞生了「2907」个提交和「683」个版本。
21 |你们对「完美横屏应用计划」的认可,也是我维护下去的动力!
22 |不管何时何地,「遇见你们都是我最美好的事」,感谢大家的一路相伴。
23 |愿「新年胜旧年」,多喜乐,长安宁。
24 |年年皆胜意,岁岁皆欢愉,祝大家「新年快乐」!
25 |十分感谢所有给「完美横屏应用计划」打赏给予认可的酷友。
26 |最后感谢「柚稚」、「Kirara」和「御坂初琴」给我提供了不少的帮助!
27 |「2025年1月1日」 By 做梦书 致辞
28 |106 | 在这里可以查看本次 Web UI 运行中产生的日志 107 |
108 |110 | 若有影响使用的问题可以通过酷安/Github/模块反馈群上进行反馈 111 |
112 |404
9 |13 | 您似乎访问了一片荒漠QwQ~ 14 |
15 |