Skip to content

Instantly share code, notes, and snippets.

@dongfg
Last active September 22, 2025 00:37
Show Gist options
  • Save dongfg/fc230b33241583d488b929331d101c3a to your computer and use it in GitHub Desktop.
Save dongfg/fc230b33241583d488b929331d101c3a to your computer and use it in GitHub Desktop.
scriptable 每日任务组件
const widget = new ListWidget();
const STORAGE_KEY_PREFIX = "douyinCheckinStatus";
function storageKey() {
const date = new Date().toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
return STORAGE_KEY_PREFIX + date;
}
function loadStatus() {
if (Keychain.contains(storageKey())) {
const value = Keychain.get(storageKey());
return value === "true";
} else {
Keychain.set(storageKey(), "false");
return false;
}
}
function saveStatus(completed) {
Keychain.set(storageKey(), completed.toString());
}
function signDays() {
const startDateStr = args.widgetParameter;
const targetDate = new Date(startDateStr).getTime();
const currentDate = new Date().setHours(0, 0, 0, 0);
const dayDiff = Math.abs(Math.floor((targetDate - currentDate) / (1000 * 60 * 60 * 24)));
console.log(dayDiff);
return dayDiff + "";
}
function buildWidget() {
const status = loadStatus();
widget.backgroundColor = new Color("#e3f2fd");
widget.setPadding(16, 10, 16, 10);
const textColor = status ? new Color("#2e7d32") : new Color("#d32f2f")
const title = widget.addText("抖音 365 签到");
title.font = Font.boldSystemFont(16);
title.textColor = textColor;
title.centerAlignText();
widget.addSpacer();
const dayCount = widget.addText(signDays());
dayCount.font = Font.boldSystemFont(36);
dayCount.textColor = textColor;
dayCount.centerAlignText();
widget.addSpacer();
const statusText = widget.addText(status ? "任务已完成" : "任务未完成");
statusText.font = Font.systemFont(16);
statusText.textColor = textColor;
statusText.centerAlignText();
}
if (config.runsInWidget) {
buildWidget();
Script.setWidget(widget);
Script.complete();
} else {
const fm = FileManager.local();
const lockFilePath = fm.joinPath(fm.temporaryDirectory(), "widget_lock.txt");
const lockTimeout = 2000; // 锁定时长:2秒 (2000毫秒)
// 检查锁文件是否存在且是否在锁定时长内
if (fm.fileExists(lockFilePath)) {
const modificationDate = fm.modificationDate(lockFilePath);
const timeSinceModified = new Date().getTime() - modificationDate.getTime();
if (timeSinceModified < lockTimeout) {
Script.complete();
return; // 必须 return 来停止后续代码
}
}
fm.writeString(lockFilePath, new Date().toISOString());
const alert = new Alert();
alert.title = "更新状态";
alert.message = "请选择当前签到状态";
alert.addAction("已完成");
alert.addAction("未完成");
alert.addCancelAction("取消");
alert.presentAlert().then(async (result) => {
if (result !== -1) {
saveStatus(result === 0);
const confirmationAlert = new Alert();
confirmationAlert.title = "更新成功";
confirmationAlert.message = "状态已保存。主屏幕小组件将在片刻后自动刷新。";
confirmationAlert.addAction("好的");
await confirmationAlert.present();
}
Script.complete();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment