diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..c8b9c24 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5" +} \ No newline at end of file diff --git a/Scripts/ChinaTelecom.js b/Scripts/ChinaTelecom.js index 10a99ed..03fa63f 100644 --- a/Scripts/ChinaTelecom.js +++ b/Scripts/ChinaTelecom.js @@ -3,30 +3,30 @@ // icon-color: pink; icon-glyph: paper-plane; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === 'undefined') require = importModule; -const {DmYY, Runing} = require('./DmYY'); +if (typeof require === "undefined") require = importModule; +const { DmYY, Runing } = require("./DmYY"); // @组件代码开始 class Widget extends DmYY { constructor(arg) { super(arg); - this.name = '中国电信'; - this.en = 'ChinaTelecom'; + this.name = "中国电信"; + this.en = "ChinaTelecom"; this.Run(); } - cookie = ''; - authToken = ''; - fgCircleColor = Color.dynamic(new Color('#dddef3'), new Color('#fff')); + cookie = ""; + authToken = ""; + fgCircleColor = Color.dynamic(new Color("#dddef3"), new Color("#fff")); percentColor = this.widgetColor; - textColor1 = Color.dynamic(new Color('#333'), new Color('#fff')); + textColor1 = Color.dynamic(new Color("#333"), new Color("#fff")); textColor2 = this.widgetColor; - circleColor1 = new Color('#ffbb73'); - circleColor2 = new Color('#ff0029'); - circleColor3 = new Color('#00b800'); - circleColor4 = new Color('#8376f9'); - iconColor = new Color('#827af1'); + circleColor1 = new Color("#ffbb73"); + circleColor2 = new Color("#ff0029"); + circleColor3 = new Color("#00b800"); + circleColor4 = new Color("#8376f9"); + iconColor = new Color("#827af1"); format = (str) => { return parseInt(str) >= 10 ? str : `0${str}`; @@ -43,37 +43,37 @@ class Widget extends DmYY { // percent 的计算方式,剩余/总量 * 100 = 百分比| 百分比 * 3.6 ,为显示进度。 phoneBill = { percent: 0, - label: '话费剩余', + label: "话费剩余", count: 0, - unit: '元', - icon: 'yensign.circle', + unit: "元", + icon: "yensign.circle", circleColor: this.circleColor1, }; flow = { percent: 0, - label: '流量剩余', + label: "流量剩余", count: 0, - unit: 'M', - icon: 'waveform.path.badge.minus', + unit: "M", + icon: "waveform.path.badge.minus", circleColor: this.circleColor2, }; voice = { percent: 0, - label: '语音剩余', + label: "语音剩余", count: 0, - unit: '分钟', - icon: 'mic', + unit: "分钟", + icon: "mic", circleColor: this.circleColor3, }; updateTime = { percent: 0, - label: '电信更新', + label: "电信更新", count: `${this.arrUpdateTime[2]}:${this.arrUpdateTime[3]}`, - unit: '', - urlIcon: 'https://raw.githubusercontent.com/Orz-3/mini/master/10000.png', + unit: "", + urlIcon: "https://raw.githubusercontent.com/Orz-3/mini/master/10000.png", circleColor: this.circleColor4, }; @@ -89,12 +89,12 @@ class Widget extends DmYY { // "User-Agent": "TYUserCenter/2.8 (iPhone; iOS 14.0; Scale/3.00)", }, // body: "t=tysuit", - method: 'POST', + method: "POST", }; fetchUri = { - detail: 'https://e.189.cn/store/user/package_detail.do', - balance: 'https://e.189.cn/store/user/balance_new.do', + detail: "https://e.189.cn/store/user/package_detail.do", + balance: "https://e.189.cn/store/user/balance_new.do", }; init = async () => { @@ -112,9 +112,9 @@ class Widget extends DmYY { formatFlow(number) { const n = number / 1024; if (n < 1024) { - return {count: n.toFixed(2), unit: 'M'}; + return { count: n.toFixed(2), unit: "M" }; } - return {count: (n / 1024).toFixed(2), unit: 'G'}; + return { count: (n / 1024).toFixed(2), unit: "G" }; } getData = async () => { @@ -131,7 +131,7 @@ class Widget extends DmYY { if (detail.result === 0) { // 套餐分钟数 this.voice.percent = Math.floor( - (parseInt(detail.voiceBalance) / parseInt(detail.voiceAmount)) * 100, + (parseInt(detail.voiceBalance) / parseInt(detail.voiceAmount)) * 100 ); this.voice.count = detail.voiceBalance; console.log(detail.items); @@ -139,10 +139,10 @@ class Widget extends DmYY { detail.items.forEach((data) => { if (data.offerType !== 19) { data.items.forEach((item) => { - if (item.unitTypeId === '3') { - if (item.usageAmount !== '0' && item.balanceAmount !== '0') { + if (item.unitTypeId === "3") { + if (item.usageAmount !== "0" && item.balanceAmount !== "0") { this.flow.percent = Math.floor( - (item.balanceAmount / (item.ratableAmount || 1)) * 100, + (item.balanceAmount / (item.ratableAmount || 1)) * 100 ); const flow = this.formatFlow(item.balanceAmount); this.flow.count = flow.count; @@ -155,19 +155,19 @@ class Widget extends DmYY { }); } else { this.flow.percent = Math.floor( - (detail.balance / (detail.total || 1)) * 100, + (detail.balance / (detail.total || 1)) * 100 ); const flow = this.formatFlow(detail.balance); this.flow.count = flow.count; this.flow.unit = flow.unit; this.flow.max = detail.total; } - } if (balance.result === 0) { // 余额 this.phoneBill.count = parseFloat( - parseInt(balance.totalBalanceAvailable) / 100).toFixed(2) + parseInt(balance.totalBalanceAvailable) / 100 + ).toFixed(2); } this.phoneBill.percent = Math.floor((this.phoneBill.count / 100) * 100); }; @@ -194,13 +194,13 @@ class Widget extends DmYY { canvas.setFillColor(color); for (let t = 0; t < degree; t++) { const rect_x = - ctr.x + - (this.canvRadius - radiusOffset) * this.sinDeg(t) - - this.canvWidth / 2; + ctr.x + + (this.canvRadius - radiusOffset) * this.sinDeg(t) - + this.canvWidth / 2; const rect_y = - ctr.y - - (this.canvRadius - radiusOffset) * this.cosDeg(t) - - this.canvWidth / 2; + ctr.y - + (this.canvRadius - radiusOffset) * this.cosDeg(t) - + this.canvWidth / 2; const rect_r = new Rect(rect_x, rect_y, this.canvWidth, this.canvWidth); canvas.fillEllipse(rect_r); } @@ -208,10 +208,10 @@ class Widget extends DmYY { drawText(txt, canvas, txtOffset, fontSize) { const txtRect = new Rect( - this.canvTextSize / 2 - 20, - txtOffset - this.canvTextSize / 2, - this.canvSize, - this.canvTextSize, + this.canvTextSize / 2 - 20, + txtOffset - this.canvTextSize / 2, + this.canvSize, + this.canvTextSize ); canvas.setTextColor(this.percentColor); canvas.setFont(Font.boldSystemFont(fontSize)); @@ -238,10 +238,10 @@ class Widget extends DmYY { const canvas = this.makeCanvas(); stackCircle.size = new Size(70, 70); this.makeCircle( - canvas, - this.dayRadiusOffset, - data.percent * 3.6, - data.circleColor, + canvas, + this.dayRadiusOffset, + data.percent * 3.6, + data.circleColor ); this.drawText(data.percent, canvas, 75, 18); @@ -251,8 +251,8 @@ class Widget extends DmYY { stackCircle.setPadding(20, 0, 0, 0); stackCircle.addSpacer(); const icon = data.urlIcon - ? {image: data.icon} - : SFSymbol.named(data.icon); + ? { image: data.icon } + : SFSymbol.named(data.icon); const imageIcon = stackCircle.addImage(icon.image); imageIcon.tintColor = this.iconColor; imageIcon.imageSize = new Size(15, 15); @@ -293,11 +293,11 @@ class Widget extends DmYY { const stackFooter = stackBody.addStack(); stackFooter.addSpacer(); const text = this.textFormat.defaultText; - text.color = new Color('#aaa'); + text.color = new Color("#aaa"); this.provideText( - `电信更新:${this.arrUpdateTime[2]}:${this.arrUpdateTime[3]}`, - stackFooter, - text, + `电信更新:${this.arrUpdateTime[2]}:${this.arrUpdateTime[3]}`, + stackFooter, + text ); stackFooter.addSpacer(); return w; @@ -312,8 +312,8 @@ class Widget extends DmYY { const stackBottom = stackBody.addStack(); this.setCircleText(stackBottom, this.voice); this.updateTime.icon = await this.$request.get( - this.updateTime.urlIcon, - 'IMG', + this.updateTime.urlIcon, + "IMG" ); this.setCircleText(stackBottom, this.updateTime); return w; @@ -325,18 +325,18 @@ class Widget extends DmYY { renderWebView = async () => { const webView = new WebView(); - const url = 'https://e.189.cn/index.do'; + const url = "https://e.189.cn/index.do"; await webView.loadURL(url); await webView.present(false); const request = new Request(this.fetchUri.detail); - request.method = 'POST'; + request.method = "POST"; const response = await request.loadJSON(); console.log(response); if (response.result === -10001) { - const index = await this.generateAlert('未获取到用户信息', [ - '取消', - '重试', + const index = await this.generateAlert("未获取到用户信息", [ + "取消", + "重试", ]); if (index === 0) return; await this.renderWebView(); @@ -344,7 +344,7 @@ class Widget extends DmYY { const cookies = request.response.cookies; let cookie = []; cookie = cookies.map((item) => `${item.name}=${item.value}`); - cookie = cookie.join('; '); + cookie = cookie.join("; "); this.settings.cookie = cookie; this.saveSettings(); } @@ -352,35 +352,45 @@ class Widget extends DmYY { Run() { if (config.runsInApp) { - const widgetInitConfig = {cookie: 'china_telecom_cookie'}; - this.registerAction('颜色配置', async () => { + const widgetInitConfig = { cookie: "china_telecom_cookie" }; + this.registerAction("颜色配置", async () => { await this.setAlertInput( - `${this.name}颜色配置`, - '进度条颜色|底圈颜色\n图标颜色|比值颜色|值颜色', - { - step1: '进度颜色 1', - step2: '进度颜色 2', - step3: '进度颜色 3', - step4: '进度颜色 4', - inner: '底圈颜色', - icon: '图标颜色', - percent: '比值颜色', - value: '值颜色', - }, + `${this.name}颜色配置`, + "进度条颜色|底圈颜色\n图标颜色|比值颜色|值颜色", + { + step1: "进度颜色 1", + step2: "进度颜色 2", + step3: "进度颜色 3", + step4: "进度颜色 4", + inner: "底圈颜色", + icon: "图标颜色", + percent: "比值颜色", + value: "值颜色", + } ); }); - this.registerAction('账号设置', async () => { - const index = await this.generateAlert('设置账号信息', [ - '取消', - '网站登录', + this.registerAction("账号设置", async () => { + const index = await this.generateAlert("设置账号信息", [ + "取消", + "手动输入", + "网站登录", ]); if (index === 0) return; - await this.renderWebView(); + + if (index === 1) + return this.setAlertInput( + `${this.name}账号设置`, + "手动输入电信 COOKIE", + { + cookie: "电信 cookie", + } + ); + return this.renderWebView(); }); - this.registerAction('代理缓存', async () => { + this.registerAction("代理缓存", async () => { await this.setCacheBoxJSData(widgetInitConfig); }); - this.registerAction('基础设置', this.setWidgetConfig); + this.registerAction("基础设置", this.setWidgetConfig); } const { step1, @@ -419,9 +429,9 @@ class Widget extends DmYY { const widget = new ListWidget(); widget.setPadding(0, 0, 0, 0); await this.getWidgetBackgroundImage(widget); - if (this.widgetFamily === 'medium') { + if (this.widgetFamily === "medium") { return await this.renderMedium(widget); - } else if (this.widgetFamily === 'large') { + } else if (this.widgetFamily === "large") { return await this.renderLarge(widget); } else { return await this.renderSmall(widget); diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index eb2acde..04bee30 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -7,10 +7,12 @@ * Github: https://github.com/dompling * UI 配置升级 感谢 @LSP 大佬提供代码 */ + class DmYY { constructor(arg, defaultSettings) { this.arg = arg; this.defaultSettings = defaultSettings || {}; + this.SETTING_KEY = this.md5(Script.name()); this._init(); this.isNight = Device.isUsingDarkAppearance(); } @@ -225,10 +227,146 @@ class DmYY { return draw.getImage(); } - // Pixel sizes and positions for widgets on all supported phones. - function phoneSizes() { + function phoneSizes(inputHeight) { return { - // 12 Pro Max + /* + + Supported devices + ================= + The following device measurements have been confirmed in iOS 18. + + */ + + // 16 Pro Max + 2868: { + text: { + small: 510, + medium: 1092, + large: 1146, + left: 114, + right: 696, + top: 276, + middle: 912, + bottom: 1548, + }, + notext: { + small: 530, + medium: 1138, + large: 1136, + left: 91, + right: 699, + top: 276, + middle: 882, + bottom: 1488, + }, + }, + + // 16 Plus, 15 Plus, 15 Pro Max, 14 Pro Max + 2796: { + text: { + small: 510, + medium: 1092, + large: 1146, + left: 98, + right: 681, + top: 252, + middle: 888, + bottom: 1524, + }, + notext: { + small: 530, + medium: 1139, + large: 1136, + left: 75, + right: 684, + top: 252, + middle: 858, + bottom: 1464, + }, + }, + + // 16 Pro + 2622: { + text: { + small: 486, + medium: 1032, + large: 1098, + left: 87, + right: 633, + top: 261, + middle: 872, + bottom: 1485, + }, + notext: { + small: 495, + medium: 1037, + large: 1035, + left: 84, + right: 626, + top: 270, + middle: 810, + bottom: 1350, + }, + }, + + // 16, 15, 15 Pro, 14 Pro + 2556: { + text: { + small: 474, + medium: 1017, + large: 1062, + left: 81, + right: 624, + top: 240, + middle: 828, + bottom: 1416, + }, + notext: { + small: 495, + medium: 1047, + large: 1047, + left: 66, + right: 618, + top: 243, + middle: 795, + bottom: 1347, + }, + }, + + // SE3, SE2 + 1334: { + text: { + small: 296, + medium: 642, + large: 648, + left: 54, + right: 400, + top: 60, + middle: 412, + bottom: 764, + }, + notext: { + small: 309, + medium: 667, + large: 667, + left: 41, + right: 399, + top: 67, + middle: 425, + bottom: 783, + }, + }, + + /* + + In-limbo devices + ================= + The following device measurements were confirmed in older versions of iOS. + Please comment if you can confirm these for iOS 18. + + */ + + // 14 Plus, 13 Pro Max, 12 Pro Max 2778: { small: 510, medium: 1092, @@ -240,18 +378,6 @@ class DmYY { bottom: 1518, }, - // 12 and 12 Pro - 2532: { - small: 474, - medium: 1014, - large: 1062, - left: 78, - right: 618, - top: 231, - middle: 819, - bottom: 1407, - }, - // 11 Pro Max, XS Max 2688: { small: 507, @@ -264,19 +390,19 @@ class DmYY { bottom: 1488, }, - // 11, XR - 1792: { - small: 338, - medium: 720, - large: 758, - left: 54, - right: 436, - top: 160, - middle: 580, - bottom: 1000, + // 14, 13, 13 Pro, 12, 12 Pro + 2532: { + small: 474, + medium: 1014, + large: 1062, + left: 78, + right: 618, + top: 231, + middle: 819, + bottom: 1407, }, - // 11 Pro, XS, X, 12 mini + // 13 mini, 12 mini / 11 Pro, XS, X 2436: { x: { small: 465, @@ -288,7 +414,6 @@ class DmYY { middle: 783, bottom: 1353, }, - mini: { small: 465, medium: 987, @@ -301,40 +426,16 @@ class DmYY { }, }, - // Plus phones - 2208: { - small: 471, - medium: 1044, - large: 1071, - left: 99, - right: 672, - top: 114, - middle: 696, - bottom: 1278, - }, - - // SE2 and 6/6S/7/8 - 1334: { - small: 296, - medium: 642, - large: 648, - left: 54, - right: 400, - top: 60, - middle: 412, - bottom: 764, - }, - - // SE1 - 1136: { - small: 282, - medium: 584, - large: 622, - left: 30, - right: 332, - top: 59, - middle: 399, - bottom: 399, + // 11, XR + 1792: { + small: 338, + medium: 720, + large: 758, + left: 55, + right: 437, + top: 159, + middle: 579, + bottom: 999, }, // 11 and XR in Display Zoom mode @@ -349,7 +450,27 @@ class DmYY { bottom: 902, }, - // Plus in Display Zoom mode + /* + + Older devices + ================= + The following devices cannot be updated to iOS 18 or later. + + */ + + // Home button Plus phones + 2208: { + small: 471, + medium: 1044, + large: 1071, + left: 99, + right: 672, + top: 114, + middle: 696, + bottom: 1278, + }, + + // Home button Plus in Display Zoom mode 2001: { small: 444, medium: 963, @@ -360,7 +481,19 @@ class DmYY { middle: 618, bottom: 1146, }, - }; + + // SE1 + 1136: { + small: 282, + medium: 584, + large: 622, + left: 30, + right: 332, + top: 59, + middle: 399, + bottom: 399, + }, + }[inputHeight]; } let message = @@ -372,13 +505,12 @@ class DmYY { // Get screenshot and determine phone size. let img = await Photos.fromLibrary(); let height = img.size.height; - let phone = phoneSizes()[height]; + let phone = phoneSizes(height); if (!phone) { message = '好像您选择的照片不是正确的截图,请先前往桌面'; await this.generateAlert(message, ['我已知晓']); return; } - // Extra setup needed for 2436-sized phones. if (height === 2436) { const files = this.FILE_MGR_LOCAL; @@ -400,6 +532,15 @@ class DmYY { } } + // If supported, check whether home screen has text labels or not. + if (phone.text) { + message = '主屏幕是否有文本标签?'; + const textOptions = ['有', '无']; + const _textOptions = ['text', 'notext']; + const textResponse = await this.generateAlert(message, textOptions); + phone = phone[_textOptions[textResponse]]; + } + // Prompt for widget size and position. message = '截图中要设置透明背景组件的尺寸类型是?'; let sizes = ['小尺寸', '中尺寸', '大尺寸']; @@ -685,12 +826,18 @@ class DmYY { if (index === 4) return; switch (index) { case 3: - for (const id of ids) { - await this.htmlChangeImage(false, `${_.val}${ids[id]}`, { - previewWebView, - id: ids[id], - }); - } + await this.htmlChangeImage(false, `${_.val}${ids[0]}`, { + previewWebView, + id: ids[0], + }); + await this.htmlChangeImage(false, `${_.val}${ids[1]}`, { + previewWebView, + id: ids[1], + }); + await this.htmlChangeImage(false, `${_.val}${ids[2]}`, { + previewWebView, + id: ids[2], + }); return; default: await this.htmlChangeImage(false, `${_.val}${ids[index]}`, { @@ -703,6 +850,23 @@ class DmYY { }, ], }, + { + title: '重置组件', + menu: [ + { + icon: { name: 'trash', color: '#D85888' }, + title: '重置', + desc: '重置当前组件配置', + name: 'reset', + val: 'reset', + onClick: () => { + this.settings = {}; + this.saveSettings(); + this.reopenScript(); + }, + }, + ], + }, ]).catch((e) => { console.log(e); }); @@ -1028,16 +1192,19 @@ class DmYY { border-radius:50%; border: 1px solid #F6D377; } - .form-item { + .form-item, .form-item-switch { display: flex; align-items: center; justify-content: space-between; font-size: ${settingItemFontSize}px; font-weight: 400; min-height: 2.2em; - padding: 0.5em 18px; + padding: 0.5em 10px; position: relative; } + label > * { + pointer-events: none; + } .form-label { display: flex; align-items: center; @@ -1066,6 +1233,7 @@ class DmYY { text-overflow: ellipsis; display:flex; align-items: center; + white-space: nowrap; } .form-item-right-desc img{ @@ -1074,14 +1242,19 @@ class DmYY { border-radius:3px; } - .form-item + .form-item::before { + .form-item + .form-item::before, + .form-item + .form-item-switch::before, + .form-item-switch + .form-item::before, + .form-item-switch + .form-item-switch::before + { content: ""; position: absolute; top: 0; - left: 20px; + left: 0; right: 0; border-top: 0.5px solid var(--divider-color); } + .form-item input[type="checkbox"] { width: 2em; height: 2em; @@ -1276,8 +1449,8 @@ class DmYY { const idName = menuItem.name || menuItem.val; let defaultHtml = ``; - if (idName !== undefined && !menuItem.defaultValue) - menuItem.defaultValue = this.settings[idName] || ''; + menuItem.defaultValue = + this.settings[idName] || menuItem.defaultValue || ''; if (menuItem.type === 'input') { defaultHtml = menuItem.defaultValue || ''; @@ -1294,13 +1467,13 @@ class DmYY { menuItem.options.forEach((option) => { let selected = `selected="selected"`; selectOptions += ``; }); defaultHtml = ``; } else if (menuItem.type === 'switch') { const checked = - menuItem.defaultValue === 'true' ? `checked="checked"` : ''; + menuItem.defaultValue == 'true' ? `checked="checked"` : ''; defaultHtml += ``; } else if (menuItem.type) { defaultHtml = ``; } + let addLable = ''; + if (menuItem.type === 'switch' || menuItem.type === 'checkbox') { + addLable = `