Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions frontend/src/html/popups.html
Original file line number Diff line number Diff line change
Expand Up @@ -1060,9 +1060,17 @@
<br />
<span class="red">You can only do this once!</span>
</div>
<input type="number" min="-11" max="12" value="0" />
<div class="group">
<button class="decreaseOffset">
<i class="fas fa-fw fa-chevron-left"></i>
</button>
<input type="number" min="-11" max="12" value="0" step="0.5" />
<button class="increaseOffset">
<i class="fas fa-fw fa-chevron-right"></i>
</button>
</div>
<div class="preview"></div>
<button>set</button>
<button class="submit">set</button>
</div>
</dialog>
<dialog id="editResultTagsModal" class="modalWrapper hidden">
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/styles/popups.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,20 @@ body.darkMode {
.red {
color: var(--error-color);
}
.group {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0.5rem;
justify-items: center;
align-items: center;
font-size: 2em;
button {
width: 100%;
}
input {
text-align: center;
}
}
.preview {
& > div:first-child {
margin-bottom: 1rem;
Expand Down
86 changes: 66 additions & 20 deletions frontend/src/ts/modals/streak-hour-offset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { getSnapshot, setSnapshot } from "../db";
import AnimatedModal from "../utils/animated-modal";
import { Snapshot } from "../constants/default-snapshot";

let state = {
offset: 0,
};

export function show(): void {
if (!ConnectionState.get()) {
Notifications.add("You are offline", 0, {
Expand All @@ -17,36 +21,35 @@ export function show(): void {
}

void modal.show({
focusFirstInput: true,
focusFirstInput: "focusAndSelect",
beforeAnimation: async (modalEl) => {
if (getSnapshot()?.streakHourOffset !== undefined) {
modalEl.qs("input")?.remove();
modalEl.qs(".preview")?.remove();
modalEl.qs("button")?.remove();
modalEl.qsa("button")?.remove();
modalEl
.qs(".text")
?.setText("You have already set your streak hour offset.");
?.setText(
`You have already set your streak hour offset to ${
getSnapshot()?.streakHourOffset ?? "?"
}. You can only set your streak hour offset once.`,
);
} else {
modalEl.qs<HTMLInputElement>("input")?.setValue("0");
state.offset = 0;
updateDisplay();
updatePreview();
}
},
});
}

function updatePreview(): void {
const inputValue = parseInt(
modal.getModal().qs<HTMLInputElement>("input")?.getValue() ?? "",
10,
);
const inputValue = state.offset;

const preview = modal.getModal().qs(".preview");

const date = new Date();
date.setUTCHours(0);
date.setUTCMinutes(0);
date.setUTCSeconds(0);
date.setUTCMilliseconds(0);
date.setUTCHours(0, 0, 0, 0);

const newDate = new Date();
newDate.setUTCHours(0);
Expand All @@ -62,23 +65,30 @@ function updatePreview(): void {
`);
}

function updateDisplay(): void {
modal
.getModal()
.qs<HTMLInputElement>("input")
?.setValue(state.offset.toFixed(1));
}

function hide(): void {
void modal.hide();
}

async function apply(): Promise<void> {
const value = parseInt(
modal.getModal().qs<HTMLInputElement>("input")?.getValue() ?? "",
10,
);
const value = state.offset;

if (isNaN(value)) {
Notifications.add("Streak hour offset must be a number", 0);
return;
}

if (value < -11 || value > 12) {
Notifications.add("Streak hour offset must be between -11 and 12", 0);
if (value < -11 || value > 12 || (value % 1 !== 0 && value % 1 !== 0.5)) {
Notifications.add(
"Streak offset must be between -11 and 12. Times ending in .5 can be used for 30-minute increments.",
0,
);
return;
}

Expand All @@ -88,25 +98,61 @@ async function apply(): Promise<void> {
body: { hourOffset: value },
});
Loader.hide();

if (response.status !== 200) {
Notifications.add("Failed to set streak hour offset", -1, { response });
} else {
Notifications.add("Streak hour offset set", 1);
const snap = getSnapshot() as Snapshot;

snap.streakHourOffset = value;
setSnapshot(snap);
hide();
}
}

function setStateToInput(): void {
const inputValue = parseFloat(
modal.getModal().qs<HTMLInputElement>("input")?.getValue() ?? "0",
);
if (!isNaN(inputValue)) {
state.offset = inputValue;
if (state.offset < -11) state.offset = -11;
if (state.offset > 12) state.offset = 12;
} else {
state.offset = 0;
}
}

const modal = new AnimatedModal({
dialogId: "streakHourOffsetModal",
setup: async (modalEl): Promise<void> => {
modalEl.qs("input")?.on("input", () => {
modalEl.qs("input")?.on("focusout", () => {
setStateToInput();
updateDisplay();
updatePreview();
});
modalEl.qs("button")?.on("click", () => {
modalEl.qs("input")?.on("keyup", (e) => {
if (e.key === "Enter") {
setStateToInput();
updateDisplay();
updatePreview();
}
});
modalEl.qs(".submit")?.on("click", () => {
void apply();
});
modalEl.qs(".decreaseOffset")?.on("click", () => {
state.offset -= 0.5;
if (state.offset < -11) state.offset = -11;
updateDisplay();
updatePreview();
});
modalEl.qs(".increaseOffset")?.on("click", () => {
state.offset += 0.5;
if (state.offset > 12) state.offset = 12;
updateDisplay();
updatePreview();
});
},
});
1 change: 1 addition & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.