Skip to content

Commit f169406

Browse files
authored
Merge pull request #5 from 2214962083/dev
修复fragment失效问题、修复透明背景bug、修改help.ts里的showPreviewOptions函数的接收参数
2 parents 6a6971e + f7d5273 commit f169406

File tree

6 files changed

+1206
-42
lines changed

6 files changed

+1206
-42
lines changed

src/lib/help.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -737,28 +737,37 @@ export function sleep(ms: number): Promise<void> {
737737

738738
/**
739739
* 显示预览尺寸菜单
740-
* @param widget 组件实例
740+
* @param render render渲染函数,返回 widget 实例
741741
*/
742-
export async function showPreviewOptions(widget: ListWidget): Promise<number> {
742+
export async function showPreviewOptions(
743+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
744+
render: (...params: any[]) => ListWidget | Promise<ListWidget | unknown>,
745+
): Promise<number> {
743746
const selectIndex = await showActionSheet({
744747
title: '预览组件',
745748
desc: '测试桌面组件在各种尺寸下的显示效果',
746749
itemList: ['小尺寸', '中尺寸', '大尺寸', '全部尺寸'],
747750
})
748751
switch (selectIndex) {
749752
case 0:
750-
await widget.presentSmall()
753+
config.widgetFamily = 'small'
754+
await ((await render()) as ListWidget).presentSmall()
751755
break
752756
case 1:
753-
await widget.presentMedium()
757+
config.widgetFamily = 'medium'
758+
await ((await render()) as ListWidget).presentMedium()
754759
break
755760
case 2:
756-
await widget.presentLarge()
761+
config.widgetFamily = 'large'
762+
await ((await render()) as ListWidget).presentLarge()
757763
break
758764
case 3:
759-
await widget.presentSmall()
760-
await widget.presentMedium()
761-
await widget.presentLarge()
765+
config.widgetFamily = 'small'
766+
await ((await render()) as ListWidget).presentSmall()
767+
config.widgetFamily = 'medium'
768+
await ((await render()) as ListWidget).presentMedium()
769+
config.widgetFamily = 'large'
770+
await ((await render()) as ListWidget).presentLarge()
762771
break
763772
}
764773
return selectIndex
@@ -991,7 +1000,7 @@ export async function setTransparentBackground(tips?: string): Promise<Image | u
9911000
crop.h = phone.large
9921001
crop.x = phone.left
9931002
positions = ['顶部', '底部']
994-
_positions = ['top', 'bottom']
1003+
_positions = ['top', 'middle']
9951004
positionIndex = await selectLocation(positions)
9961005
key = _positions[positionIndex] as WidgetSize
9971006
crop.y = phone[key]

src/lib/jsx-runtime.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,9 @@ export function h(
321321
...children: Children<Scriptable.Widget> | string[]
322322
): Promise<unknown> | unknown {
323323
props = props || {}
324-
// 由于 Fragment 的存在,children 可能为一、二维数组混合,先把它展平
325-
const _children = [].concat(...(children as never[])) as typeof children
324+
325+
// 由于 Fragment 的存在,children 可能为多维数组混合,先把它展平
326+
const _children = flatteningArr(children as unknown[]) as typeof children
326327

327328
switch (type) {
328329
case 'wbox':
@@ -356,6 +357,18 @@ export function Fragment({children}: {children: typeof h[]}): typeof h[] {
356357
return children
357358
}
358359

360+
/**
361+
* 展平所有维度数组
362+
* @param arr 数组
363+
*/
364+
function flatteningArr<T>(arr: T[]): T[] {
365+
return [].concat(
366+
...arr.map((item: T | T[]) => {
367+
return (Array.isArray(item) ? flatteningArr(item) : item) as never[]
368+
}),
369+
) as T[]
370+
}
371+
359372
/**
360373
* 输出真正颜色(比如string转color)
361374
* @param color

src/scripts/funds.tsx

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import {
2+
isLaunchInsideApp,
3+
request,
4+
ResponseType,
5+
setTransparentBackground,
6+
showActionSheet,
7+
showModal,
8+
showNotification,
9+
showPreviewOptions,
10+
useStorage,
11+
} from '@app/lib/help'
12+
13+
interface FundInfo {
14+
/**基金代码*/
15+
FCODE: string
16+
17+
/**基金名字*/
18+
SHORTNAME: string
19+
20+
/**日期*/
21+
PDATE: string
22+
23+
/**单位净值数值*/
24+
NAV: string
25+
26+
/**累计净值数值*/
27+
ACCNAV: string
28+
29+
/**单位净值涨跌百分比*/
30+
NAVCHGRT: string
31+
32+
/**单位净值估算数值*/
33+
GSZ: string
34+
35+
/**单位净值估算涨跌百分比*/
36+
GSZZL: string
37+
38+
/**更新时间*/
39+
GZTIME: string
40+
NEWPRICE: string
41+
CHANGERATIO: string
42+
ZJL: string
43+
HQDATE: string
44+
ISHAVEREDPACKET: boolean
45+
}
46+
47+
interface FundsData {
48+
Datas: FundInfo[]
49+
ErrCode: number
50+
Success: boolean
51+
ErrMsg: null | string
52+
Message: null | string
53+
ErrorCode: string
54+
ErrorMessage: null | string
55+
ErrorMsgLst: null | string
56+
TotalCount: number
57+
Expansion: {
58+
GZTIME: string
59+
FSRQ: string
60+
}
61+
}
62+
63+
const {setStorage, getStorage} = useStorage('Funds')
64+
const transparentBg: Image | string = getStorage<Image>('transparentBg') || '#fff'
65+
const textColor = getStorage<string>('textColor') || (transparentBg === '#fff' ? '#000' : '#fff')
66+
const bgColor = getStorage<string>('bgColor') || '#ffffff00'
67+
const fundsCode = getStorage<string[]>('fundsCode') || []
68+
69+
/**生成表格列组件*/
70+
function getFundColumn(fundsInfo: FundInfo[], title: string, keyName: keyof FundInfo) {
71+
// 数值个性化
72+
function showValue(value: FundInfo[keyof FundInfo]): Partial<Record<keyof FundInfo, JSX.Element>> {
73+
return {
74+
// 涨跌幅文字特别处理(涨绿,跌红)
75+
GSZZL: (
76+
<wtext font={Font.lightSystemFont(14)} textColor={Number(value) >= 0 ? '#4eff4e' : '#ff4e4e'}>
77+
{value + '%'}
78+
</wtext>
79+
),
80+
}
81+
}
82+
return (
83+
<wstack flexDirection="column">
84+
<wtext font={14} textColor={textColor}>
85+
{title}
86+
</wtext>
87+
{fundsInfo.map(fundInfo => {
88+
const value = fundInfo[keyName]
89+
return (
90+
<>
91+
<wspacer length={14}></wspacer>
92+
{showValue(value)[keyName] || (
93+
<wtext font={Font.lightSystemFont(14)} textColor={textColor}>
94+
{value}
95+
</wtext>
96+
)}
97+
</>
98+
)
99+
})}
100+
</wstack>
101+
)
102+
}
103+
104+
class Funds {
105+
async init() {
106+
if (isLaunchInsideApp()) {
107+
return await this.showMenu()
108+
}
109+
const widget = (await this.render()) as ListWidget
110+
Script.setWidget(widget)
111+
Script.complete()
112+
}
113+
114+
//渲染组件
115+
async render(): Promise<unknown> {
116+
let fundsInfo: FundInfo[] = []
117+
try {
118+
const result = (await this.getFundsData(this.getFundsCode())).data as FundsData
119+
fundsInfo = result.Datas || []
120+
} catch (err) {}
121+
122+
return (
123+
<wbox padding={[0, 0, 0, 0]} background={transparentBg} updateDate={new Date(Date.now() + 30 * 1000)}>
124+
<wstack padding={[16, 16, 16, 16]} flexDirection="column" background={bgColor}>
125+
<wstack>
126+
{getFundColumn(fundsInfo, '基金名字', 'SHORTNAME')}
127+
<wspacer></wspacer>
128+
{getFundColumn(fundsInfo, '估算净值', 'GSZ')}
129+
<wspacer></wspacer>
130+
{getFundColumn(fundsInfo, '涨跌幅', 'GSZZL')}
131+
</wstack>
132+
<wspacer></wspacer>
133+
<wstack>
134+
<wspacer></wspacer>
135+
<wtext font={Font.lightSystemFont(12)} opacity={0.5} textColor={textColor}>
136+
更新时间: {new Date().toLocaleTimeString('chinese', {hour12: false})}
137+
</wtext>
138+
<wspacer></wspacer>
139+
</wstack>
140+
</wstack>
141+
</wbox>
142+
)
143+
}
144+
145+
// 显示菜单
146+
async showMenu() {
147+
const selectIndex = await showActionSheet({
148+
title: '菜单',
149+
itemList: ['设置基金代码', '预览组件', '设置透明背景', '设置文字和背景颜色'],
150+
})
151+
switch (selectIndex) {
152+
case 0:
153+
const {texts: fundsCodeTexts} = await showModal({
154+
title: '设置基金代码',
155+
content: '最多只能设置9个,在中尺寸下只显示前3个, 多个代码用逗号隔开。例如:002207, 002446, 161005',
156+
inputItems: [
157+
{
158+
text: (getStorage<string[]>('fundsCode') || []).join(', '),
159+
placeholder: '例如:002207, 002446, 161005',
160+
},
161+
],
162+
})
163+
if (fundsCodeTexts[0]) {
164+
const fundsCode = fundsCodeTexts[0].match(/[\d]{6}/g) || []
165+
setStorage('fundsCode', fundsCode)
166+
}
167+
break
168+
case 1:
169+
await showPreviewOptions(this.render.bind(this))
170+
break
171+
case 2:
172+
const img: Image | null = (await setTransparentBackground()) || null
173+
img && setStorage('transparentBg', img)
174+
img && (await showNotification({title: '设置透明背景成功', sound: 'default'}))
175+
break
176+
case 3:
177+
const {texts} = await showModal({
178+
title: '设置文字和背景颜色',
179+
content: '黑色是#000,白色是#fff,半透明白是 #ffffff88, 半透明黑是 #00000088',
180+
inputItems: [
181+
{
182+
placeholder: `文字颜色,${
183+
getStorage('textColor') ? '当前是' + getStorage('textColor') + ',' : ''
184+
}默认黑色#000`,
185+
},
186+
{
187+
placeholder: `背景颜色,${
188+
getStorage('bgColor') ? '当前是' + getStorage('bgColor') + ',' : ''
189+
}默认白色#fff`,
190+
},
191+
],
192+
})
193+
if (texts[0]) setStorage('textColor', texts[0])
194+
if (texts[1]) setStorage('bgColor', texts[1])
195+
break
196+
}
197+
}
198+
// 获取基金代码数组
199+
getFundsCode(): string[] {
200+
// 大号组件显示9个
201+
// 中号组件显示3个
202+
const defaultFundsCode = ['002207', '002446', '161005', '163406', '008282', '001790', '008641', '001838', '001475']
203+
const _fundsCode = fundsCode.length > 0 ? fundsCode : defaultFundsCode
204+
return config.widgetFamily === 'medium' ? _fundsCode.slice(0, 3) : _fundsCode.slice(0, 9)
205+
}
206+
207+
// 生成 device id
208+
getDeviceId(): string {
209+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
210+
const r = (Math.random() * 16) | 0
211+
const v = c == 'x' ? r : (r & 0x3) | 0x8
212+
return v.toString(16)
213+
})
214+
}
215+
216+
// 获取基金数据
217+
async getFundsData(fundsId: string[]): Promise<ResponseType<FundsData>> {
218+
return request<FundsData>({
219+
url: `https://fundmobapi.eastmoney.com/FundMNewApi/FundMNFInfo?pageIndex=1&pageSize=100&plat=Android&appType=ttjj&product=EFund&Version=1&deviceid=${this.getDeviceId()}&Fcodes=${fundsId.join(
220+
',',
221+
)}`,
222+
dataType: 'json',
223+
})
224+
}
225+
}
226+
227+
new Funds().init()

src/scripts/tsx-bili.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ const {setStorage, getStorage} = useStorage('bilibili-fans')
3030

3131
class BiliFans {
3232
async init() {
33-
const widget = (await this.render()) as ListWidget
3433
if (isLaunchInsideApp()) {
35-
return await this.showMenu(widget)
34+
return await this.showMenu()
3635
}
36+
const widget = (await this.render()) as ListWidget
3737
Script.setWidget(widget)
3838
Script.complete()
3939
}
@@ -94,7 +94,7 @@ class BiliFans {
9494
}
9595

9696
// 显示菜单
97-
async showMenu(widget: ListWidget): Promise<void> {
97+
async showMenu(): Promise<void> {
9898
const selectIndex = await showActionSheet({
9999
title: '菜单',
100100
itemList: ['设置 up 主 id', '预览尺寸'],
@@ -117,7 +117,7 @@ class BiliFans {
117117
break
118118
case 1:
119119
// 预览尺寸
120-
await showPreviewOptions(widget)
120+
await showPreviewOptions(this.render.bind(this))
121121
break
122122
}
123123
}

src/scripts/tsx-yiyan.tsx

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ interface RemoteData {
2222
class YiyanWidget {
2323
private widget!: ListWidget
2424
async init() {
25-
this.widget = (await this.render()) as ListWidget
2625
if (isLaunchInsideApp()) {
27-
return await showPreviewOptions(this.widget)
26+
return await showPreviewOptions(this.render.bind(this))
2827
}
28+
this.widget = (await this.render()) as ListWidget
2929
Script.setWidget(this.widget)
3030
Script.complete()
3131
}
@@ -64,7 +64,6 @@ class YiyanWidget {
6464
})
6565
}
6666
async menu(): Promise<void> {
67-
const optionFunc = [this.selectPreviewSize]
6867
const selectIndex = await showActionSheet({
6968
title: '菜单',
7069
itemList: [
@@ -73,32 +72,9 @@ class YiyanWidget {
7372
},
7473
],
7574
})
76-
optionFunc[selectIndex].apply(this)
77-
}
78-
async selectPreviewSize(): Promise<void> {
79-
const selectIndex = await showActionSheet({
80-
title: '选择预览尺寸',
81-
itemList: [
82-
{
83-
text: '小组件',
84-
},
85-
{
86-
text: '中组件',
87-
},
88-
{
89-
text: '大组件',
90-
},
91-
],
92-
})
9375
switch (selectIndex) {
9476
case 0:
95-
await this.widget.presentSmall()
96-
break
97-
case 1:
98-
await this.widget.presentMedium()
99-
break
100-
case 2:
101-
await this.widget.presentLarge()
77+
await showPreviewOptions(this.render.bind(this))
10278
break
10379
}
10480
}

0 commit comments

Comments
 (0)