// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: red; icon-glyph: user-astronaut;
/**
* Author:LSP
* Date:2022-12-22
*/
// -------------------------------------------------------
// 是否是开发环境,配合手机端调试使用,正式发布设置为false
const isDev = false;
console.log(`开发环境 👉👉👉👉👉 ${isDev ? 'DEV' : 'RELEASE'}`);
console.log(`----------------------------------------`);
const remoteRoot = 'https://gitcode.net/enoyee/scriptable/-/raw/master/';
// 依赖包目录
const fm = FileManager.local();
const rootDir = fm.documentsDirectory();
const cacheDir = fm.joinPath(rootDir, 'LSP');
const dependencyFileName = isDev ? "_LSP.js" : `${cacheDir}/_LSP.js`;
// 下载依赖包
await downloadLSPDependency();
// -------------------------------------------------------
if (typeof require === 'undefined') require = importModule
// 引入相关方法
const { BaseWidget } = require(dependencyFileName);
// @定义小组件
class Widget extends BaseWidget {
defaultPreference = {
version: 20221215,
domain: 'https://tophub.today',
hotban: [{ title: '微博 · 热搜榜', link: 'https://tophub.today/n/KqndgxeLl9' }],
weiboOpenOptions: [
{ name: '国内版' },
{ name: '国际版' },
{ name: '浏览器' },
],
// --------------------------
titleFontSize: 16,
titleFontColor: '#FFFFFF',
contentFontSize: 13,
contentFontColor: '#FFFFFF',
contentLineSpacing: 6,
// --------------------------
blur: true,
bgUrl: 'https://gitcode.net/enoyee/scriptable/-/raw/master/img/bg_1.jpg',
// --------------------------
normalItemCount: 5,
largeItemCount: 13
};
getCookie() {
const { cookie } = this.readWidgetSetting();
this.logDivider();
console.log(`TopHub的cookie-->${cookie}`);
this.logDivider();
return cookie;
}
getHotban = (defaultValue) => JSON.parse(this.useFileManager().readStringCache('hotban') ?? (defaultValue ? defaultValue : JSON.stringify(this.defaultPreference.hotban)));
getWeiboOpenType = () => this.getSettingValueByKey('weiboOpenType', this.defaultPreference.weiboOpenOptions[2].name);
getTitleFontSize = () => Number(this.getSettingValueByKey('titleFontSize', `${this.defaultPreference.titleFontSize}`));
getTitleFontColor = () => this.getSettingValueByKey('titleFontColor', `${this.defaultPreference.titleFontColor}`);
getContentFontSize = () => Number(this.getSettingValueByKey('contentFontSize', `${this.defaultPreference.contentFontSize}`));
getContentFontColor = () => this.getSettingValueByKey('contentFontColor', `${this.defaultPreference.contentFontColor}`);
getContentLineSpacing = () => Number(this.getSettingValueByKey('contentLineSpacing', `${this.defaultPreference.contentLineSpacing}`));
getNormalItemCount = () => Number(this.getSettingValueByKey('normalItemCount', `${this.defaultPreference.normalItemCount}`));
getLargeItemCount = () => Number(this.getSettingValueByKey('largeItemCount', `${this.defaultPreference.largeItemCount}`));
getCKDesc = () => {
let hasCK = this.getCookie()?.length > 0;
return hasCK ? '已登录' : '未登录'
};
constructor(scriptName) {
super(scriptName);
this.changeBgMode2OnLineBg(
this.defaultPreference.bgUrl,
{ blur: this.defaultPreference.blur, blurRadius: 10 }
);
}
async renderSearchResultView(response, onItemClick) {
const { coverArr = [], linkArr = [], titleArr = [], tipArr = [] } = response;
// =========================================================
const style = `
:root {
--color-primary: #007aff;
--divider-color: rgba(60,60,67,0.16);
--card-background: #fff;
--card-radius: 8px;
--list-header-color: rgba(60,60,67,0.6);
}
body {
margin: 10px 0;
-webkit-font-smoothing: antialiased;
font-family: "SF Pro Display","SF Pro Icons","Helvetica Neue","Helvetica","Arial",sans-serif;
accent-color: var(--color-primary);
background: #f6f6f6;
}
.list {
margin: 15px;
}
.list__body {
margin-top: 10px;
background: var(--card-background);
border-radius: var(--card-radius);
overflow: hidden;
}
.form-label {
display: flex;
align-items: center;
}
.form-item {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 4em;
padding: 2px 16px;
position: relative;
}
.form-item + .form-item::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
border-top: 0.8px solid var(--divider-color);
}
.form-item-cover {
width: 44px;
height: 44px;
border-radius: 6px;
border: 0;
}
.form-item-tite {
margin: 0px 12px;
font-size: 14px;
font-weight: 700;
}
.form-item-desc {
color: #999;
margin: 0px 12px;
font-size: 13px;
}
@media (prefers-color-scheme: dark) {
:root {
--divider-color: rgba(84,84,88,0.65);
--card-background: #1c1c1e;
--list-header-color: rgba(235,235,245,0.6);
}
body {
background: #000;
color: #fff;
}
}
`;
// =========================================================
const js = `
(() => {
const coverArr = JSON.parse('${JSON.stringify(coverArr)}')
const titleArr = JSON.parse('${JSON.stringify(titleArr)}')
const tipArr = JSON.parse('${JSON.stringify(tipArr)}')
const linkArr = JSON.parse('${JSON.stringify(linkArr)}')
window.invoke = (title, link) => {
window.dispatchEvent(
new CustomEvent(
'JBridge',
{ detail: { title, link } }
)
)
}
const fragment = document.createDocumentFragment()
coverArr.forEach((cover, index) => {
const title = titleArr[index];
const tips = tipArr[index];
const link = linkArr[index];
const label = document.createElement("label");
label.className = "form-item";
const divLabel = document.createElement("div");
divLabel.className = 'form-label';
label.appendChild(divLabel);
const img = document.createElement("img");
img.src = cover;
img.className = 'form-item-cover';
divLabel.appendChild(img);
const divContent = document.createElement("div");
divLabel.appendChild(divContent);
const divTitle = document.createElement("div");
divTitle.className = 'form-item-tite';
divTitle.innerText = title;
divContent.appendChild(divTitle);
const divDesc = document.createElement("div");
divDesc.className = 'form-item-desc';
divDesc.innerText = tips;
divContent.appendChild(divDesc);
const icon = document.createElement('i')
icon.className = 'iconfont icon-xuqiudingyue'
label.appendChild(icon)
label.addEventListener('click', (e) => invoke(title, link))
fragment.appendChild(label);
});
document.getElementById('form').appendChild(fragment)
})()`;
// =========================================================
const html = `
`;
// 预览web
const previewWebView = new WebView();
await previewWebView.loadHTML(html, 'https://tophub.today');
const injectListener = async () => {
const event = await previewWebView.evaluateJavaScript(
`(() => {
try {
const controller = new AbortController()
const listener = (e) => {
completion(e.detail)
controller.abort()
}
window.addEventListener(
'JBridge',
listener,
{ signal: controller.signal }
)
} catch (e) {
alert("搜索界面出错:" + e);
throw new Error("搜索界面处理出错: " + e);
return;
}
})()`, true).catch((err) => {
console.error(err);
this.ERRS.push(err);
if (!config.runsInApp) {
this.notify('APP主界面', `🚫 ${err}`);
} else {
throw err
}
});
////////////////////////////////////
onItemClick?.(event);
injectListener();
}
injectListener().catch((e) => {
console.error(e);
});
await previewWebView.present();
}
async getAppViewOptions() {
return {
widgetProvider: {
small: true, // 是否提供小号组件
medium: true, // 是否提供中号组件
large: true, // 是否提供大号组件
},
// 预览界面的组件设置item
settingItems: [
{
name: 'hotbanCK',
label: '登录TopHub',
type: 'cell',
icon: 'https://file.ipadown.com/tophub/assets/images/logo.png',
needLoading: true,
desc: this.getCKDesc()
},
{
name: 'hotban',
label: '热搜榜设置',
type: 'cell',
icon: { name: 'flame', color: '#EB3323', },
needLoading: true,
showDesc: false,
},
{
name: 'weiboOpenType',
label: '微博打开方式',
type: 'cell',
icon: 'https://gitcode.net/enoyee/scriptable/-/raw/master/img/ic_weibo.png',
needLoading: false,
default: this.getWeiboOpenType(),
},
{
name: 'otherSetting',
label: '其他设置',
type: 'cell',
icon: 'https://gitcode.net/4qiao/framework/raw/master/img/icon/setting.gif',
needLoading: true,
childItems: [
{
name: 'titleFontSize',
label: '标题文字大小',
type: 'cell',
icon: { name: 'pencil.and.outline', color: '#ff758f', },
needLoading: false,
alert: {
title: '标题文字大小',
options: [
{
key: 'titleFontSize',
hint: '请输入字号',
}
]
},
default: `${this.getTitleFontSize()}`,
},
{
name: 'titleFontColor',
label: '标题文字颜色',
type: 'color',
icon: { name: 'pencil.and.outline', color: '#c9184a', },
needLoading: false,
default: this.getTitleFontColor(),
},
{
name: 'contentFontSize',
label: '榜单文字大小',
type: 'cell',
icon: { name: 'scribble', color: '#9d4edd', },
needLoading: false,
alert: {
title: '榜单文字大小',
options: [
{
key: 'contentFontSize',
hint: '请输入字号',
}
]
},
default: `${this.getContentFontSize()}`,
},
{
name: 'contentFontColor',
label: '榜单文字颜色',
type: 'color',
icon: { name: 'scribble', color: '#7b2cbf', },
needLoading: false,
default: this.getContentFontColor(),
},
{
name: 'contentLineSpacing',
label: '榜单行间距',
type: 'cell',
icon: { name: 'doc.richtext', color: '#f6aa1c', },
needLoading: false,
alert: {
title: '榜单行间距',
options: [
{
key: 'contentLineSpacing',
hint: '请输入间距数字',
}
]
},
default: `${this.getContentLineSpacing()}`,
},
{
name: 'banCount',
label: '榜单条数',
type: 'cell',
icon: { name: 'doc.text.below.ecg', color: '#00a8e8' },
alert: {
title: '榜单显示条数',
message: "小组件每次展示的热榜条数",
options: [
{
key: 'normalItemCount',
hint: '请输入中/小号组件热榜条数',
},
{
key: 'largeItemCount',
hint: '请输入大号组件热榜条数',
}
]
},
needLoading: false,
},
]
},
],
// cell类型的item点击回调
onItemClick: async (item) => {
let widgetSetting = this.readWidgetSetting();
let insertDesc;
switch (item.name) {
case 'hotbanCK':
const url = "https://tophub.today/login";
const webview = new WebView();
await webview.loadURL(url);
await webview.present();
const cookie = await webview.evaluateJavaScript("document.cookie");
console.log(`登录成功,获取到的ck:${cookie}`);
widgetSetting.cookie = cookie;
insertDesc = cookie?.length > 0 ? '已登录' : '未登录';
break;
case 'hotban':
const hotSelectIndex = await this.presentSheet({
title: '热榜设置',
message: '⊱配置热榜显示榜单内容⊰',
options: [{ name: '查看已添加榜单' }, { name: '搜索添加榜单' }, { name: '重置榜单' }],
});
if (hotSelectIndex == 0) {
const hotbanArr = this.getHotban('[]');
const hotbanTitleArr = hotbanArr.map(hotban => hotban.title.replaceAll(" ", ""));
await this.generateAlert('已添加榜单', `${hotbanTitleArr.length > 0 ? hotbanTitleArr.join('、') : '暂无添加,默认微博热搜'}`, ['确定']);
} else if (hotSelectIndex == 1) {
await this.generateInputAlert({
title: '热榜搜索',
options: [{ hint: '请输入关键字', value: '' }]
}, async (inputArr) => {
const keyword = inputArr[0].value;
let response = undefined;
try {
//////
const webview = new WebView();
await webview.loadURL(`${this.defaultPreference.domain}/search?q=${encodeURIComponent(keyword)}`);
const html = await webview.getHTML();
await webview.loadHTML(html);
// 通过dom操作把HTML里面的热榜内容提取出来
const getData = `
function getData() {
// 图片封面
coverArr = []
// 链接
linkArr = []
// 标题
titleArr = []
// 描述
tipArr = []
nodeSize = 0
totalCount = 20
// 图片封面
let allItemNodeList = document.getElementsByClassName('weui-media-box__thumb radius');
for(let node of allItemNodeList) {
if(nodeSize < totalCount) {
coverArr.push(node.src)
} else {
break
}
nodeSize += 1
}
// 链接
nodeSize = 0
allItemNodeList = document.getElementsByClassName('weui-media-box weui-media-box_appmsg weui-cell');
for(let node of allItemNodeList) {
if(nodeSize < totalCount) {
linkArr.push(node.href)
} else {
break
}
nodeSize += 1
}
// 标题
nodeSize = 0
allItemNodeList = document.getElementsByClassName('weui-media-box__title');
for(let node of allItemNodeList) {
if(nodeSize < totalCount) {
titleArr.push(node.innerText)
} else {
break
}
nodeSize += 1
}
// 订阅人数
nodeSize = 0
allItemNodeList = document.getElementsByClassName('weui-media-box__desc');
for(let node of allItemNodeList) {
if(nodeSize < totalCount) {
tipArr.push(node.innerText)
} else {
break
}
nodeSize += 1
}
return { coverArr, linkArr, titleArr, tipArr };
}
getData()
`
// 热榜数据
response = await webview.evaluateJavaScript(getData, false);
const { linkArr = [] } = response;
if (linkArr.length === 0) {
await this.generateAlert('热榜搜索', '搜索结果为空', ['确定']);
} else {
await this.renderSearchResultView(response, async (event) => {
let { title, link } = event;
const hotbanArr = this.getHotban('[]');
const findItem = hotbanArr.find(hotban => hotban.title == title);
if (findItem == undefined) {
try {
link = `${this.defaultPreference.domain}${link}`;
hotbanArr.push({ title, link });
this.useFileManager().writeStringCache('hotban', JSON.stringify(hotbanArr));
await this.generateAlert(`热榜内容`, `已成功添加«${title}»\n返回上级点击组件预览即可查看效果`, ['确定']);
} catch (error) {
console.error(error);
}
}
});
}
//////
} catch (error) {
console.error(`🚫 热榜搜索出错==>${error}`);
await this.generateAlert('🚫 热榜搜索出错', `${error}`, ['确定']);
};
});
} else if (hotSelectIndex != -1) {
this.useFileManager().writeStringCache('hotban', JSON.stringify([]));
await this.generateAlert('热榜设置', '热榜已重置成功', ['确定']);
}
break;
case 'weiboOpenType':
const index = await this.presentSheet({
title: '微博打开方式',
message: '⊱配置点击微博跳转方式⊰',
options: this.defaultPreference.weiboOpenOptions,
});
insertDesc = this.defaultPreference.weiboOpenOptions[index].name;
widgetSetting.weiboOpenType = insertDesc;
break
}
// 写入更新配置
this.writeWidgetSetting(widgetSetting);
return {
desc: { value: insertDesc },
};
},
};
}
async render({ widgetSetting, family }) {
let widget;
switch (family) {
case 'small':
widget = await this.provideSmallWidget();
break;
case 'medium':
widget = await this.provideMediumWidget();
break;
case 'large':
widget = await this.provideLargeWidget();
break;
}
widget.setPadding(6, 16, 6, 12);
return widget;
}
/**
* 小型组件
* @returns
*/
async provideSmallWidget() {
return await this.provideWidget(this.getNormalItemCount(), true);
}
/**
* 中型组件
* @returns
*/
async provideMediumWidget() {
return await this.provideWidget(this.getNormalItemCount());
}
/**
* 大型组件
* @returns
*/
async provideLargeWidget() {
return await this.provideWidget(this.getLargeItemCount());
}
async provideWidget(itemCount, small = false) {
const defaultHotArr = this.defaultPreference.hotban;
const cacheHotStr = this.useFileManager().readStringCache('hotban');
let hotbanArr = cacheHotStr ? JSON.parse(cacheHotStr) : defaultHotArr;
hotbanArr = hotbanArr.length === 0 ? defaultHotArr : hotbanArr;
const index = this.carouselIndex(`HotbanRandom${this.defaultPreference.version}`, hotbanArr.length);
const response = await this.loadHotBanRES(hotbanArr[index].link);
// 数据
const { hotTitle = '', logoUrl = '', linkArr = [], titleArr = [] } = response;
//=================================
const widget = new ListWidget();
//=================================
let stack = widget.addStack();
stack.layoutVertically();
// 标题
let titleStack = stack.addStack();
titleStack.size = new Size(0, 44);
titleStack.centerAlignContent();
titleStack.layoutHorizontally();
let img = await this.getImageByUrl(logoUrl);
let imgSpan = titleStack.addImage(img);
imgSpan.imageSize = new Size(23, 23);
imgSpan.cornerRadius = 6;
titleStack.addSpacer(8);
let textSpan = titleStack.addText(hotTitle.replace('\n', ''));
textSpan.textColor = new Color(this.getTitleFontColor());
let titleSize = this.getTitleFontSize();
if (small) {
titleSize -= 2;
}
textSpan.font = Font.semiboldSystemFont(titleSize);
textSpan.lineLimit = 1;
//
titleStack.addSpacer();
if (!small) {
img = this.getSFSymbol('goforward');
imgSpan = titleStack.addImage(img);
imgSpan.imageSize = new Size(12, 12);
imgSpan.tintColor = new Color(this.getTitleFontColor());
titleStack.addSpacer(4);
textSpan = titleStack.addText(this.getDateStr(new Date(), 'HH:mm'));
textSpan.textColor = new Color(this.getTitleFontColor());
textSpan.font = Font.semiboldSystemFont(titleSize - 4);
titleStack.addSpacer(10);
}
// item
for (let index = 0; index < itemCount; index++) {
const name = titleArr[index];
const link = linkArr[index];
let nameStack = stack.addStack();
stack.addSpacer(this.getContentLineSpacing());
nameStack.layoutHorizontally();
textSpan = nameStack.addText(`${index + 1}. `);
let hotTop = index <= 2;
textSpan.textColor = new Color(`${hotTop ? '#ef233c' : this.getContentFontColor()}`);
let contentSize = this.getContentFontSize();
textSpan.font = hotTop ? Font.italicSystemFont(contentSize) : Font.systemFont(contentSize);
//
textSpan = nameStack.addText(`${name}`);
textSpan.textColor = new Color(this.getContentFontColor());
textSpan.font = Font.systemFont(contentSize);
textSpan.lineLimit = 1;
//
let linkElement = link;
if (!link?.startsWith('http')) {
linkElement = `https://tophub.today${link}`;
}
if (hotTitle.search("微博") != -1) {
const weiboOpenType = this.getWeiboOpenType();
if (weiboOpenType == '国内版') {
// 微博客户端
linkElement = 'sinaweibo://searchall?q=' + encodeURIComponent(`#${name}#`)
} else if (weiboOpenType == '国际版') {
// 微博国际版客户端
linkElement = 'weibointernational://search?q=' + encodeURIComponent(`#${name}#`)
}
}
nameStack.url = linkElement;
}
stack.addSpacer();
//=================================
return widget;
}
// --------------------------NET START--------------------------
async loadHTML(url) {
let req = new Request(url);
req.headers = {
"cookie": this.getCookie(),
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
};
let html = await req.loadString();
return html.replace(/(\r\n|\n|\r)/gm, "");
}
async loadHotBanRES(link) {
// 热榜数据
let response = undefined;
try {
const ufm = this.useFileManager();
const webview = new WebView();
const cacheFileName = this.md5(link);
const lastCacheTime = ufm.getCacheModifyDate(cacheFileName);
const timeInterval = Math.floor((this.getCurrentTimeStamp() - lastCacheTime) / 60);
// 读取本地缓存
const localCache = ufm.readStringCache(cacheFileName);
const canUseCache = localCache != null && localCache.length > 0;
// 过时且有本地缓存则直接返回本地缓存数据
const { refreshInterval = '0' } = this.readWidgetSetting();
const shouldLoadCache = timeInterval <= Number(refreshInterval) && canUseCache;
let html = ufm.readStringCache(cacheFileName);
if (!shouldLoadCache) {
console.log(`-->>在线加载网页数据:${link}`);
html = await this.loadHTML(link);
ufm.writeStringCache(cacheFileName, html);
} else {
console.log(`-->>加载缓存网页数据:${link}`);
}
await webview.loadHTML(html);
// 通过dom操作把HTML里面的热榜内容提取出来
const getData =
`
function getData() {
// logo链接
logoUrl = ''
// 榜单标题
hotTitle = '--'
branLogoArr = document.getElementsByClassName('brand logo')
if(JSON.stringify(branLogoArr) == '{}') {
return getPCData()
}
if(branLogoArr.length > 0) {
branLogo = branLogoArr[0]
logoUrl = branLogo.style['background-image'].slice(5).slice(0, -2)
//
mainTitle = branLogo.innerText
subTitle = document.getElementsByClassName('tab-nav-item active')[0]?.innerText ?? ''
hotTitle = mainTitle + (subTitle.length > 0 ? ' · ' : '') + subTitle
}
// 链接
linkArr = []
// 标题
titleArr = []
allItemNodeList = document.querySelectorAll('.rank-item-container')
// 链接&标题
nodeSize = 0
for(let node of allItemNodeList) {
if(nodeSize < 30) {
link = node.href;
linkArr.push(link);
title = node.getElementsByClassName('s-title')[0].innerText
titleArr.push(title);
} else {
break
}
nodeSize += 1
}
return { hotTitle, logoUrl, linkArr, titleArr };
}
function getPCData() {
// 获取榜单标题
hotTitle = document.querySelector('.Xc-ec-L').innerText
// 获取logo链接
logoImgHtml = document.querySelector('#tabbed-header-panel div').innerHTML;
// 提取src的正则表达式
logoPattern = /]*href=['"]([^'"]+)[^>]*/gi, function(match, link){
linkArr.push(link)
});
// 标题
titleArr.push(node.innerText)
}
return { hotTitle, logoUrl, linkArr, titleArr };
}
getData()
`
// 热榜数据
response = await webview.evaluateJavaScript(getData, false);
if (response.titleArr?.length > 0) {
this.useFileManager().writeStringCache('hot', JSON.stringify(response));
}
} catch (error) {
console.error(`🚫 请求热板数据出错了=>${error}`);
response = JSON.parse(this.useFileManager().readStringCache('hot'));
}
return response;
}
// --------------------------NET END--------------------------
}
await new Widget(Script.name()).run();
// =================================================================================
// =================================================================================
async function downloadLSPDependency() {
let fm = FileManager.local();
const dependencyURL = `${remoteRoot}_LSP.js`;
if (isDev) {
const iCloudPath = FileManager.iCloud().documentsDirectory();
const localIcloudDependencyExit = fm.isFileStoredIniCloud(`${iCloudPath}/_LSP.js`);
const localDependencyExit = fm.fileExists(`${rootDir}/_LSP.js`);
const fileExist = localIcloudDependencyExit || localDependencyExit;
console.log(`🚀 DEV开发依赖文件${fileExist ? '已存在 ✅' : '不存在 🚫'}`);
if (!fileExist) {
console.log(`🤖 DEV 开始下载依赖~`);
await downloadFile2Scriptable('_LSP', dependencyURL);
}
return
}
//////////////////////////////////////////////////////////
console.log(`----------------------------------------`);
const remoteDependencyExit = fm.fileExists(`${cacheDir}/_LSP.js`);
console.log(`🚀 RELEASE依赖文件${remoteDependencyExit ? '已存在 ✅' : '不存在 🚫'}`);
console.log(`----------------------------------------`);
// ------------------------------
if (!remoteDependencyExit) { // 下载依赖
// 创建根目录
if (!fm.fileExists(cacheDir)) {
fm.createDirectory(cacheDir, true);
}
// 下载
console.log('🤖 RELEASE开始下载依赖~');
console.log(`----------------------------------------`);
const req = new Request(dependencyURL);
const moduleJs = await req.load();
if (moduleJs) {
fm.write(fm.joinPath(cacheDir, '/_LSP.js'), moduleJs);
console.log('✅ LSP远程依赖环境下载成功!');
console.log(`----------------------------------------`);
} else {
console.error('🚫 获取依赖环境脚本失败,请重试!');
console.log(`----------------------------------------`);
}
}
}
/**
* 获取保存的文件名
* @param {*} fileName
* @returns
*/
function getSaveFileName(fileName) {
const hasSuffix = fileName.lastIndexOf(".") + 1;
return !hasSuffix ? `${fileName}.js` : fileName;
};
/**
* 保存文件到Scriptable软件目录,app可看到
* @param {*} fileName
* @param {*} content
* @returns
*/
function saveFile2Scriptable(fileName, content) {
try {
const fm = FileManager.iCloud();
let fileSimpleName = getSaveFileName(fileName);
const filePath = fm.joinPath(fm.documentsDirectory(), fileSimpleName);
fm.writeString(filePath, content);
return true;
} catch (error) {
return false;
}
};
/**
* 下载js文件到Scriptable软件目录
* @param {*} moduleName 名称
* @param {*} url 在线地址
* @returns
*/
async function downloadFile2Scriptable(moduleName, url) {
const req = new Request(url);
const content = await req.loadString();
return saveFile2Scriptable(`${moduleName}`, content);
};
// =================================================================================
// =================================================================================