diff options
| author | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
|---|---|---|
| committer | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
| commit | 5d94c0a7d44a2255b81815a52a7056a94a39842d (patch) | |
| tree | 759bdea9645c6a62f9e1e4c001f7d81cccd120d2 /raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/modules/schedule-info.js | |
| parent | e79cdf210b267f21a186255ce1a4d50029439d54 (diff) | |
| download | RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.tar.gz RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.zip | |
update Raveos themes
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/modules/schedule-info.js')
| -rw-r--r-- | raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/modules/schedule-info.js | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/modules/schedule-info.js b/raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/modules/schedule-info.js new file mode 100644 index 0000000..394ebc8 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/modules/schedule-info.js @@ -0,0 +1,150 @@ +// SPDX-FileCopyrightText: 2023 Deminder <tremminder@gmail.com> +// SPDX-License-Identifier: GPL-3.0-or-later + +import GLib from 'gi://GLib'; +import { gettext as _, ngettext as _n, pgettext as C_ } from './translation.js'; +import { mapLegacyAction, untilText } from '../dbus-service/action.js'; + +export class ScheduleInfo { + constructor({ mode = '?', deadline = -1, external = false }) { + this._v = { mode: mapLegacyAction(mode), deadline, external }; + } + + copy(vals) { + return new ScheduleInfo({ ...this._v, ...vals }); + } + + get deadline() { + return this._v.deadline; + } + + get external() { + return this._v.external; + } + + get mode() { + return this._v.mode; + } + + get scheduled() { + return this.deadline > -1; + } + + get secondsLeft() { + return this.deadline - GLib.DateTime.new_now_utc().to_unix(); + } + + get minutes() { + return Math.floor(this.secondsLeft / 60); + } + + get label() { + let label = ''; + if (this.scheduled) { + label = _('{durationString} until {untiltext}') + .replace('{durationString}', durationString(this.secondsLeft)) + .replace('{untiltext}', untilText(this.mode)); + if (this.external) { + label = _('{label} (sys)').replace('{label}', label); + } + } + return label; + } + + get absoluteTimeString() { + return GLib.DateTime.new_from_unix_utc(this.deadline) + .to_local() + .format(C_('absolute schedule notation', '%a, %T')); + } + + isMoreUrgendThan(otherInfo) { + return ( + !otherInfo.scheduled || + (this.scheduled && + // external deadline is instant, internal deadline has 1 min slack time + (this.external ? this.deadline : this.deadline + 58) < + otherInfo.deadline) + ); + } +} + +export function getShutdownScheduleFromSettings(settings) { + return new ScheduleInfo({ + mode: settings.get_string('shutdown-mode-value'), + deadline: settings.get_int('shutdown-timestamp-value'), + }); +} + +export function getSliderMinutesFromSettings(settings, prefix) { + const sliderValue = settings.get_double(`${prefix}-slider-value`) / 100.0; + const rampUp = settings.get_double(`nonlinear-${prefix}-slider-value`); + const ramp = x => Math.expm1(rampUp * x) / Math.expm1(rampUp); + let minutes = Math.floor( + (rampUp === 0 ? sliderValue : ramp(sliderValue)) * + settings.get_int(`${prefix}-max-timer-value`) + ); + + const refstr = settings.get_string(`${prefix}-ref-timer-value`); + // default: 'now' + const MS = 1000 * 60; + if (refstr.includes(':')) { + const mh = refstr + .split(':') + .map(s => Number.parseInt(s)) + .filter(n => !Number.isNaN(n) && n >= 0); + if (mh.length >= 2) { + const d = new Date(); + const nowTime = d.getTime(); + d.setHours(mh[0]); + d.setMinutes(mh[1]); + + if (d.getTime() + MS * minutes < nowTime) { + d.setDate(d.getDate() + 1); + } + minutes += Math.floor(new Date(d.getTime() - nowTime).getTime() / MS); + } + } else if (prefix !== 'shutdown' && refstr === 'shutdown') { + minutes += getSliderMinutesFromSettings(settings, 'shutdown'); + } + return minutes; +} + +/** + * A short duration string showing >=3 hours, >=1 mins, or secs. + * + * @param {number} seconds duration in seconds + */ +export function durationString(seconds) { + const sign = Math.sign(seconds); + const absSec = Math.floor(Math.abs(seconds)); + const minutes = Math.floor(absSec / 60); + const hours = Math.floor(minutes / 60); + if (hours >= 3) { + return _n('%s hour', '%s hours', hours).format(sign * hours); + } else if (minutes === 0) { + return _n('%s sec', '%s secs', absSec).format( + sign * (absSec > 5 ? 10 * Math.ceil(absSec / 10) : absSec) + ); + } + return _n('%s min', '%s mins', minutes).format(sign * minutes); +} + +/** + * + * @param minutes + * @param hrFmt + * @param minFmt + */ +export function longDurationString(minutes, hrFmt, minFmt) { + const hours = Math.floor(minutes / 60); + const residualMinutes = minutes % 60; + let parts = [minFmt(residualMinutes).format(residualMinutes)]; + if (hours) { + parts = [hrFmt(hours).format(hours)].concat(parts); + } + return parts.join(' '); +} + +export function absoluteTimeString(minutes, timeFmt) { + return GLib.DateTime.new_now_local().add_minutes(minutes).format(timeFmt); +} |