mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-10-31 04:02:59 +08:00 
			
		
		
		
	docs: 选择框与确认框、新增属性
This commit is contained in:
		
							parent
							
								
									c26ae39060
								
							
						
					
					
						commit
						d39e2c2159
					
				| @ -78,6 +78,10 @@ export default defineConfig({ | |||||||
|                                 { |                                 { | ||||||
|                                     text: '动画效果', |                                     text: '动画效果', | ||||||
|                                     link: '/guide/implements/animate' |                                     link: '/guide/implements/animate' | ||||||
|  |                                 }, | ||||||
|  |                                 { | ||||||
|  |                                     text: '选择框与确认框', | ||||||
|  |                                     link: '/guide/implements/choice' | ||||||
|                                 } |                                 } | ||||||
|                             ] |                             ] | ||||||
|                         } |                         } | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ | |||||||
| function onOrientationChange(hook: OrientationHook): void; | function onOrientationChange(hook: OrientationHook): void; | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| 监听屏幕方向变化事件。   | 监听屏幕方向变化事件。需要在组件内或 UI 内调用。   | ||||||
| **参数** | **参数** | ||||||
| 
 | 
 | ||||||
| - `hook`: 方向变化回调函数 | - `hook`: 方向变化回调函数 | ||||||
| @ -28,6 +28,7 @@ type OrientationHook = ( | |||||||
| ```typescript | ```typescript | ||||||
| import { onOrientationChange, Orientation } from './use'; | import { onOrientationChange, Orientation } from './use'; | ||||||
| 
 | 
 | ||||||
|  | // 组件内 | ||||||
| onOrientationChange((orient, width) => { | onOrientationChange((orient, width) => { | ||||||
|     if (orient === Orientation.Portrait) { |     if (orient === Orientation.Portrait) { | ||||||
|         // 竖屏模式 |         // 竖屏模式 | ||||||
|  | |||||||
							
								
								
									
										189
									
								
								docs/guide/implements/choice.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								docs/guide/implements/choice.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,189 @@ | |||||||
|  | # 选择框与确认框 | ||||||
|  | 
 | ||||||
|  | 2.B 提供的简单的确认框与选择框接口,允许你用几行代码就可以弹出一个确认框让用户确认,或是弹出选择框让用户选择,不再需要像 2.x 一样用非常不好用的 `myconfirm` 或 `insertAction` 事件流了。 | ||||||
|  | 
 | ||||||
|  | ## 确认框 | ||||||
|  | 
 | ||||||
|  | 假设我们需要在点击一个按钮后弹出应该确认框,让玩家确认操作,可以使用 `getConfirm` 或 `routedConfirm` 接口。假设我们在 `packages-user/client-modules/src/render/ui` 文件夹下的 UI 中实现这一需求,我们可以这么写: | ||||||
|  | 
 | ||||||
|  | ```tsx | ||||||
|  | // 从 components 文件夹引入接口,注意路径关系 | ||||||
|  | import { getConfirm } from '../components'; | ||||||
|  | 
 | ||||||
|  | // UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出 | ||||||
|  | export const MyCom = defineComponent(props => { | ||||||
|  |     /** 当鼠标点击时触发,由于 getConfirm 是异步函数,这里的 click 也需要异步 */ | ||||||
|  |     const click = async () => { | ||||||
|  |         // 调用接口,并等待执行完毕,获取异步返回值 | ||||||
|  |         const confirm = await getConfirm( | ||||||
|  |             props.controller, // 使用打开当前 UI 的控制器作为 UI 控制器 | ||||||
|  |             '确认要 XXX 吗?', // 提示文字 | ||||||
|  |             [240, 240, void 0, void 0, 0.5, 0.5], // 确认框所处的位置,这里使用居中对齐,中心点在 (240,240) 位置 | ||||||
|  |             240, // 确认框的宽度 | ||||||
|  |             { | ||||||
|  |                 // 这一参数具体看后面的解释 | ||||||
|  |                 selFill: 'gold' // 选项文字使用金色 | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |         if (confirm) { | ||||||
|  |             // 如果用户选择了确认,可以执行确认内容,例如显示一个提示 | ||||||
|  |             core.drawTip('用户确认'); | ||||||
|  |         } else { | ||||||
|  |             // 如果用户选择了取消,可以执行取消内容 | ||||||
|  |             core.drawTip('用户取消'); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return () => ( | ||||||
|  |         <container> | ||||||
|  |             <text | ||||||
|  |                 text="这是一个按钮" | ||||||
|  |                 // 监听 click 事件 | ||||||
|  |                 onClick={click} | ||||||
|  |             /> | ||||||
|  |         </container> | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 其中 `getConfirm` 的最后一个参数是一个对象,可以传入 `ConfirmBox` 组件的参数,具体可以参考[此文档](../../api/user-client-modules/组件%20ConfirmBox.md)。例如 `selFill` 是 `ConfirmBox` 控制选项填充样式的参数。 | ||||||
|  | 
 | ||||||
|  | 除此之外,还有一个 `routedConfirm` 接口,此接口与 `getConfirm` 引入方式相同,主要差别为 `routedConfirm` 会自动处理录像。但是这并不意味着用 `routedConfirm` 比 `getConfirm` 更好,因为我们一般会在客户端(渲染端)调用它,而客户端的内容在录像验证时是不会执行的,这就可能导致录像出错。一般情况下,我们只需要使用 `getConfirm` 接口,而需要使用 `routedConfirm` 的场景已经在样板中处理。 | ||||||
|  | 
 | ||||||
|  | **总结成一句话就是**:一般情况下不要使用 `routedConfirm`,使用 `getConfirm` 即可。 | ||||||
|  | 
 | ||||||
|  | ## 选择框 | ||||||
|  | 
 | ||||||
|  | 选择框会给玩家提供一系列选项,让玩家选择某一项,并返回玩家选择的内容。使用 `getChoice` 接口,示例如下: | ||||||
|  | 
 | ||||||
|  | ```tsx | ||||||
|  | // 从 components 文件夹引入接口,注意路径关系 | ||||||
|  | import { getChoice } from '../components'; // [!code ++] | ||||||
|  | 
 | ||||||
|  | // UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出 | ||||||
|  | export const MyCom = defineComponent(props => { | ||||||
|  |     // 选项内容,第一项是 id,第二项是该选项的显示内容 | ||||||
|  |     // 第一项 id 可以填字符串或者数字 | ||||||
|  |     const choices: ChoiceItem[] = [ | ||||||
|  |         ['key1', '选项1'], // 第一个选项 | ||||||
|  |         ['key2', '选项2'] // 第二个选项 | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     /** 同样,由于 getChoice 是异步函数,这里的 click 也需要异步 */ | ||||||
|  |     const click = async () => { | ||||||
|  |         // 调用接口,并等待执行完毕,获取异步返回值 | ||||||
|  |         const choice = await getChoice( | ||||||
|  |             props.controller, // 使用打开当前 UI 的控制器作为 UI 控制器 | ||||||
|  |             choices, // 在这里传入选项内容 | ||||||
|  |             [240, 240, void 0, void 0, 0.5, 0.5], // 选择框所处的位置 | ||||||
|  |             240, // 选择框的宽度 | ||||||
|  |             { | ||||||
|  |                 // 可选参数,例如显示提示文字 | ||||||
|  |                 text: '请选择一项' | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |         // 使用 switch 判断 | ||||||
|  |         switch (choice) { | ||||||
|  |             case 'key1': | ||||||
|  |                 // 选择了第一个选项时 | ||||||
|  |                 core.drawTip('选择了第一项'); | ||||||
|  |                 break; | ||||||
|  |             // ... 其他判断 | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return () => ( | ||||||
|  |         <container> | ||||||
|  |             <text | ||||||
|  |                 text="这是一个按钮" | ||||||
|  |                 // 监听 click 事件 | ||||||
|  |                 onClick={click} | ||||||
|  |             /> | ||||||
|  |         </container> | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 同样,`getChoice` 也有一个对应的 `routedChoice`,依然建议一般情况下只使用 `getChoice`,不使用 `routedChoice`。 | ||||||
|  | 
 | ||||||
|  | ## 拓展-使用枚举定义选择框 | ||||||
|  | 
 | ||||||
|  | 如果使用字符串定义选择框的 `id`,一来没有严格的类型标注,二来字符串的性能也较差,因此我们推荐使用枚举定义选择框的 `id`。首先我们先编写一段枚举: | ||||||
|  | 
 | ||||||
|  | ```ts | ||||||
|  | // 定义选项枚举,可以写一些有意义的单词辅助记忆 | ||||||
|  | const enum MyChoice { | ||||||
|  |     Choice1, // 第一个选项 | ||||||
|  |     Choice2, // 第二个选项 | ||||||
|  |     Choice3 // 第三个选项 | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 然后在选择框定义中使用枚举定义: | ||||||
|  | 
 | ||||||
|  | ```ts | ||||||
|  | const choices: Choices<MyChoice>[] = [ | ||||||
|  |     [MyChoice.Choice1, '选项1'], | ||||||
|  |     [MyChoice.Choice2, '选项2'], | ||||||
|  |     [MyChoice.Choice3, '选项3'] | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | // 这里不变 | ||||||
|  | const choice = await getChoice( | ||||||
|  |     props.controller | ||||||
|  |     choices | ||||||
|  |     [240, 240, void 0, void 0, 0.5, 0.5] | ||||||
|  |     240 | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | // 可以用 switch 判断 | ||||||
|  | switch (choice) { | ||||||
|  |     case MyChoice.Choice1: | ||||||
|  |         // 选择选项1时 | ||||||
|  |         break; | ||||||
|  |     // ... 其他内容 | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 拓展-等待框 | ||||||
|  | 
 | ||||||
|  | 等待框也是一种类似于确认框的东西,不过它用来等待一个操作执行完毕,同时给用户显示一个界面,可以是复杂逻辑运算,也可以是网络请求等。以等待网络请求为例: | ||||||
|  | 
 | ||||||
|  | ```tsx | ||||||
|  | // 从 components 文件夹引入接口,注意路径关系 | ||||||
|  | import { waitbox } from '../components'; | ||||||
|  | 
 | ||||||
|  | // UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出 | ||||||
|  | export const MyCom = defineComponent(props => { | ||||||
|  |     const click = async () => { | ||||||
|  |         // 等待网络请求,同时展示一个等待框让玩家不孤单 | ||||||
|  |         const response = await waitbox( | ||||||
|  |             props.controller, // 控制器 | ||||||
|  |             [240, 240, void 0, void 0, 0.5, 0.5], // 位置 | ||||||
|  |             240, // 宽度 | ||||||
|  |             fetch('/api/example') // 一个 fetch 请求 | ||||||
|  |         ); | ||||||
|  |         // 之后就可以直接使用了 | ||||||
|  |         const body = response.body; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return () => ( | ||||||
|  |         <container> | ||||||
|  |             <text | ||||||
|  |                 text="这是一个按钮" | ||||||
|  |                 // 监听 click 事件 | ||||||
|  |                 onClick={click} | ||||||
|  |             /> | ||||||
|  |         </container> | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 拓展-API参考 | ||||||
|  | 
 | ||||||
|  | - [ConfirmBox](../../api/user-client-modules/组件%20ConfirmBox.md) | ||||||
|  | - [Choices](../../api/user-client-modules/组件%20Choices.md) | ||||||
|  | - [Waitbox](../../api/user-client-modules/组件%20Waitbox.md) | ||||||
|  | - [getConfirm](../../api/user-client-modules/functions.md#getconfirm) | ||||||
|  | - [getChoice](../../api/user-client-modules/functions.md#getchoice) | ||||||
|  | - [waitbox](../../api/user-client-modules/functions.md#waitbox) | ||||||
| @ -10,6 +10,8 @@ | |||||||
| - [修改状态栏显示](./status-bar.md) | - [修改状态栏显示](./status-bar.md) | ||||||
| - [编写新 UI](./new-ui.md) | - [编写新 UI](./new-ui.md) | ||||||
| - [自定义按键](./hotkey.md) | - [自定义按键](./hotkey.md) | ||||||
|  | - [动画效果](./animate.md) | ||||||
|  | - [选择框与确认框](./choice.md) | ||||||
| 
 | 
 | ||||||
| ## 数据端内容 | ## 数据端内容 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -109,6 +109,78 @@ export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>( | |||||||
| ); | ); | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ## 拓展-新增勇士属性 | ||||||
|  | 
 | ||||||
|  | 在上例中,展示了如何显示一个自定义的 `flag`,但有时候我们需要自定义一个勇士属性,例如攻速、减伤等,这些属性可能会受到全局 `buff` 的影响,这时候使用 `flag` 就不方便,我们推荐使用自定义属性的方式。 | ||||||
|  | 
 | ||||||
|  | ### 定义属性 | ||||||
|  | 
 | ||||||
|  | 我们打开编辑器的全塔属性界面,点击左侧上方的编辑表格按钮,向下滑动找到 `勇士攻击` 等勇士属性(约第 250 行)的位置,仿照这些属性增加一个新的属性,例如添加攻速,取属性名为 `atkSpeed`: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | { | ||||||
|  |     "mana": { | ||||||
|  |         "_leaf": true, | ||||||
|  |         "_type": "textarea", | ||||||
|  |         "_data": "初始魔力" | ||||||
|  |     }, | ||||||
|  |     "atkSpeed": { // [!code ++] | ||||||
|  |         "_leaf": true, // [!code ++] | ||||||
|  |         "_type": "textarea", // [!code ++] | ||||||
|  |         "_data": "初始攻速" // [!code ++] | ||||||
|  |     }, // [!code ++] | ||||||
|  |     "atk": { | ||||||
|  |         "_leaf": true, | ||||||
|  |         "_type": "textarea", | ||||||
|  |         "_data": "初始攻击" | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 保存后刷新页面,再次进入全塔属性界面,可以看到在勇士属性部分多了一项 `初始攻速`,我们可以输入初始值,例如设为初始值 `1`,表示攻速为 `100%`。 | ||||||
|  | 
 | ||||||
|  | 接下来回到 `vscode`,打开文件 `src/types/declaration/status.d.ts`,按下 `ctrl+F` 搜索 `interface HeroStatus`,在其中新增一个属性值 `atkSpeed`: | ||||||
|  | 
 | ||||||
|  | ```ts | ||||||
|  | interface HeroStatus { | ||||||
|  |     // ... 原有内容 | ||||||
|  | 
 | ||||||
|  |     /** 勇士攻速 */ | ||||||
|  |     atkSpeed: number; // [!code ++] | ||||||
|  | 
 | ||||||
|  |     // ... 原有内容 | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 容错处理 | ||||||
|  | 
 | ||||||
|  | 为了保证属性添加前的存档还能正常加载,我们需要容错处理,打开编辑器,进入脚本编辑界面,编辑 `重置游戏` 这一脚本编辑项。我们在函数的最后进行容错处理: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | function () { | ||||||
|  |     // ... 原有内容 | ||||||
|  | 
 | ||||||
|  |     // 容错处理 | ||||||
|  |     core.status.hero.atkSpeed ??= 1; // [!code ++] | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 由于样板编辑器的限制,上述代码会有语法报错,但实际上不会有任何问题,关闭语法检查再保存即可。 | ||||||
|  | 
 | ||||||
|  | ### 状态栏显示 | ||||||
|  | 
 | ||||||
|  | 与本文章最初的示例基本一致,只有传入属性值时需要略加变动,其他操作包括属性定义等不改变,将赋值行为改为 `getHeroStatusOn`: | ||||||
|  | 
 | ||||||
|  | ```ts | ||||||
|  | leftStatus.atk = getHeroStatusOn('atk'); | ||||||
|  | leftStatus.hp = getHeroStatusOn('hp'); | ||||||
|  | leftStatus.def = getHeroStatusOn('def'); | ||||||
|  | // ... 原有内容 | ||||||
|  | 
 | ||||||
|  | // 改为 getHeroStatusOn | ||||||
|  | leftStatus.atkSpeed = getHeroStatusOn('atkSpeed'); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## 拓展-了解 UI 编写的基本逻辑 | ## 拓展-了解 UI 编写的基本逻辑 | ||||||
| 
 | 
 | ||||||
| 参考[此文档](./ui.md),此文档将会教你如何从头开始编写一个 UI,并解释 UI 运行与渲染的基本逻辑。 | 参考[此文档](./ui.md),此文档将会教你如何从头开始编写一个 UI,并解释 UI 运行与渲染的基本逻辑。 | ||||||
|  | |||||||
| @ -6,6 +6,26 @@ | |||||||
| 
 | 
 | ||||||
| 参考[此文档](./implements.md) | 参考[此文档](./implements.md) | ||||||
| 
 | 
 | ||||||
|  | ## 启动游戏与编辑器 | ||||||
|  | 
 | ||||||
|  | 在造塔群中的群文件中找到 `启动服务->2.B+ 启动服务`,根据自己设备的系统下载对应的启动服务(此版本不支持移动端造塔),下载后运行安装到自己的设备,可以选择安装路径。 | ||||||
|  | 
 | ||||||
|  | 安装完毕后,打开软件,在左侧点击选择文件夹,然后打开 2.B 样板文件夹,即包含 `package.json` `packages` `packages-user` 这些目录的文件,打开错了会提示打开错误。 | ||||||
|  | 
 | ||||||
|  | 然后点击右侧的安装依赖,耐心等待一段时间,等待依赖安装完毕。 | ||||||
|  | 
 | ||||||
|  | 然后点击右侧的启动服务器,等待服务器启动,启动完毕后会自动使用默认浏览器打开游戏、编辑器和帮助文档。 | ||||||
|  | 
 | ||||||
|  | 当你**制作完游戏**后,点击构建游戏,即可自动构建游戏,构建结果在 `dist` 文件夹,会自动打包到 `dist.zip` 压缩包,发塔或更新上传此压缩包即可。 | ||||||
|  | 
 | ||||||
|  | 此帮助文档远比 2.x 的文档易读,也更容易理解,建议多阅读此文档来解决自己的问题,如果问题很复杂,或是短时间内解决不了,再去造塔群询问。 | ||||||
|  | 
 | ||||||
|  | ```mermaid | ||||||
|  | graph TD | ||||||
|  |     A[下载安装包] --> B[安装启动服务] --> C[运行启动服务] --> D[选择样板文件夹] --> E[安装依赖] --> F[启动服务器]; | ||||||
|  |     F -- 造完塔 --> G[构建游戏] --> H[发布或更新游戏] | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## 编辑器 | ## 编辑器 | ||||||
| 
 | 
 | ||||||
| 编辑器与 2.x 的编辑器差别不大,但 2.B 的编辑器多了一些功能: | 编辑器与 2.x 的编辑器差别不大,但 2.B 的编辑器多了一些功能: | ||||||
| @ -62,7 +82,7 @@ | |||||||
| 
 | 
 | ||||||
| ### 协议问题 | ### 协议问题 | ||||||
| 
 | 
 | ||||||
| 2.B 样板换用了 `GPL3.0` 开源协议,这要求所有以此为基础开发的项目也必须完全开源,但考虑到很多作者不了解其中的细节,因此样板将会针对此问题进行处理,处理方案为:**将源码原封不动地打包为压缩包,放到构建完成的游戏中**,届时,只要在网站上下载游戏,就可以解压压缩包查看源码。 | 2.B 样板换用了 `GPL3.0` 开源协议,这要求所有以此为基础开发的项目也必须完全开源,但考虑到很多作者不了解其中的细节,因此样板将会针对此问题自动处理,处理方案为:**将源码原封不动地打包为压缩包,放到构建完成的游戏中**,届时,只要在网站上下载游戏,就可以解压压缩包查看源码。 | ||||||
| 
 | 
 | ||||||
| ## 学会查阅此文档 | ## 学会查阅此文档 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -194,7 +194,10 @@ export const ConfirmBox = defineComponent< | |||||||
| }, confirmBoxProps); | }, confirmBoxProps); | ||||||
| 
 | 
 | ||||||
| export type ChoiceKey = string | number; | export type ChoiceKey = string | number; | ||||||
| export type ChoiceItem = [key: ChoiceKey, text: string]; | export type ChoiceItem<T extends ChoiceKey = ChoiceKey> = [ | ||||||
|  |     key: T, | ||||||
|  |     text: string | ||||||
|  | ]; | ||||||
| 
 | 
 | ||||||
| export interface ChoicesProps extends DefaultProps, TextContentProps { | export interface ChoicesProps extends DefaultProps, TextContentProps { | ||||||
|     choices: ChoiceItem[]; |     choices: ChoiceItem[]; | ||||||
| @ -614,11 +617,11 @@ export function getConfirm( | |||||||
|  */ |  */ | ||||||
| export function getChoice<T extends ChoiceKey = ChoiceKey>( | export function getChoice<T extends ChoiceKey = ChoiceKey>( | ||||||
|     controller: IUIMountable, |     controller: IUIMountable, | ||||||
|     choices: ChoiceItem[], |     choices: ChoiceItem<T>[], | ||||||
|     loc: ElementLocator, |     loc: ElementLocator, | ||||||
|     width: number, |     width: number, | ||||||
|     props?: Partial<ChoicesProps> |     props?: Partial<ChoicesProps> | ||||||
| ) { | ): Promise<T> { | ||||||
|     return new Promise<T>(res => { |     return new Promise<T>(res => { | ||||||
|         const instance = controller.open( |         const instance = controller.open( | ||||||
|             ChoicesUI, |             ChoicesUI, | ||||||
| @ -681,6 +684,7 @@ export async function routedConfirm( | |||||||
|     if (core.isReplaying()) { |     if (core.isReplaying()) { | ||||||
|         const confirm = getChoiceRoute() === 1; |         const confirm = getChoiceRoute() === 1; | ||||||
|         const timeout = core.control.__replay_getTimeout(); |         const timeout = core.control.__replay_getTimeout(); | ||||||
|  |         core.status.route.push(`choices:${confirm ? 1 : 0}`); | ||||||
|         if (timeout === 0) return confirm; |         if (timeout === 0) return confirm; | ||||||
|         const instance = controller.open(ConfirmBoxUI, { |         const instance = controller.open(ConfirmBoxUI, { | ||||||
|             ...(props ?? {}), |             ...(props ?? {}), | ||||||
| @ -724,17 +728,18 @@ export async function routedConfirm( | |||||||
|  * @param width 选择框的宽度 |  * @param width 选择框的宽度 | ||||||
|  * @param props 额外的 props,参考 {@link ChoicesProps} |  * @param props 额外的 props,参考 {@link ChoicesProps} | ||||||
|  */ |  */ | ||||||
| export async function routedChoices( | export async function routedChoices<T extends ChoiceKey>( | ||||||
|     controller: IUIMountable, |     controller: IUIMountable, | ||||||
|     choices: ChoiceItem[], |     choices: ChoiceItem<T>[], | ||||||
|     loc: ElementLocator, |     loc: ElementLocator, | ||||||
|     width: number, |     width: number, | ||||||
|     props?: Partial<ChoicesProps> |     props?: Partial<ChoicesProps> | ||||||
| ) { | ): Promise<T> { | ||||||
|     if (core.isReplaying()) { |     if (core.isReplaying()) { | ||||||
|         const selected = getChoiceRoute(); |         const selected = getChoiceRoute(); | ||||||
|         const timeout = core.control.__replay_getTimeout(); |         const timeout = core.control.__replay_getTimeout(); | ||||||
|         if (timeout === 0) return selected; |         core.status.route.push(`choices:${selected}`); | ||||||
|  |         if (timeout === 0) return choices[selected][0]; | ||||||
|         const instance = controller.open(ChoicesUI, { |         const instance = controller.open(ChoicesUI, { | ||||||
|             ...(props ?? {}), |             ...(props ?? {}), | ||||||
|             choices, |             choices, | ||||||
| @ -744,7 +749,7 @@ export async function routedChoices( | |||||||
|         }); |         }); | ||||||
|         await sleep(core.control.__replay_getTimeout()); |         await sleep(core.control.__replay_getTimeout()); | ||||||
|         controller.close(instance); |         controller.close(instance); | ||||||
|         return selected; |         return choices[selected][0]; | ||||||
|     } else { |     } else { | ||||||
|         const choice = await getChoice(controller, choices, loc, width, props); |         const choice = await getChoice(controller, choices, loc, width, props); | ||||||
|         const index = choices.findIndex(v => v[1] === choice); |         const index = choices.findIndex(v => v[1] === choice); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user