Last active
November 9, 2023 13:17
-
-
Save Meatwo310/e4fb2f902d21072673323a69ebb7400a to your computer and use it in GitHub Desktop.
iOS用アプリScriptableで使用できる、Misskeyカレンダー風ウィジェットです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ====================== | |
// ====== コンフィグ ====== | |
// ====================== | |
/* | |
このセクションの値を編集すると、 | |
ウィジェットの見た目を微調整できます。 | |
Labelを空の文字列に設定すると、 | |
その項目を非表示にすることができます。 | |
*/ | |
// ウィジェット背景色 | |
const widgetBackgroundColor = new Color("#222222"); | |
// 進捗バー 外観 | |
const barWidth = 125; | |
const barHeight = 5; | |
const barPadding = 6; | |
const barCornerWidth = 3; | |
const barCornerHeight = 2; | |
// 進捗バー ラベル | |
const barLabelColor = new Color("#dfdfdf"); | |
const barLabelFontSize = 13; | |
const barLabelFont = Font.boldMonospacedSystemFont(barLabelFontSize); | |
// 進捗バー 背景 | |
const barBackgroundColor = new Color("#3f3f3f"); | |
// 進捗: 今日 | |
const todayBarLabel = "今日: $1%"; | |
const todayBarColor = new Color("#FA8072"); | |
// 進捗: 今月 | |
const thisMonthBarLabel = "今月: $1%"; | |
const thisMonthBarColor = new Color("#ADFF2F"); | |
// 進捗: 今年 | |
const thisYearBarLabel = "今年: $1%"; | |
const thisYearBarColor = new Color("#00BFFF"); | |
// ウィジェット更新時刻 外観 | |
const updatedInfoLabel = "更新: $1"; | |
const updatedInfoLabelColor = new Color("#dfdfdf"); | |
const updatedInfoLabelFontSize = 10; | |
const updatedInfoLabelFont = Font.mediumMonospacedSystemFont(updatedInfoLabelFontSize); | |
// ========================== | |
// ====== 各種変数の設定 ====== | |
// ========================== | |
const widget = new ListWidget(); | |
widget.backgroundColor = widgetBackgroundColor; | |
const now = new Date(); | |
// 年。取得は1990年からの年数を取得するgetYear()ではなく完全な年数を取得するgetFullYearを使用する | |
const year = now.getFullYear(); | |
// 月。getMonth()は0月始まり11月終わりなので1を加えておく | |
const month = now.getMonth() + 1; | |
// 日。 | |
const date = now.getDate(); | |
// 曜日。0-6の数値 | |
const day = now.getDay(); | |
const hours = now.getHours(); | |
const minutes = now.getMinutes(); | |
const monthPerYear = 12; | |
// 注: new Date()の第2引数は0-11の値を指定する必要がある。また、第3引数に0を指定すると、日時は一つ前の月の最終日に設定される | |
const datePerMonth = (new Date(year, month - 1 + 1, 0)).getDate(); | |
const hoursPerDay = 24; | |
const minutesPerHour = 60; | |
// 現在のms | |
const ms_current = now.getTime(); | |
// 今日の0:00のms | |
const ms_thisMidnight = (new Date(year, month - 1, date)).getTime(); | |
// 明日の0:00のms | |
const ms_nextMidnight = (new Date(year, month - 1, date + 1)).getTime(); | |
// 今月1日 0:00のms | |
const ms_firstDayOfThisMonth = (new Date(year, month - 1, 1)).getTime(); | |
// 来月1日 0:00のms | |
const ms_firstDayOfNextMonth = (new Date(year, month - 1 + 1, 1)).getTime(); | |
// 今年1/01 0:00のms | |
const ms_firstDayOfThisYear = (new Date(year, 1 - 1, 1)).getTime(); | |
// 来年1/01 0:00のms | |
const ms_firstDayOfNextYear = (new Date(year + 1, 1 - 1, 1)).getTime(); | |
console.log(ms_current); | |
console.log(ms_thisMidnight); | |
console.log(ms_nextMidnight); | |
console.log(ms_firstDayOfThisMonth); | |
console.log(ms_firstDayOfNextMonth); | |
console.log(ms_firstDayOfThisYear); | |
console.log(ms_firstDayOfNextYear); | |
// ================= | |
// ====== 関数 ====== | |
// ================= | |
/** | |
* 進捗バーの画像を返す。 | |
* @param {number} rate - 進捗。0.00から1.00の範囲で指定。 | |
* @param {Color} barColor - 進捗バーの色。 | |
* @returns {Image} | |
*/ | |
const createProgressBarImage = ((rate, barColor) => { | |
// context準備 | |
const context = new DrawContext(); | |
context.size = new Size(barWidth, barHeight); | |
context.opaque = false; | |
context.respectScreenScale = true; | |
// バー背景描画 | |
const barBackgroundPath = new Path(); | |
barBackgroundPath.addRoundedRect(new Rect(0, 0, barWidth, barHeight), barCornerWidth, barCornerHeight); | |
context.addPath(barBackgroundPath); | |
context.setFillColor(barBackgroundColor); | |
context.fillPath(); | |
// バー全景描画 | |
const barForegroundPath = new Path(); | |
barForegroundPath.addRoundedRect(new Rect(0, 0, barWidth*rate, barHeight), barCornerWidth, barCornerHeight); | |
context.addPath(barForegroundPath); | |
context.setFillColor(barColor); | |
context.fillPath(); | |
// 完成品を返す | |
return context.getImage(); | |
}); | |
/** | |
* 進捗バーとラベルを生成しウィジェットに追加します。 | |
* @param {number} current - 現在の値 | |
* @param {number} total - バーが最大になる値 | |
* @param {string} labelBase - バーの上部に表示される値。label中の$1という文字列は、currentとtotalから計算された進捗の百分率の値で置き換えられて表示される。 | |
* @param {Color} barColor - バーの色 | |
*/ | |
const addBar = ((current, total, labelBase = "", barColor) => { | |
if (labelBase === "") { | |
return; | |
} | |
// ラベル生成 | |
const label = widget.addText(labelBase.replace(/\$1/g, (current/total*100).toFixed(1))); | |
label.textColor = barLabelColor; | |
label.font = barLabelFont; | |
// バー生成 | |
widget.addSpacer(barPadding); | |
const img = widget.addImage(createProgressBarImage(current / total, barColor)); | |
img.imageSize = new Size(barWidth, barHeight); | |
widget.addSpacer(barPadding); | |
}); | |
// =========================== | |
// ====== ウィジェット構築 ====== | |
// =========================== | |
// today | |
addBar( | |
ms_current - ms_thisMidnight, | |
ms_nextMidnight - ms_thisMidnight, | |
todayBarLabel, | |
todayBarColor | |
); | |
// thisMonth | |
addBar( | |
ms_current - ms_firstDayOfThisMonth, | |
ms_firstDayOfNextMonth - ms_firstDayOfThisMonth, | |
thisMonthBarLabel, | |
thisMonthBarColor | |
); | |
// thisYear | |
addBar( | |
ms_current - ms_firstDayOfThisYear, | |
ms_firstDayOfNextYear - ms_firstDayOfThisYear, | |
thisYearBarLabel, | |
thisYearBarColor | |
); | |
if (updatedInfoLabel !== "") { | |
const updatedInfo = widget.addText( | |
updatedInfoLabel.replace( | |
/\$1/, | |
hours + ":" + (("00"+minutes).slice(2)), | |
), | |
); | |
updatedInfo.textColor = updatedInfoLabelColor; | |
updatedInfo.font = updatedInfoLabelFont; | |
} | |
// =========================== | |
// ====== ウィジェット反映 ====== | |
// =========================== | |
Script.setWidget(widget); | |
Script.complete(); | |
widget.presentSmall(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment