Add refresh buttons to weather data pages
This commit is contained in:
parent
7a14101e01
commit
a1f84465cc
4 changed files with 106 additions and 43 deletions
|
@ -26,9 +26,11 @@ export const useWeatherStore = defineStore('weather', {
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
clearWeather() {
|
clearWeather(keepCoordinates) {
|
||||||
this.setCoordinates(null)
|
if (!keepCoordinates) {
|
||||||
this.setCityState(null)
|
this.setCoordinates(null)
|
||||||
|
this.setCityState(null)
|
||||||
|
}
|
||||||
this.setWeather(null)
|
this.setWeather(null)
|
||||||
this.setForecast(null)
|
this.setForecast(null)
|
||||||
this.radarLatestURL = null
|
this.radarLatestURL = null
|
||||||
|
@ -103,10 +105,10 @@ export const useWeatherStore = defineStore('weather', {
|
||||||
// put "likely" before "possible" alerts
|
// put "likely" before "possible" alerts
|
||||||
newAlerts.features.sort((a, b) => {
|
newAlerts.features.sort((a, b) => {
|
||||||
|
|
||||||
if (a.properties.certainty == 'Likely' && b.properties.certainty == 'Possible') {
|
if (a.properties.certainty == 'Likely' && b.properties.certainty != 'Likely') {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
if (a.properties.certainty == 'Possible' && b.properties.certainty == 'Likely') {
|
if (a.properties.certainty != 'Likely' && b.properties.certainty == 'Likely') {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,44 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onActivated } from 'vue'
|
import { ref, onActivated } from 'vue'
|
||||||
import { useWeatherStore } from '../stores/weather'
|
import { useWeatherStore } from '../stores/weather'
|
||||||
|
|
||||||
const weatherStore = useWeatherStore()
|
const weatherStore = useWeatherStore()
|
||||||
|
|
||||||
|
const refreshing = ref(false)
|
||||||
|
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
weatherStore.getWeather()
|
refreshing.value = true
|
||||||
|
weatherStore.getWeather().then(() => {
|
||||||
|
refreshing.value = false
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
async function refreshAlerts() {
|
||||||
|
refreshing.value = true
|
||||||
|
weatherStore.clearWeather(true)
|
||||||
|
await weatherStore.getWeather()
|
||||||
|
refreshing.value = false
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<o-button variant="primary"
|
<div class="block"
|
||||||
size="small"
|
style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
icon-left="arrow-left"
|
<o-button variant="primary"
|
||||||
@click="$router.push('/weather')">
|
icon-left="arrow-left"
|
||||||
Back
|
@click="$router.push('/weather')">
|
||||||
</o-button>
|
Back
|
||||||
|
</o-button>
|
||||||
|
<o-button variant="primary"
|
||||||
|
icon-left="refresh"
|
||||||
|
@click="refreshAlerts()"
|
||||||
|
:disabled="refreshing">
|
||||||
|
{{ refreshing ? "Refreshing" : "Refresh" }}
|
||||||
|
</o-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h5 class="is-size-5">{{ weatherStore.cityState }}</h5>
|
<h5 class="is-size-5">{{ weatherStore.cityState }}</h5>
|
||||||
<h5 class="is-size-5">Alerts</h5>
|
<h5 class="is-size-5">Alerts</h5>
|
||||||
|
|
|
@ -6,14 +6,17 @@ import { useWeatherStore } from '../stores/weather'
|
||||||
const weatherStore = useWeatherStore()
|
const weatherStore = useWeatherStore()
|
||||||
|
|
||||||
const coordinates = ref(null)
|
const coordinates = ref(null)
|
||||||
const hourly = ref(null)
|
|
||||||
const chunks = ref([])
|
const chunks = ref([])
|
||||||
|
const refreshing = ref(false)
|
||||||
|
|
||||||
|
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
if (coordinates.value != weatherStore.coordinates) {
|
if (coordinates.value != weatherStore.coordinates) {
|
||||||
hourly.value = null
|
refreshing.value = true
|
||||||
chunks.value = []
|
chunks.value = []
|
||||||
fetchHourly()
|
fetchHourly().then(() => {
|
||||||
|
refreshing.value = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -24,11 +27,11 @@ async function fetchHourly() {
|
||||||
|
|
||||||
const url = weather.properties.forecastHourly
|
const url = weather.properties.forecastHourly
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
hourly.value = await response.json()
|
const hourly = await response.json()
|
||||||
|
|
||||||
chunks.value = []
|
chunks.value = []
|
||||||
let chunk = null
|
let chunk = null
|
||||||
for (let period of hourly.value.properties.periods.slice(0, 12)) {
|
for (let period of hourly.properties.periods.slice(0, 12)) {
|
||||||
const date = new Date(period.startTime).toLocaleDateString('en-US', {
|
const date = new Date(period.startTime).toLocaleDateString('en-US', {
|
||||||
dateStyle: 'full',
|
dateStyle: 'full',
|
||||||
})
|
})
|
||||||
|
@ -43,6 +46,16 @@ async function fetchHourly() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function refreshHourly() {
|
||||||
|
refreshing.value = true
|
||||||
|
weatherStore.clearWeather(true)
|
||||||
|
chunks.value = []
|
||||||
|
await fetchHourly()
|
||||||
|
refreshing.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function renderTime(period) {
|
function renderTime(period) {
|
||||||
const date = new Date(period.startTime)
|
const date = new Date(period.startTime)
|
||||||
return date.toLocaleTimeString('en-US', {timeStyle: 'short'})
|
return date.toLocaleTimeString('en-US', {timeStyle: 'short'})
|
||||||
|
@ -53,12 +66,20 @@ function renderTime(period) {
|
||||||
<template>
|
<template>
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<o-button variant="primary"
|
<div class="block"
|
||||||
size="small"
|
style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
icon-left="arrow-left"
|
<o-button variant="primary"
|
||||||
@click="$router.push('/weather')">
|
icon-left="arrow-left"
|
||||||
Back
|
@click="$router.push('/weather')">
|
||||||
</o-button>
|
Back
|
||||||
|
</o-button>
|
||||||
|
<o-button variant="primary"
|
||||||
|
icon-left="refresh"
|
||||||
|
@click="refreshHourly()"
|
||||||
|
:disabled="refreshing">
|
||||||
|
{{ refreshing ? "Refreshing" : "Refresh" }}
|
||||||
|
</o-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h5 class="is-size-5">{{ weatherStore.cityState }}</h5>
|
<h5 class="is-size-5">{{ weatherStore.cityState }}</h5>
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -10,7 +10,7 @@ const locationStore = useLocationStore()
|
||||||
const weatherStore = useWeatherStore()
|
const weatherStore = useWeatherStore()
|
||||||
|
|
||||||
const coordinates = ref(null)
|
const coordinates = ref(null)
|
||||||
const alerts = ref(null)
|
const refreshing = ref(false)
|
||||||
|
|
||||||
|
|
||||||
const panelHeadingTitle = computed(() => {
|
const panelHeadingTitle = computed(() => {
|
||||||
|
@ -25,27 +25,39 @@ const panelHeadingTitle = computed(() => {
|
||||||
|
|
||||||
|
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
fetchWeather()
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
function coordinatesUpdated(coords) {
|
|
||||||
weatherStore.clearWeather()
|
|
||||||
weatherStore.setCoordinates(coords)
|
|
||||||
fetchWeather()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function fetchWeather() {
|
|
||||||
|
|
||||||
if (!weatherStore.coordinates) {
|
if (!weatherStore.coordinates) {
|
||||||
router.push('/')
|
router.push('/')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const forecast = await weatherStore.getForecast()
|
refreshing.value = true
|
||||||
|
fetchWeather().then(() => {
|
||||||
|
refreshing.value = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
async function coordinatesUpdated(coords) {
|
||||||
|
refreshing.value = true
|
||||||
|
weatherStore.clearWeather()
|
||||||
|
weatherStore.setCoordinates(coords)
|
||||||
|
await fetchWeather()
|
||||||
|
refreshing.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function fetchWeather() {
|
||||||
|
await weatherStore.getForecast()
|
||||||
coordinates.value = weatherStore.coordinates
|
coordinates.value = weatherStore.coordinates
|
||||||
alerts.value = weatherStore.alerts
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function refreshWeather() {
|
||||||
|
refreshing.value = true
|
||||||
|
weatherStore.clearWeather(true)
|
||||||
|
await fetchWeather()
|
||||||
|
refreshing.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,7 +76,8 @@ function showHourly(period) {
|
||||||
<main>
|
<main>
|
||||||
<div style="display: flex; flex-direction: column;">
|
<div style="display: flex; flex-direction: column;">
|
||||||
|
|
||||||
<o-field>
|
<div class="block"
|
||||||
|
style="display: flex; justify-content: space-between; align-items: center;">
|
||||||
<o-select v-if="weatherStore.weather"
|
<o-select v-if="weatherStore.weather"
|
||||||
v-model="coordinates"
|
v-model="coordinates"
|
||||||
@update:model-value="coordinatesUpdated">
|
@update:model-value="coordinatesUpdated">
|
||||||
|
@ -74,15 +87,21 @@ function showHourly(period) {
|
||||||
{{ location.cityState }}
|
{{ location.cityState }}
|
||||||
</option>
|
</option>
|
||||||
</o-select>
|
</o-select>
|
||||||
</o-field>
|
<o-button variant="primary"
|
||||||
|
icon-left="refresh"
|
||||||
|
@click="refreshWeather()"
|
||||||
|
:disabled="refreshing">
|
||||||
|
{{ refreshing ? "Refreshing" : "Refresh" }}
|
||||||
|
</o-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="alerts?.features?.length">
|
<div v-if="weatherStore.alerts?.features?.length">
|
||||||
<o-notification variant="warning"
|
<o-notification variant="warning"
|
||||||
icon="warning"
|
icon="warning"
|
||||||
@click="$router.push('/alerts')"
|
@click="$router.push('/alerts')"
|
||||||
style="cursor: pointer;">
|
style="cursor: pointer;">
|
||||||
<p class="has-text-weight-bold">Watches In Effect</p>
|
<p class="has-text-weight-bold">Watches In Effect</p>
|
||||||
<p>Updated {{ new Date(alerts.updated).toLocaleTimeString('en-US', {timeStyle: 'short'}) }}</p>
|
<p>Updated {{ new Date(weatherStore.alerts.updated).toLocaleTimeString('en-US', {timeStyle: 'short'}) }}</p>
|
||||||
</o-notification>
|
</o-notification>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -101,6 +120,7 @@ function showHourly(period) {
|
||||||
:key="period.number"
|
:key="period.number"
|
||||||
class="weather-period is-size-7 has-text-weight-bold"
|
class="weather-period is-size-7 has-text-weight-bold"
|
||||||
:class="{daytime: period.isDaytime}"
|
:class="{daytime: period.isDaytime}"
|
||||||
|
style="cursor: pointer;"
|
||||||
@click="showHourly(period)">
|
@click="showHourly(period)">
|
||||||
|
|
||||||
<p>{{ period.name }}</p>
|
<p>{{ period.name }}</p>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue