Navigation: add version update indicator (#29343)
This commit is contained in:
parent
1c7cdeb87a
commit
90fdd8ee6b
8 changed files with 85 additions and 18 deletions
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<GenericModal id="aboutModal" :size="modalSize">
|
||||
<GenericModal id="aboutModal" :size="modalSize" @opened="acknowledge">
|
||||
<template #title>
|
||||
<a :href="websiteUrl" target="_blank" rel="noopener noreferrer"
|
||||
><Logo class="about-logo"
|
||||
|
|
@ -132,8 +132,15 @@ import "@h2d2/shopicons/es/regular/gift";
|
|||
import "@h2d2/shopicons/es/filled/heart";
|
||||
import Logo from "./Footer/Logo.vue";
|
||||
import api from "@/api";
|
||||
import settings from "@/settings";
|
||||
import { extractDomain } from "@/utils/extractDomain";
|
||||
import { isDevelopment, isNightly, getReleaseName, shortCommit } from "@/utils/version";
|
||||
import {
|
||||
isDevelopment,
|
||||
isNightly,
|
||||
getReleaseName,
|
||||
shortCommit,
|
||||
isNewVersionAvailable,
|
||||
} from "@/utils/version";
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
const GITHUB_REPO = "https://github.com/evcc-io/evcc";
|
||||
|
|
@ -193,11 +200,7 @@ export default defineComponent({
|
|||
return this.releaseNotes.replaceAll("<h2>Changelog</h2>", "");
|
||||
},
|
||||
newVersionAvailable() {
|
||||
return (
|
||||
this.availableVersion &&
|
||||
!this.development &&
|
||||
this.availableVersion !== this.installed
|
||||
);
|
||||
return isNewVersionAvailable(this.installed, this.availableVersion);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -213,6 +216,10 @@ export default defineComponent({
|
|||
releaseNotesUrl(version?: string) {
|
||||
return `${GITHUB_REPO}/releases/tag/${version}`;
|
||||
},
|
||||
acknowledge() {
|
||||
if (!this.newVersionAvailable) return;
|
||||
settings.lastAcknowledgedVersion = this.availableVersion!;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
:evopt="evopt"
|
||||
:installed="installed"
|
||||
:commit="commit"
|
||||
:available-version="availableVersion"
|
||||
/>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
@ -75,6 +76,7 @@ export default defineComponent({
|
|||
evopt: { type: Object as PropType<EvOpt>, required: false },
|
||||
installed: String,
|
||||
commit: String,
|
||||
availableVersion: String,
|
||||
},
|
||||
computed: {
|
||||
hidden() {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
:evopt="evopt"
|
||||
:installed="installed"
|
||||
:commit="commit"
|
||||
:available-version="availableVersion"
|
||||
@close="open = false"
|
||||
/>
|
||||
</template>
|
||||
|
|
@ -31,6 +32,8 @@ import Item from "./Item.vue";
|
|||
import MoreIcon from "../MaterialIcon/More.vue";
|
||||
import MoreMenu from "./MoreMenu.vue";
|
||||
import { isUserConfigError } from "@/utils/fatal";
|
||||
import { isNewVersionAvailable, isNewVersionUnacknowledged } from "@/utils/version";
|
||||
import settings from "@/settings";
|
||||
import type { FatalError, Sponsor, EvOpt, AuthProviders } from "@/types/evcc";
|
||||
|
||||
export default defineComponent({
|
||||
|
|
@ -46,6 +49,7 @@ export default defineComponent({
|
|||
evopt: { type: Object as PropType<EvOpt>, required: false },
|
||||
installed: String,
|
||||
commit: String,
|
||||
availableVersion: String,
|
||||
},
|
||||
data() {
|
||||
return { open: false };
|
||||
|
|
@ -69,14 +73,27 @@ export default defineComponent({
|
|||
showConfigBadge() {
|
||||
return this.sponsorExpires || isUserConfigError(this.fatal);
|
||||
},
|
||||
newVersionAvailable() {
|
||||
return isNewVersionAvailable(this.installed, this.availableVersion);
|
||||
},
|
||||
showVersionBadge() {
|
||||
return isNewVersionUnacknowledged(
|
||||
this.installed,
|
||||
this.availableVersion,
|
||||
settings.lastAcknowledgedVersion
|
||||
);
|
||||
},
|
||||
showRootBadge() {
|
||||
return this.authorizationRequired || this.showConfigBadge;
|
||||
return this.authorizationRequired || this.showConfigBadge || this.showVersionBadge;
|
||||
},
|
||||
badgeClass() {
|
||||
if (this.fatal.length > 0) {
|
||||
return "bg-danger";
|
||||
}
|
||||
return "bg-warning";
|
||||
if (this.authorizationRequired || this.showConfigBadge) {
|
||||
return "bg-warning";
|
||||
}
|
||||
return "bg-darker-green";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,14 @@
|
|||
class="dropdown-item d-flex align-items-center"
|
||||
@click="openAboutModal"
|
||||
>
|
||||
<span v-if="showVersionBadge" class="circle-badge me-1 bg-darker-green"></span>
|
||||
<span>evcc</span>
|
||||
<span class="ms-2 text-muted small">{{ versionLabel }}</span>
|
||||
<shopicon-regular-gift
|
||||
v-if="newVersionAvailable"
|
||||
size="s"
|
||||
class="ms-2 text-gray-light gift-icon"
|
||||
></shopicon-regular-gift>
|
||||
</button>
|
||||
<button v-if="isApp" type="button" class="dropdown-item" @click="openNativeSettings">
|
||||
{{ $t("header.nativeSettings") }}
|
||||
|
|
@ -65,9 +71,15 @@
|
|||
|
||||
<script lang="ts">
|
||||
import Modal from "bootstrap/js/dist/modal";
|
||||
import "@h2d2/shopicons/es/regular/gift";
|
||||
import { logout, isLoggedIn } from "../Auth/auth";
|
||||
import { isApp, sendToApp } from "@/utils/native";
|
||||
import { getShortVersion } from "@/utils/version";
|
||||
import {
|
||||
getShortVersion,
|
||||
isNewVersionAvailable,
|
||||
isNewVersionUnacknowledged,
|
||||
} from "@/utils/version";
|
||||
import settings from "@/settings";
|
||||
import { isUserConfigError } from "@/utils/fatal";
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import type { FatalError, Sponsor, EvOpt, AuthProviders } from "@/types/evcc";
|
||||
|
|
@ -84,6 +96,7 @@ export default defineComponent({
|
|||
evopt: { type: Object as PropType<EvOpt>, required: false },
|
||||
installed: String,
|
||||
commit: String,
|
||||
availableVersion: String,
|
||||
},
|
||||
emits: ["close"],
|
||||
data() {
|
||||
|
|
@ -120,6 +133,16 @@ export default defineComponent({
|
|||
versionLabel() {
|
||||
return getShortVersion(this.installed || "", this.commit);
|
||||
},
|
||||
newVersionAvailable() {
|
||||
return isNewVersionAvailable(this.installed, this.availableVersion);
|
||||
},
|
||||
showVersionBadge() {
|
||||
return isNewVersionUnacknowledged(
|
||||
this.installed,
|
||||
this.availableVersion,
|
||||
settings.lastAcknowledgedVersion
|
||||
);
|
||||
},
|
||||
optimizeAvailable() {
|
||||
return !!this.evopt && this.experimental;
|
||||
},
|
||||
|
|
@ -226,4 +249,9 @@ export default defineComponent({
|
|||
color: var(--bs-primary);
|
||||
border-left: 2px solid var(--bs-primary);
|
||||
}
|
||||
|
||||
.gift-icon {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import Modal from "bootstrap/js/dist/modal";
|
|||
import "@h2d2/shopicons/es/regular/gift";
|
||||
import "@h2d2/shopicons/es/regular/moonstars";
|
||||
import Logo from "./Logo.vue";
|
||||
import { isDevelopment } from "@/utils/version";
|
||||
import { isNewVersionAvailable } from "@/utils/version";
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
|
|
@ -56,11 +56,7 @@ export default defineComponent({
|
|||
return `https://github.com/evcc-io/evcc/commit/${this.commit}`;
|
||||
},
|
||||
newVersionAvailable() {
|
||||
return (
|
||||
this.available &&
|
||||
!isDevelopment(this.installed || "") &&
|
||||
this.available !== this.installed
|
||||
);
|
||||
return isNewVersionAvailable(this.installed, this.available);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -27,13 +27,14 @@ const LAST_TARGET_TIME = "last_target_time";
|
|||
const LAST_SOC_GOAL = "last_soc_goal";
|
||||
const LAST_ENERGY_GOAL = "last_energy_goal";
|
||||
const CONFIG_CARD_HEIGHTS = "config_card_heights";
|
||||
const LAST_ACKNOWLEDGED_VERSION = "last_acknowledged_version";
|
||||
|
||||
function read(key: string) {
|
||||
return window.localStorage[key];
|
||||
}
|
||||
|
||||
function save(key: string) {
|
||||
return (value: string | null) => {
|
||||
return (value: string | null | undefined) => {
|
||||
try {
|
||||
if (value) {
|
||||
window.localStorage[key] = value;
|
||||
|
|
@ -132,6 +133,7 @@ export interface Settings {
|
|||
lastSocGoal: number | undefined;
|
||||
lastEnergyGoal: number | undefined;
|
||||
cardHeights: Record<string, number>;
|
||||
lastAcknowledgedVersion: string | undefined;
|
||||
}
|
||||
|
||||
const settings: Settings = reactive({
|
||||
|
|
@ -160,6 +162,7 @@ const settings: Settings = reactive({
|
|||
lastSocGoal: readNumber(LAST_SOC_GOAL),
|
||||
lastEnergyGoal: readNumber(LAST_ENERGY_GOAL),
|
||||
cardHeights: readJSON(CONFIG_CARD_HEIGHTS),
|
||||
lastAcknowledgedVersion: read(LAST_ACKNOWLEDGED_VERSION),
|
||||
});
|
||||
|
||||
watch(() => settings.locale, save(SETTINGS_LOCALE));
|
||||
|
|
@ -187,6 +190,7 @@ watch(() => settings.lastTargetTime, save(LAST_TARGET_TIME));
|
|||
watch(() => settings.lastSocGoal, saveNumber(LAST_SOC_GOAL));
|
||||
watch(() => settings.lastEnergyGoal, saveNumber(LAST_ENERGY_GOAL));
|
||||
watch(() => settings.cardHeights, saveJSON(CONFIG_CARD_HEIGHTS), { deep: true });
|
||||
watch(() => settings.lastAcknowledgedVersion, save(LAST_ACKNOWLEDGED_VERSION));
|
||||
|
||||
export default settings;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export interface State {
|
|||
authProviders?: AuthProviders;
|
||||
evopt?: EvOpt;
|
||||
version?: string;
|
||||
availableVersion?: string;
|
||||
system?: string;
|
||||
timezone?: string;
|
||||
battery?: Battery;
|
||||
|
|
|
|||
|
|
@ -19,5 +19,17 @@ export function shortCommit(commit?: string): string {
|
|||
export function getShortVersion(version: string, commit?: string): string {
|
||||
if (isDevelopment(version)) return "dev build";
|
||||
if (isNightly(version, commit)) return `v${version} (${shortCommit(commit)})`;
|
||||
return version;
|
||||
return `v${version}`;
|
||||
}
|
||||
|
||||
export function isNewVersionAvailable(installed?: string, available?: string): boolean {
|
||||
return !!available && !isDevelopment(installed || "") && available !== installed;
|
||||
}
|
||||
|
||||
export function isNewVersionUnacknowledged(
|
||||
installed?: string,
|
||||
available?: string,
|
||||
acknowledged?: string
|
||||
): boolean {
|
||||
return isNewVersionAvailable(installed, available) && available !== acknowledged;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue