作者:@Michael Lee
", 32 | "Michael Lee 大佬博客里一篇文章详细的描述了关于这个小组件开发和使用,有一定英语水平的大佬可以自行摸索,了解了解代码
", 33 | "博客:iOS Scriptable YouTube widget
", 34 | "谷歌的 API KEY 需要自行申请,地址:YouTube DataAPI
" 35 | ] 36 | }, 37 | { 38 | "version": "1.0.0", 39 | "author": "@Unknown", 40 | "description": "根据脚本注释自行使用", 41 | "scriptURL": "https://raw.githubusercontent.com/zc-nju-med/own_JS/master/NBA.js", 42 | "thumb": "https://img.icons8.com/nolan/344/basketball.png", 43 | "name": "NBA", 44 | "title": "NBA", 45 | "html": ["
喜欢篮球的,可以看看
"] 46 | }, 47 | { 48 | "version": "1.0.0", 49 | "author": "@三行", 50 | "description": "根据脚本注释自行使用", 51 | "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/webo.js", 52 | "thumb": "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2225458401,2104443747&fm=26&gp=0.jpg", 53 | "name": "Webo", 54 | "title": "微博热搜", 55 | "html": [ 56 | "修改自三行大佬的脚本@三行
" 57 | ] 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /images/count.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/count.png -------------------------------------------------------------------------------- /images/ftms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/ftms.png -------------------------------------------------------------------------------- /images/gas-night.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/gas-night.png -------------------------------------------------------------------------------- /images/jdk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/jdk.jpg -------------------------------------------------------------------------------- /images/large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/large.png -------------------------------------------------------------------------------- /images/medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/medium.png -------------------------------------------------------------------------------- /images/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/more.png -------------------------------------------------------------------------------- /images/small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dompling/Scriptable/c00be22b941a22cfdade52cf7851df69214f7595/images/small.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scriptable-types", 3 | "version": "1.0.0", 4 | "author": "2Ya", 5 | "description": "", 6 | "main": "index.js", 7 | "keywords": [ 8 | "scriptable", 9 | "ios", 10 | "widget" 11 | ], 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@types/scriptable-ios": "^1.6.1", 15 | "prettier": "^3.3.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /widget.Install.js: -------------------------------------------------------------------------------- 1 | // Variables used by Scriptable. 2 | // These must be at the very top of the file. Do not edit. 3 | // icon-color: brown; icon-glyph: download; 4 | 5 | // version:'1.0.0'; 6 | 7 | const Files = FileManager.iCloud(); 8 | const RootPath = Files.documentsDirectory(); 9 | 10 | const saveFileName = (fileName) => { 11 | const hasSuffix = fileName.lastIndexOf(".") + 1; 12 | return !hasSuffix ? `${fileName}.js` : fileName; 13 | }; 14 | 15 | const write = (fileName, content) => { 16 | let file = saveFileName(fileName); 17 | const filePath = Files.joinPath(RootPath, file); 18 | Files.writeString(filePath, content); 19 | return true; 20 | }; 21 | 22 | const saveFile = async ({ moduleName, url }) => { 23 | const req = new Request(encodeURI(url)); 24 | const content = await req.loadString(); 25 | write(`${moduleName}`, content); 26 | return true; 27 | }; 28 | 29 | const notify = async (title, body, url, opts = {}) => { 30 | let n = new Notification(); 31 | n = Object.assign(n, opts); 32 | n.title = title; 33 | n.body = body; 34 | if (url) n.openURL = url; 35 | return await n.schedule(); 36 | }; 37 | 38 | const renderTableList = async (data) => { 39 | try { 40 | const table = new UITable(); 41 | // 如果是节点,则先远程获取 42 | const req = new Request(data.subscription); 43 | const subscription = await req.loadJSON(); 44 | const apps = subscription.apps; 45 | apps.forEach((item) => { 46 | const r = new UITableRow(); 47 | r.height = 75; 48 | const imgCell = UITableCell.imageAtURL(item.thumb); 49 | imgCell.centerAligned(); 50 | r.addCell(imgCell); 51 | 52 | const nameCell = UITableCell.text(item.title); 53 | nameCell.centerAligned(); 54 | r.addCell(nameCell); 55 | 56 | const downloadCell = UITableCell.button("下载"); 57 | downloadCell.centerAligned(); 58 | downloadCell.dismissOnTap = true; 59 | downloadCell.onTap = async () => { 60 | if (item.depend) { 61 | try { 62 | for (let i = 0; i < item.depend.length; i++) { 63 | const relyItem = item.depend[i]; 64 | const _isWrite = await saveFile({ 65 | moduleName: relyItem.name, 66 | url: relyItem.scriptURL, 67 | }); 68 | if (_isWrite) { 69 | notify("下载提示", `依赖插件:${relyItem.name}下载/更新成功`); 70 | } 71 | } 72 | } catch (e) { 73 | console.log(e); 74 | } 75 | } 76 | const isWrite = await saveFile({ 77 | moduleName: item.name, 78 | url: item.scriptURL, 79 | }); 80 | if (isWrite) { 81 | notify("下载提示", `插件:${item.title}下载/更新成功`); 82 | } 83 | }; 84 | r.addCell(downloadCell); 85 | table.addRow(r); 86 | }); 87 | table.present(false); 88 | } catch (e) { 89 | console.log(e); 90 | notify("错误提示", "订阅获取失败"); 91 | } 92 | }; 93 | const Run = async () => { 94 | try { 95 | const mainAlert = new Alert(); 96 | mainAlert.title = "组件下载"; 97 | mainAlert.message = "可以自行添加订阅地址"; 98 | const cacheKey = "subscriptionList"; 99 | const render = async () => { 100 | let subscriptionList = []; 101 | if (Keychain.contains(cacheKey)) { 102 | subscriptionList = JSON.parse(Keychain.get(cacheKey)); 103 | } 104 | const _actions = []; 105 | console.log(subscriptionList); 106 | subscriptionList.forEach((item) => { 107 | const { author } = item; 108 | mainAlert.addAction("作者:" + author); 109 | _actions.push(async () => { 110 | await renderTableList(item); 111 | }); 112 | }); 113 | 114 | _actions.push(async () => { 115 | const a = new Alert(); 116 | a.title = "订阅地址"; 117 | a.addTextField( 118 | "URL", 119 | "https://raw.githubusercontent.com/dompling/Scriptable/master/install.json" 120 | ); 121 | a.addAction("确定"); 122 | a.addCancelAction("取消"); 123 | const id = await a.presentAlert(); 124 | if (id === -1) return; 125 | try { 126 | const url = a.textFieldValue(0); 127 | const response = await new Request(url).loadJSON(); 128 | delete response.apps; 129 | const data = []; 130 | let isPush = true; 131 | for (let i in subscriptionList) { 132 | const item = subscriptionList[i]; 133 | if (response.author === item.author) { 134 | isPush = false; 135 | data.push({ ...response, subscription: url }); 136 | } else { 137 | data.push(item); 138 | } 139 | } 140 | if (isPush) data.push({ author: response.author, subscription: url }); 141 | Keychain.set(cacheKey, JSON.stringify(data)); 142 | notify("更新成功", "请重新运行本脚本"); 143 | } catch (e) { 144 | console.log(e); 145 | notify("错误提示", "订阅地址错误,不是一个 JSON 格式"); 146 | } 147 | }); 148 | 149 | mainAlert.addAction("添加订阅"); 150 | mainAlert.addCancelAction("取消操作"); 151 | const _actionsIndex = await mainAlert.presentSheet(); 152 | if (_actions[_actionsIndex]) { 153 | const func = _actions[_actionsIndex]; 154 | await func(); 155 | } 156 | }; 157 | await render(); 158 | } catch (e) { 159 | console.log("缓存读取错误" + e); 160 | } 161 | }; 162 | (async () => { 163 | try { 164 | console.log("🤖自更新开始"); 165 | const modules = { 166 | moduleName: "widget.Install", 167 | url: 168 | "https://raw.githubusercontent.com/dompling/Scriptable/master/widget.Install.js", 169 | }; 170 | const result = await saveFile(modules); 171 | if (result) console.log("🤖自更新成功"); 172 | } catch (e) { 173 | console.log(e); 174 | } 175 | })(); 176 | await Run(); 177 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/scriptable-ios@^1.6.1": 6 | version "1.6.1" 7 | resolved "https://registry.npm.taobao.org/@types/scriptable-ios/download/@types/scriptable-ios-1.6.1.tgz#44766b47a0c0c9f92a3c1bf46214288cf3d926f4" 8 | integrity sha1-RHZrR6DAyfkqPBv0YhQojPPZJvQ= 9 | 10 | prettier@^3.3.3: 11 | version "3.3.3" 12 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" 13 | integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== 14 | --------------------------------------------------------------------------------