1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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);
}
|