aboutsummaryrefslogtreecommitdiffstats
path: root/apps/weather_status/src/App.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/weather_status/src/App.vue')
-rw-r--r--apps/weather_status/src/App.vue435
1 files changed, 185 insertions, 250 deletions
diff --git a/apps/weather_status/src/App.vue b/apps/weather_status/src/App.vue
index 8b96a520ef7..34dc8e90efa 100644
--- a/apps/weather_status/src/App.vue
+++ b/apps/weather_status/src/App.vue
@@ -1,189 +1,238 @@
<!--
- - @copyright Copyright (c) 2020 Julien Veyssier <eneiluj@posteo.net>
- - @author Julien Veyssier <eneiluj@posteo.net>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - This program is distributed in the hope that it will be useful,
- - but WITHOUT ANY WARRANTY; without even the implied warranty of
- - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - GNU Affero General Public License for more details.
- -
- - You should have received a copy of the GNU Affero General Public License
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
- <li :class="{ inline }">
- <div id="weather-status-menu-item">
- <Actions class="weather-status-menu-item__subheader"
- :default-icon="weatherIcon"
- :menu-title="currentWeatherMessage">
- <ActionText v-if="gotWeather"
- :icon="futureWeatherIcon">
- {{ forecastMessage }}
- </ActionText>
- <ActionLink v-if="gotWeather"
- icon="icon-address"
- target="_blank"
- :href="weatherLinkTarget"
- :close-after-click="true">
- {{ locationText }}
- </ActionLink>
- <ActionButton v-if="gotWeather"
- :icon="addRemoveFavoriteIcon"
- @click="onAddRemoveFavoriteClick">
- {{ addRemoveFavoriteText }}
- </ActionButton>
- <ActionSeparator v-if="address && !errorMessage" />
- <ActionButton icon="icon-crosshair"
- :close-after-click="true"
- @click="onBrowserLocationClick">
- {{ t('weather_status', 'Detect location') }}
- </ActionButton>
- <ActionInput ref="addressInput"
- :disabled="false"
- icon="icon-rename"
- type="text"
- value=""
- @submit="onAddressSubmit">
- {{ t('weather_status', 'Set custom address') }}
- </ActionInput>
- <ActionButton v-show="favorites.length > 0"
- :icon="toggleFavoritesIcon"
- @click="showFavorites = !showFavorites">
- {{ t('weather_status', 'Favorites') }}
- </ActionButton>
- <ActionButton v-for="f in displayedFavorites"
- :key="f"
- icon="icon-starred"
- @click="onFavoriteClick($event, f)">
- {{ f }}
- </ActionButton>
- </Actions>
- </div>
- </li>
+ <div id="weather-status-menu-item">
+ <NcActions class="weather-status-menu-item__subheader"
+ :aria-hidden="true"
+ :aria-label="currentWeatherMessage"
+ :menu-name="currentWeatherMessage">
+ <template #icon>
+ <NcLoadingIcon v-if="loading" />
+ <img v-else
+ :src="weatherIconUrl"
+ alt=""
+ class="weather-image">
+ </template>
+ <NcActionText v-if="gotWeather"
+ :aria-hidden="true">
+ <template #icon>
+ <NcLoadingIcon v-if="loading" />
+ <div v-else class="weather-action-image-container">
+ <img :src="futureWeatherIconUrl"
+ alt=""
+ class="weather-image">
+ </div>
+ </template>
+ {{ forecastMessage }}
+ </NcActionText>
+ <NcActionLink v-if="gotWeather"
+ target="_blank"
+ :aria-hidden="true"
+ :href="weatherLinkTarget"
+ :close-after-click="true">
+ <template #icon>
+ <NcIconSvgWrapper name="MapMarker"
+ :svg="mapMarkerSvg"
+ :size="20" />
+ </template>
+ {{ locationText }}
+ </NcActionLink>
+ <NcActionButton v-if="gotWeather"
+ :aria-hidden="true"
+ @click="onAddRemoveFavoriteClick">
+ <template #icon>
+ <NcIconSvgWrapper name="Star"
+ :svg="addRemoveFavoriteSvg"
+ :size="20"
+ class="favorite-color" />
+ </template>
+ {{ addRemoveFavoriteText }}
+ </NcActionButton>
+ <NcActionSeparator v-if="address && !errorMessage" />
+ <NcActionButton :close-after-click="true"
+ :aria-hidden="true"
+ @click="onBrowserLocationClick">
+ <template #icon>
+ <NcIconSvgWrapper name="Crosshairs"
+ :svg="crosshairsSvg"
+ :size="20" />
+ </template>
+ {{ t('weather_status', 'Detect location') }}
+ </NcActionButton>
+ <NcActionInput ref="addressInput"
+ :label="t('weather_status', 'Set custom address')"
+ :disabled="false"
+ icon="icon-rename"
+ :aria-hidden="true"
+ type="text"
+ value=""
+ @submit="onAddressSubmit" />
+ <template v-if="favorites.length > 0">
+ <NcActionCaption :name="t('weather_status', 'Favorites')" />
+ <NcActionButton v-for="favorite in favorites"
+ :key="favorite"
+ :aria-hidden="true"
+ @click="onFavoriteClick($event, favorite)">
+ <template #icon>
+ <NcIconSvgWrapper name="Star"
+ :svg="starSvg"
+ :size="20"
+ :class="{'favorite-color': address === favorite}" />
+ </template>
+ {{ favorite }}
+ </NcActionButton>
+ </template>
+ </NcActions>
+ </div>
</template>
<script>
import { showError } from '@nextcloud/dialogs'
import moment from '@nextcloud/moment'
import { getLocale } from '@nextcloud/l10n'
-import Actions from '@nextcloud/vue/dist/Components/Actions'
-import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
-import ActionInput from '@nextcloud/vue/dist/Components/ActionInput'
-import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
-import ActionSeparator from '@nextcloud/vue/dist/Components/ActionSeparator'
-import ActionText from '@nextcloud/vue/dist/Components/ActionText'
-import * as network from './services/weatherStatusService'
+import { imagePath } from '@nextcloud/router'
+import NcActions from '@nextcloud/vue/components/NcActions'
+import NcActionButton from '@nextcloud/vue/components/NcActionButton'
+import NcActionCaption from '@nextcloud/vue/components/NcActionCaption'
+import NcActionInput from '@nextcloud/vue/components/NcActionInput'
+import NcActionLink from '@nextcloud/vue/components/NcActionLink'
+import NcActionSeparator from '@nextcloud/vue/components/NcActionSeparator'
+import NcActionText from '@nextcloud/vue/components/NcActionText'
+import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
+import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
+import * as network from './services/weatherStatusService.js'
+import crosshairsSvg from '@mdi/svg/svg/crosshairs.svg?raw'
+import mapMarkerSvg from '@mdi/svg/svg/map-marker.svg?raw'
+import starSvg from '@mdi/svg/svg/star.svg?raw'
+import starOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
const MODE_BROWSER_LOCATION = 1
const MODE_MANUAL_LOCATION = 2
const weatherOptions = {
clearsky_day: {
- icon: 'icon-clearsky-day',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} clear sky later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} clear sky', { temperature, unit }),
},
clearsky_night: {
- icon: 'icon-clearsky-night',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} clear sky later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} clear sky', { temperature, unit }),
},
cloudy: {
- icon: 'icon-cloudy',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} cloudy later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} cloudy', { temperature, unit }),
},
+ snowandthunder: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow and thunder later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow and thunder', { temperature, unit }),
+ },
+ snowshowersandthunder_day: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow showers and thunder later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow showers and thunder', { temperature, unit }),
+ },
+ snowshowersandthunder_night: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow showers and thunder later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow showers and thunder', { temperature, unit }),
+ },
+ snowshowersandthunder_polartwilight: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow showers, thunder and polar twilight later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow showers, thunder and polar twilight', { temperature, unit }),
+ },
+ snowshowers_day: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow showers later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow showers', { temperature, unit }),
+ },
+ snowshowers_night: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow showers later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow showers', { temperature, unit }),
+ },
+ snowshowers_polartwilight: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow showers and polar twilight later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow showers and polar twilight', { temperature, unit }),
+ },
+ snow: {
+ text: (temperature, unit, later = false) => later
+ ? t('weather_status', '{temperature} {unit} snow later today', { temperature, unit })
+ : t('weather_status', '{temperature} {unit} snow', { temperature, unit }),
+ },
fair_day: {
- icon: 'icon-fair-day',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} fair weather later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} fair weather', { temperature, unit }),
},
fair_night: {
- icon: 'icon-fair-night',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} fair weather later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} fair weather', { temperature, unit }),
},
partlycloudy_day: {
- icon: 'icon-partlycloudy-day',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} partly cloudy later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} partly cloudy', { temperature, unit }),
},
partlycloudy_night: {
- icon: 'icon-partlycloudy-night',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} partly cloudy later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} partly cloudy', { temperature, unit }),
},
fog: {
- icon: 'icon-fog',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} foggy later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} foggy', { temperature, unit }),
},
lightrain: {
- icon: 'icon-lightrain',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rainfall later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rainfall', { temperature, unit }),
},
rain: {
- icon: 'icon-rain',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rainfall later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rainfall', { temperature, unit }),
},
heavyrain: {
- icon: 'icon-heavyrain',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rainfall later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rainfall', { temperature, unit }),
},
rainshowers_day: {
- icon: 'icon-rainshowers-day',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rainfall showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rainfall showers', { temperature, unit }),
},
rainshowers_night: {
- icon: 'icon-rainshowers-night',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rainfall showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rainfall showers', { temperature, unit }),
},
lightrainshowers_day: {
- icon: 'icon-light-rainshowers-day',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rainfall showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rainfall showers', { temperature, unit }),
},
lightrainshowers_night: {
- icon: 'icon-light-rainshowers-night',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rainfall showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rainfall showers', { temperature, unit }),
},
heavyrainshowers_day: {
- icon: 'icon-heavy-rainshowers-day',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rainfall showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rainfall showers', { temperature, unit }),
},
heavyrainshowers_night: {
- icon: 'icon-heavy-rainshowers-night',
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rainfall showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rainfall showers', { temperature, unit }),
@@ -193,16 +242,22 @@ const weatherOptions = {
export default {
name: 'App',
components: {
- Actions, ActionButton, ActionInput, ActionLink, ActionSeparator, ActionText,
- },
- props: {
- inline: {
- type: Boolean,
- default: false,
- },
+ NcActions,
+ NcActionButton,
+ NcActionCaption,
+ NcActionInput,
+ NcActionLink,
+ NcActionSeparator,
+ NcActionText,
+ NcLoadingIcon,
+ NcIconSvgWrapper,
},
data() {
return {
+ crosshairsSvg,
+ mapMarkerSvg,
+ starSvg,
+ starOutlineSvg,
locale: getLocale(),
loading: true,
errorMessage: '',
@@ -215,7 +270,6 @@ export default {
forecasts: [],
loop: null,
favorites: [],
- showFavorites: false,
}
},
computed: {
@@ -240,11 +294,11 @@ export default {
futureWeatherCode() {
return this.getWeatherCode(this.forecasts, this.offset)
},
- weatherIcon() {
- return this.getWeatherIcon(this.weatherCode, this.loading)
+ weatherIconUrl() {
+ return this.getWeatherIconUrl(this.weatherCode)
},
- futureWeatherIcon() {
- return this.getWeatherIcon(this.futureWeatherCode, this.loading)
+ futureWeatherIconUrl() {
+ return this.getWeatherIconUrl(this.futureWeatherCode)
},
/**
* The message displayed in the top right corner
@@ -256,15 +310,19 @@ export default {
return t('weather_status', 'Loading weather')
} else if (this.errorMessage) {
return this.errorMessage
- } else {
+ } else if (this.gotWeather) {
return this.getWeatherMessage(this.weatherCode, this.temperature)
+ } else {
+ return t('weather_status', 'Set location for weather')
}
},
forecastMessage() {
if (this.loading) {
return t('weather_status', 'Loading weather')
- } else {
+ } else if (this.gotWeather) {
return this.getWeatherMessage(this.futureWeatherCode, this.futureTemperature, true)
+ } else {
+ return t('weather_status', 'Set location for weather')
}
},
weatherLinkTarget() {
@@ -273,10 +331,10 @@ export default {
gotWeather() {
return this.address && !this.errorMessage
},
- addRemoveFavoriteIcon() {
+ addRemoveFavoriteSvg() {
return this.currentAddressIsFavorite
- ? 'icon-starred'
- : 'icon-star'
+ ? starSvg
+ : starOutlineSvg
},
addRemoveFavoriteText() {
return this.currentAddressIsFavorite
@@ -288,16 +346,6 @@ export default {
return f === this.address
})
},
- toggleFavoritesIcon() {
- return this.showFavorites
- ? 'icon-triangle-s'
- : 'icon-triangle-e'
- },
- displayedFavorites() {
- return this.showFavorites
- ? this.favorites
- : []
- },
},
mounted() {
this.initWeatherStatus()
@@ -495,153 +543,40 @@ export default {
getWeatherCode(forecasts, offset = 0) {
return forecasts.length > offset ? forecasts[offset].data.next_1_hours.summary.symbol_code : ''
},
- getWeatherIcon(weatherCode, loading) {
- if (loading) {
- return 'icon-loading-small'
- } else {
- return weatherCode && weatherCode in weatherOptions
- ? weatherOptions[weatherCode].icon
- : 'icon-fair-day'
- }
+ getWeatherIconUrl(weatherCode) {
+ // those icons were obtained there: https://github.com/metno/weathericons/tree/main/weather/svg
+ return (weatherCode && weatherCode in weatherOptions)
+ ? imagePath('weather_status', 'met.no.icons/' + weatherCode + '.svg')
+ : imagePath('weather_status', 'met.no.icons/fair_day.svg')
},
getWeatherMessage(weatherCode, temperature, later = false) {
return weatherCode && weatherCode in weatherOptions
? weatherOptions[weatherCode].text(
Math.round(this.getLocalizedTemperature(temperature)),
this.temperatureUnit,
- later
+ later,
)
- : t('weather_status', 'Set location for weather')
+ : t('weather_status', 'Unknown weather code')
},
},
}
</script>
<style lang="scss">
-.icon-weather-status {
- background-image: url('./../img/app-dark.svg');
-}
-body.theme--dark .icon-weather-status {
- background-image: url('./../img/app.svg');
-}
-.icon-clearsky-day {
- background-image: url('./../img/sun.svg');
+.weather-action-image-container {
+ width: var(--default-clickable-area);
+ height: var(--default-clickable-area);
+ display: flex;
+ align-items: center;
+ justify-content: center;
}
-.icon-clearsky-night {
- background-image: url('./../img/moon.svg');
-}
-.icon-cloudy {
- background-image: url('./../img/cloud-cloud.svg');
-}
-.icon-fair-day {
- background-image: url('./../img/sun-small-cloud.svg');
-}
-.icon-fair-night {
- background-image: url('./../img/moon-small-cloud.svg');
-}
-.icon-partlycloudy-day {
- background-image: url('./../img/sun-cloud.svg');
-}
-.icon-partlycloudy-night {
- background-image: url('./../img/moon-cloud.svg');
-}
-.icon-fog {
- background-image: url('./../img/fog.svg');
-}
-.icon-lightrain {
- background-image: url('./../img/light-rain.svg');
-}
-.icon-rain {
- background-image: url('./../img/rain.svg');
-}
-.icon-heavyrain {
- background-image: url('./../img/heavy-rain.svg');
-}
-.icon-light-rainshowers-day {
- background-image: url('./../img/sun-cloud-light-rain.svg');
-}
-.icon-light-rainshowers-night {
- background-image: url('./../img/moon-cloud-light-rain.svg');
-}
-.icon-rainshowers-day {
- background-image: url('./../img/sun-cloud-rain.svg');
-}
-.icon-rainshowers-night {
- background-image: url('./../img/moon-cloud-rain.svg');
-}
-.icon-heavy-rainshowers-day {
- background-image: url('./../img/sun-cloud-heavy-rain.svg');
-}
-.icon-heavy-rainshowers-night {
- background-image: url('./../img/moon-cloud-heavy-rain.svg');
-}
-.icon-crosshair {
- background-color: var(--color-main-text);
- padding: 0 !important;
- mask: url(./../img/cross.svg) no-repeat;
- mask-size: 18px 18px;
- mask-position: center;
- -webkit-mask: url(./../img/cross.svg) no-repeat;
- -webkit-mask-size: 18px 18px;
- -webkit-mask-position: center;
- min-width: 44px !important;
- min-height: 44px !important;
-}
-
-li:not(.inline) .weather-status-menu-item {
- &__header {
- display: block;
- align-items: center;
- color: var(--color-main-text);
- padding: 10px 12px 5px 12px;
- box-sizing: border-box;
- opacity: 1;
- white-space: nowrap;
- width: 100%;
- text-align: center;
- max-width: 250px;
- text-overflow: ellipsis;
- min-width: 175px;
- }
-
- &__subheader {
- width: 100%;
-
- .trigger > .icon {
- background-color: var(--color-main-background);
- background-size: 16px;
- border: 0;
- border-radius: 0;
- font-weight: normal;
- padding-left: 40px;
-
- &:hover,
- &:focus {
- box-shadow: inset 4px 0 var(--color-primary-element);
- }
- }
- }
-}
-
-.inline .weather-status-menu-item__subheader {
- width: 100%;
- .trigger > .icon {
- background-size: 16px;
- border: 0;
- border-radius: var(--border-radius-pill);
- font-weight: normal;
- padding-left: 40px;
-
- &.icon-loading-small {
- &::after {
- left: 21px;
- }
- }
- }
+.weather-image {
+ width: calc(var(--default-clickable-area) - 2 * var(--default-grid-baseline));
}
-li {
- list-style-type: none;
+// Set color to primary element for current / active favorite address
+.favorite-color {
+ color: var(--color-favorite);
}
</style>