Files

922 lines
37 KiB
Vue

<!--
- SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div id="weather-status-menu-item">
<NcActions
class="weather-status-menu-item__subheader"
: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">
<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"
:href="weatherLinkTarget"
:close-after-click="true">
<template #icon>
<NcIconSvgWrapper
name="MapMarker"
:svg="mapMarkerSvg"
:size="20" />
</template>
{{ locationText }}
</NcActionLink>
<NcActionButton
v-if="gotWeather"
@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"
@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"
type="text"
model-value=""
@submit="onAddressSubmit" />
<template v-if="favorites.length > 0">
<NcActionCaption :name="t('weather_status', 'Favorites')" />
<NcActionButton
v-for="favorite in favorites"
:key="favorite"
@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 crosshairsSvg from '@mdi/svg/svg/crosshairs.svg?raw'
import mapMarkerSvg from '@mdi/svg/svg/map-marker.svg?raw'
import starOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
import starSvg from '@mdi/svg/svg/star.svg?raw'
import { showError } from '@nextcloud/dialogs'
import { getLocale } from '@nextcloud/l10n'
import moment from '@nextcloud/moment'
import { imagePath } from '@nextcloud/router'
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 NcActions from '@nextcloud/vue/components/NcActions'
import NcActionSeparator from '@nextcloud/vue/components/NcActionSeparator'
import NcActionText from '@nextcloud/vue/components/NcActionText'
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import { logger } from './logger.ts'
import * as network from './services/weatherStatusService.js'
const MODE_BROWSER_LOCATION = 1
const MODE_MANUAL_LOCATION = 2
const weatherOptions = {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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: {
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 }),
},
clearsky_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} clear sky and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} clear sky and polar twilight', { temperature, unit }),
},
fair_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} fair weather and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} fair weather and polar twilight', { temperature, unit }),
},
partlycloudy_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} partly cloudy and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} partly cloudy and polar twilight', { temperature, unit }),
},
lightrainandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rain and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rain and thunder', { temperature, unit }),
},
rainandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rain and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rain and thunder', { temperature, unit }),
},
heavyrainandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rain and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rain and thunder', { temperature, unit }),
},
lightrainshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rainfall showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rainfall showers and thunder', { temperature, unit }),
},
lightrainshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rainfall showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rainfall showers and thunder', { temperature, unit }),
},
lightrainshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rainfall showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rainfall showers, thunder and polar twilight', { temperature, unit }),
},
rainshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rainfall showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rainfall showers and thunder', { temperature, unit }),
},
rainshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rainfall showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rainfall showers and thunder', { temperature, unit }),
},
rainshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rainfall showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rainfall showers, thunder and polar twilight', { temperature, unit }),
},
heavyrainshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rainfall showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rainfall showers and thunder', { temperature, unit }),
},
heavyrainshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rainfall showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rainfall showers and thunder', { temperature, unit }),
},
heavyrainshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rainfall showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rainfall showers, thunder and polar twilight', { temperature, unit }),
},
lightrainshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light rainfall showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light rainfall showers and polar twilight', { temperature, unit }),
},
rainshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} rainfall showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} rainfall showers and polar twilight', { temperature, unit }),
},
heavyrainshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy rainfall showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy rainfall showers and polar twilight', { temperature, unit }),
},
lightsleet: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet', { temperature, unit }),
},
sleet: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet', { temperature, unit }),
},
heavysleet: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet', { temperature, unit }),
},
lightsleetandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet and thunder', { temperature, unit }),
},
sleetandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet and thunder', { temperature, unit }),
},
heavysleetandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet and thunder', { temperature, unit }),
},
lightsleetshowers_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet showers', { temperature, unit }),
},
lightsleetshowers_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet showers', { temperature, unit }),
},
lightsleetshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet showers and polar twilight', { temperature, unit }),
},
sleetshowers_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet showers', { temperature, unit }),
},
sleetshowers_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet showers', { temperature, unit }),
},
sleetshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet showers and polar twilight', { temperature, unit }),
},
heavysleetshowers_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet showers', { temperature, unit }),
},
heavysleetshowers_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet showers', { temperature, unit }),
},
heavysleetshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet showers and polar twilight', { temperature, unit }),
},
lightssleetshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet showers and thunder', { temperature, unit }),
},
lightssleetshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet showers and thunder', { temperature, unit }),
},
lightssleetshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light sleet showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light sleet showers, thunder and polar twilight', { temperature, unit }),
},
sleetshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet showers and thunder', { temperature, unit }),
},
sleetshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet showers and thunder', { temperature, unit }),
},
sleetshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} sleet showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} sleet showers, thunder and polar twilight', { temperature, unit }),
},
heavysleetshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet showers and thunder', { temperature, unit }),
},
heavysleetshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet showers and thunder', { temperature, unit }),
},
heavysleetshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy sleet showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy sleet showers, thunder and polar twilight', { temperature, unit }),
},
lightsnow: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow', { temperature, unit }),
},
heavysnow: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow', { temperature, unit }),
},
lightsnowandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow and thunder', { temperature, unit }),
},
heavysnowandthunder: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow and thunder', { temperature, unit }),
},
lightsnowshowers_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow showers', { temperature, unit }),
},
lightsnowshowers_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow showers', { temperature, unit }),
},
lightsnowshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow showers and polar twilight', { temperature, unit }),
},
heavysnowshowers_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow showers', { temperature, unit }),
},
heavysnowshowers_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow showers later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow showers', { temperature, unit }),
},
heavysnowshowers_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow showers and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow showers and polar twilight', { temperature, unit }),
},
lightssnowshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow showers and thunder', { temperature, unit }),
},
lightssnowshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow showers and thunder', { temperature, unit }),
},
lightssnowshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} light snow showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} light snow showers, thunder and polar twilight', { temperature, unit }),
},
heavysnowshowersandthunder_day: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow showers and thunder', { temperature, unit }),
},
heavysnowshowersandthunder_night: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow showers and thunder later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow showers and thunder', { temperature, unit }),
},
heavysnowshowersandthunder_polartwilight: {
text: (temperature, unit, later = false) => later
? t('weather_status', '{temperature} {unit} heavy snow showers, thunder and polar twilight later today', { temperature, unit })
: t('weather_status', '{temperature} {unit} heavy snow showers, thunder and polar twilight', { temperature, unit }),
},
}
export default {
name: 'App',
components: {
NcActions,
NcActionButton,
NcActionCaption,
NcActionInput,
NcActionLink,
NcActionSeparator,
NcActionText,
NcLoadingIcon,
NcIconSvgWrapper,
},
data() {
return {
crosshairsSvg,
mapMarkerSvg,
starSvg,
starOutlineSvg,
locale: getLocale(),
loading: true,
errorMessage: '',
mode: MODE_BROWSER_LOCATION,
address: null,
lat: null,
lon: null,
// how many hours ahead do we want to see the forecast?
offset: 5,
forecasts: [],
loop: null,
favorites: [],
}
},
computed: {
useFahrenheitLocale() {
return ['en_US', 'en_MH', 'en_FM', 'en_PW', 'en_KY', 'en_LR'].includes(this.locale)
},
temperatureUnit() {
return this.useFahrenheitLocale ? '°F' : '°C'
},
locationText() {
return t('weather_status', 'More weather for {adr}', { adr: this.address })
},
temperature() {
return this.getTemperature(this.forecasts, 0)
},
futureTemperature() {
return this.getTemperature(this.forecasts, this.offset)
},
weatherCode() {
return this.getWeatherCode(this.forecasts, 0)
},
futureWeatherCode() {
return this.getWeatherCode(this.forecasts, this.offset)
},
weatherIconUrl() {
return this.getWeatherIconUrl(this.weatherCode)
},
futureWeatherIconUrl() {
return this.getWeatherIconUrl(this.futureWeatherCode)
},
/**
* The message displayed in the top right corner
*
* @return {string}
*/
currentWeatherMessage() {
if (this.loading) {
return t('weather_status', 'Loading weather')
} else if (this.errorMessage) {
return this.errorMessage
} 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 if (this.gotWeather) {
return this.getWeatherMessage(this.futureWeatherCode, this.futureTemperature, true)
} else {
return t('weather_status', 'Set location for weather')
}
},
weatherLinkTarget() {
return 'https://www.windy.com/-Rain-thunder-rain?rain,' + this.lat + ',' + this.lon + ',11'
},
gotWeather() {
return this.address && !this.errorMessage
},
addRemoveFavoriteSvg() {
return this.currentAddressIsFavorite
? starSvg
: starOutlineSvg
},
addRemoveFavoriteText() {
return this.currentAddressIsFavorite
? t('weather_status', 'Remove from favorites')
: t('weather_status', 'Add as favorite')
},
currentAddressIsFavorite() {
return this.favorites.find((f) => {
return f === this.address
})
},
},
mounted() {
this.initWeatherStatus()
},
methods: {
async initWeatherStatus() {
try {
const loc = await network.getLocation()
this.lat = loc.lat
this.lon = loc.lon
this.address = loc.address
this.mode = loc.mode
if (this.mode === MODE_BROWSER_LOCATION) {
this.askBrowserLocation()
} else if (this.mode === MODE_MANUAL_LOCATION) {
this.startLoop()
}
const favs = await network.getFavorites()
this.favorites = favs
} catch (err) {
if (err?.code === 'ECONNABORTED') {
logger.info('The weather status request was cancelled because the user navigates.')
return
}
if (err.response && err.response.status === 401) {
showError(t('weather_status', 'You are not logged in.'))
} else {
showError(t('weather_status', 'There was an error getting the weather status information.'))
}
logger.error(err)
}
},
startLoop() {
clearInterval(this.loop)
if (this.lat && this.lon) {
this.loop = setInterval(() => this.getForecast(), 60 * 1000 * 60)
this.getForecast()
} else {
this.loading = false
}
},
askBrowserLocation() {
this.loading = true
this.errorMessage = ''
if (navigator.geolocation && window.isSecureContext) {
navigator.geolocation.getCurrentPosition(
(position) => {
logger.debug('browser location success')
this.lat = position.coords.latitude
this.lon = position.coords.longitude
this.saveMode(MODE_BROWSER_LOCATION)
this.mode = MODE_BROWSER_LOCATION
this.saveLocation(this.lat, this.lon)
},
(error) => {
logger.debug('location permission refused')
logger.debug(error)
this.saveMode(MODE_MANUAL_LOCATION)
this.mode = MODE_MANUAL_LOCATION
// fallback on what we have if possible
if (this.lat && this.lon) {
this.startLoop()
} else {
this.usePersonalAddress()
}
},
)
} else {
logger.debug('no secure context!')
this.saveMode(MODE_MANUAL_LOCATION)
this.mode = MODE_MANUAL_LOCATION
this.startLoop()
}
},
async getForecast() {
try {
this.forecasts = await network.fetchForecast()
} catch (err) {
this.errorMessage = t('weather_status', 'No weather information found')
logger.debug(err)
}
this.loading = false
},
async setAddress(address) {
this.loading = true
this.errorMessage = ''
try {
const loc = await network.setAddress(address)
if (loc.success) {
this.lat = loc.lat
this.lon = loc.lon
this.address = loc.address
this.mode = MODE_MANUAL_LOCATION
this.startLoop()
} else {
this.errorMessage = t('weather_status', 'Location not found')
this.loading = false
}
} catch (err) {
if (err.response && err.response.status === 401) {
showError(t('weather_status', 'You are not logged in.'))
} else {
showError(t('weather_status', 'There was an error setting the location address.'))
}
this.loading = false
}
},
async saveLocation(lat, lon) {
try {
const loc = await network.setLocation(lat, lon)
this.address = loc.address
this.startLoop()
} catch (err) {
if (err.response && err.response.status === 401) {
showError(t('weather_status', 'You are not logged in.'))
} else {
showError(t('weather_status', 'There was an error setting the location.'))
}
logger.debug(err)
}
},
async saveMode(mode) {
try {
await network.setMode(mode)
} catch (err) {
if (err.response && err.response.status === 401) {
showError(t('weather_status', 'You are not logged in.'))
} else {
showError(t('weather_status', 'There was an error saving the mode.'))
}
logger.debug(err)
}
},
onBrowserLocationClick() {
this.askBrowserLocation()
},
async usePersonalAddress() {
this.loading = true
try {
const loc = await network.usePersonalAddress()
this.lat = loc.lat
this.lon = loc.lon
this.address = loc.address
this.mode = MODE_MANUAL_LOCATION
this.startLoop()
} catch (err) {
if (err.response && err.response.status === 401) {
showError(t('weather_status', 'You are not logged in.'))
} else {
showError(t('weather_status', 'There was an error using personal address.'))
}
logger.debug(err)
this.loading = false
}
},
onAddressSubmit() {
const newAddress = this.$refs.addressInput.$el.querySelector('input[type="text"]').value
this.setAddress(newAddress)
},
getLocalizedTemperature(celcius) {
return this.useFahrenheitLocale
? (celcius * (9 / 5)) + 32
: celcius
},
onAddRemoveFavoriteClick() {
const currentIsFavorite = this.currentAddressIsFavorite
if (currentIsFavorite) {
const i = this.favorites.indexOf(currentIsFavorite)
if (i !== -1) {
this.favorites.splice(i, 1)
}
} else {
this.favorites.push(this.address)
}
network.saveFavorites(this.favorites)
},
onFavoriteClick(e, favAddress) {
// clicked on the icon
if (e.target.classList.contains('action-button__icon')) {
const i = this.favorites.indexOf(favAddress)
if (i !== -1) {
this.favorites.splice(i, 1)
}
network.saveFavorites(this.favorites)
} else if (favAddress !== this.address) {
// clicked on the text
this.setAddress(favAddress)
}
},
formatTime(time) {
return moment(time).format('LT')
},
getTemperature(forecasts, offset = 0) {
return forecasts.length > offset ? forecasts[offset].data.instant.details.air_temperature : ''
},
getWeatherCode(forecasts, offset = 0) {
return forecasts.length > offset ? forecasts[offset].data.next_1_hours.summary.symbol_code : ''
},
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,
)
: t('weather_status', 'Unknown weather code')
},
},
}
</script>
<style lang="scss">
.icon-weather-status {
background-image: url('../img/app-dark.svg');
}
.weather-action-image-container {
width: var(--default-clickable-area);
height: var(--default-clickable-area);
display: flex;
align-items: center;
justify-content: center;
}
.weather-image {
width: calc(var(--default-clickable-area) - 2 * var(--default-grid-baseline));
}
// Set color to primary element for current / active favorite address
.favorite-color {
color: var(--color-favorite);
}
</style>