UI: add 12h/24h setting (#21140)
This commit is contained in:
parent
376537363f
commit
9da6236e03
8 changed files with 80 additions and 3 deletions
|
|
@ -42,6 +42,21 @@
|
|||
equal-width
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow id="settingsTimeFormat" :label="$t('settings.time.label')">
|
||||
<SelectGroup
|
||||
id="settingsTimeFormat"
|
||||
v-model="timeFormat"
|
||||
class="w-75"
|
||||
transparent
|
||||
:options="
|
||||
TIME_FORMATS.map((value) => ({
|
||||
value,
|
||||
name: $t(`settings.time.${value}h`),
|
||||
}))
|
||||
"
|
||||
equal-width
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow id="telemetryEnabled" :label="$t('settings.telemetry.label')">
|
||||
<TelemetrySettings :sponsorActive="sponsor && !!sponsor.name" class="mt-1 mb-0" />
|
||||
</FormRow>
|
||||
|
|
@ -82,12 +97,15 @@ import FormRow from "../Helper/FormRow.vue";
|
|||
import SelectGroup from "../Helper/SelectGroup.vue";
|
||||
import { getLocalePreference, setLocalePreference, LOCALES, removeLocalePreference } from "@/i18n";
|
||||
import { getThemePreference, setThemePreference, THEMES } from "@/theme";
|
||||
import { getUnits, setUnits, UNITS } from "@/units";
|
||||
import { getUnits, setUnits, UNITS, is12hFormat, set12hFormat } from "@/units";
|
||||
import { getHiddenFeatures, setHiddenFeatures } from "@/featureflags";
|
||||
import { isApp } from "@/utils/native";
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import type { Sponsor } from "@/types/evcc";
|
||||
|
||||
const TIME_12H = "12";
|
||||
const TIME_24H = "24";
|
||||
|
||||
export default defineComponent({
|
||||
name: "UserInterfaceSettings",
|
||||
components: { TelemetrySettings, FormRow, SelectGroup },
|
||||
|
|
@ -99,10 +117,12 @@ export default defineComponent({
|
|||
theme: getThemePreference(),
|
||||
language: getLocalePreference() || "",
|
||||
unit: getUnits(),
|
||||
timeFormat: is12hFormat() ? TIME_12H : TIME_24H,
|
||||
hiddenFeatures: getHiddenFeatures(),
|
||||
fullscreenActive: false,
|
||||
THEMES,
|
||||
UNITS,
|
||||
TIME_FORMATS: [TIME_24H, TIME_12H],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -126,6 +146,9 @@ export default defineComponent({
|
|||
unit(value) {
|
||||
setUnits(value);
|
||||
},
|
||||
timeFormat(value) {
|
||||
set12hFormat(value === TIME_12H);
|
||||
},
|
||||
theme(value) {
|
||||
setThemePreference(value);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
<div class="slot-label">
|
||||
<span v-if="!slot.isTarget || targetNearlyOutOfRange">{{
|
||||
slot.startHour
|
||||
formatHour(slot.startHour)
|
||||
}}</span>
|
||||
<br />
|
||||
<span v-if="showWeekday(index)">{{ slot.day }}</span>
|
||||
|
|
@ -55,6 +55,7 @@
|
|||
<script lang="ts">
|
||||
import type { PropType } from "vue";
|
||||
import "@h2d2/shopicons/es/regular/arrowright";
|
||||
import { is12hFormat } from "@/units";
|
||||
import PlanEndIcon from "../MaterialIcon/PlanEnd.vue";
|
||||
import formatter from "@/mixins/formatter";
|
||||
import type { Slot } from "@/types/evcc";
|
||||
|
|
@ -164,6 +165,9 @@ export default {
|
|||
clearTimeout(this.longPressTimer);
|
||||
this.hoverSlot(null);
|
||||
},
|
||||
formatHour(hour: number) {
|
||||
return is12hFormat() ? hour % 12 : hour;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import { mount, config } from "@vue/test-utils";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
import formatter, { POWER_UNIT } from "./formatter";
|
||||
import * as units from "../units";
|
||||
|
||||
const is12hSpy = vi.spyOn(units, "is12hFormat").mockReturnValue(false);
|
||||
|
||||
config.global.mocks["$i18n"] = { locale: "de-DE" };
|
||||
config.global.mocks["$t"] = (a) => a;
|
||||
|
|
@ -183,3 +186,23 @@ describe("fmtPercentage", () => {
|
|||
expect(fmt.fmtPercentage(-100, 0, false)).eq("-100 %");
|
||||
});
|
||||
});
|
||||
|
||||
const testDate = new Date(2023, 0, 15, 15, 30); // Jan 15, 2023, 15:30 (3:30 PM)
|
||||
|
||||
describe("12h/24h time format", () => {
|
||||
test("12h format", () => {
|
||||
is12hSpy.mockReturnValue(true);
|
||||
expect(fmt.fmtHourMinute(testDate)).toBe("3:30 PM");
|
||||
expect(fmt.fmtFullDateTime(testDate)).toBe("So., 15. Jan., 3:30 PM");
|
||||
expect(fmt.fmtWeekdayTime(testDate)).toBe("So. 3:30 PM");
|
||||
expect(fmt.fmtAbsoluteDate(testDate)).toBe("So 3:30 PM");
|
||||
});
|
||||
|
||||
test("24h format", () => {
|
||||
is12hSpy.mockReturnValue(false);
|
||||
expect(fmt.fmtHourMinute(testDate)).toBe("15:30");
|
||||
expect(fmt.fmtFullDateTime(testDate)).toBe("So., 15. Jan., 15:30");
|
||||
expect(fmt.fmtWeekdayTime(testDate)).toBe("So., 15:30");
|
||||
expect(fmt.fmtAbsoluteDate(testDate)).toBe("So 15:30");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { defineComponent } from "vue";
|
||||
import { is12hFormat } from "@/units";
|
||||
import { CURRENCY } from "../types/evcc";
|
||||
|
||||
// list of currencies where energy price should be displayed in subunits (factor 100)
|
||||
|
|
@ -198,6 +199,7 @@ export default defineComponent({
|
|||
if (locale === "de") return date.getHours();
|
||||
return new Intl.DateTimeFormat(locale, {
|
||||
hour: "numeric",
|
||||
hour12: is12hFormat(),
|
||||
}).format(date);
|
||||
},
|
||||
weekdayShort(date: Date) {
|
||||
|
|
@ -210,6 +212,7 @@ export default defineComponent({
|
|||
const hour = new Intl.DateTimeFormat(this.$i18n?.locale, {
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
hour12: is12hFormat(),
|
||||
}).format(date);
|
||||
|
||||
return `${weekday} ${hour}`.trim();
|
||||
|
|
@ -218,6 +221,7 @@ export default defineComponent({
|
|||
return new Intl.DateTimeFormat(this.$i18n?.locale, {
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
hour12: is12hFormat(),
|
||||
}).format(date);
|
||||
},
|
||||
fmtFullDateTime(date: Date, short: boolean) {
|
||||
|
|
@ -227,6 +231,7 @@ export default defineComponent({
|
|||
day: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
hour12: is12hFormat(),
|
||||
}).format(date);
|
||||
},
|
||||
fmtWeekdayTime(date: Date) {
|
||||
|
|
@ -234,6 +239,7 @@ export default defineComponent({
|
|||
weekday: "short",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
hour12: is12hFormat(),
|
||||
}).format(date);
|
||||
},
|
||||
fmtMonthYear(date: Date) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { reactive, watch } from "vue";
|
|||
const SETTINGS_LOCALE = "settings_locale";
|
||||
const SETTINGS_THEME = "settings_theme";
|
||||
const SETTINGS_UNIT = "settings_unit";
|
||||
const SETTINGS_12H_FORMAT = "settings_12h_format";
|
||||
const SETTINGS_HIDDEN_FEATURES = "settings_hidden_features";
|
||||
const SETTINGS_ENERGYFLOW_DETAILS = "settings_energyflow_details";
|
||||
const SETTINGS_ENERGYFLOW_PV = "settings_energyflow_pv";
|
||||
|
|
@ -59,6 +60,7 @@ const settings = reactive({
|
|||
locale: read(SETTINGS_LOCALE),
|
||||
theme: read(SETTINGS_THEME),
|
||||
unit: read(SETTINGS_UNIT),
|
||||
is12hFormat: readBool(SETTINGS_12H_FORMAT),
|
||||
hiddenFeatures: readBool(SETTINGS_HIDDEN_FEATURES),
|
||||
energyflowDetails: readBool(SETTINGS_ENERGYFLOW_DETAILS),
|
||||
energyflowPv: readBool(SETTINGS_ENERGYFLOW_PV),
|
||||
|
|
@ -76,6 +78,7 @@ const settings = reactive({
|
|||
watch(() => settings.locale, save(SETTINGS_LOCALE));
|
||||
watch(() => settings.theme, save(SETTINGS_THEME));
|
||||
watch(() => settings.unit, save(SETTINGS_UNIT));
|
||||
watch(() => settings.is12hFormat, saveBool(SETTINGS_12H_FORMAT));
|
||||
watch(() => settings.hiddenFeatures, saveBool(SETTINGS_HIDDEN_FEATURES));
|
||||
watch(() => settings.energyflowDetails, saveBool(SETTINGS_ENERGYFLOW_DETAILS));
|
||||
watch(() => settings.energyflowPv, saveBool(SETTINGS_ENERGYFLOW_PV));
|
||||
|
|
|
|||
|
|
@ -29,3 +29,11 @@ export function getUnits() {
|
|||
export function setUnits(value) {
|
||||
settings.unit = value;
|
||||
}
|
||||
|
||||
export function is12hFormat() {
|
||||
return settings.is12hFormat;
|
||||
}
|
||||
|
||||
export function set12hFormat(value) {
|
||||
settings.is12hFormat = value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -931,6 +931,11 @@
|
|||
"label": "Design",
|
||||
"light": "Hell"
|
||||
},
|
||||
"time": {
|
||||
"12h": "12h",
|
||||
"24h": "24h",
|
||||
"label": "Zeitformat"
|
||||
},
|
||||
"title": "Darstellung",
|
||||
"unit": {
|
||||
"km": "Kilometer",
|
||||
|
|
|
|||
|
|
@ -931,6 +931,11 @@
|
|||
"label": "Design",
|
||||
"light": "light"
|
||||
},
|
||||
"time": {
|
||||
"12h": "12h",
|
||||
"24h": "24h",
|
||||
"label": "Time format"
|
||||
},
|
||||
"title": "User Interface",
|
||||
"unit": {
|
||||
"km": "km",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue