Convert all view components to use Composition API

might as well start getting used to this new hotness
This commit is contained in:
Lance Edgar 2024-06-09 15:45:38 -05:00
parent 5e238aa2aa
commit 7a14101e01
6 changed files with 191 additions and 235 deletions

View file

@ -2,17 +2,6 @@
import appsettings from '../appsettings' import appsettings from '../appsettings'
</script> </script>
<script>
export default {
data() {
return {
appsettings,
}
},
}
</script>
<template> <template>
<div class="about"> <div class="about">
<h4 class="is-size-4">{{ appsettings.appTitle }} {{ appsettings.appVersion }}</h4> <h4 class="is-size-4">{{ appsettings.appTitle }} {{ appsettings.appVersion }}</h4>

View file

@ -1,19 +1,13 @@
<script setup> <script setup>
import { mapStores } from 'pinia' import { onActivated } from 'vue'
import { useWeatherStore } from '../stores/weather' import { useWeatherStore } from '../stores/weather'
</script>
<script> const weatherStore = useWeatherStore()
export default {
computed: { onActivated(() => {
...mapStores(useWeatherStore), weatherStore.getWeather()
}, })
activated() {
this.weatherStore.getWeather()
},
}
</script> </script>
<template> <template>

View file

@ -1,22 +1,12 @@
<script setup> <script setup>
import { mapStores } from 'pinia'
import { useLocationStore } from '../stores/location' import { useLocationStore } from '../stores/location'
</script>
<script> const locationStore = useLocationStore()
export default {
computed: { function deleteLocation(location) {
...mapStores(useLocationStore), locationStore.removeLocation(location)
},
methods: {
deleteLocation(location) {
this.locationStore.removeLocation(location)
},
},
} }
</script> </script>
<template> <template>

View file

@ -1,77 +1,75 @@
<script setup> <script setup>
import { mapStores } from 'pinia' import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useWeatherStore } from '../stores/weather' import { useWeatherStore } from '../stores/weather'
import { useLocationStore } from '../stores/location' import { useLocationStore } from '../stores/location'
</script> import { useOruga } from '@oruga-ui/oruga-next'
<script>
export default {
data() { const router = useRouter()
return { const locationStore = useLocationStore()
coordinates: null, const weatherStore = useWeatherStore()
loading: false, const oruga = useOruga()
locationAccessBlocked: false,
}
},
computed: { const coordinates = ref(null)
...mapStores(useWeatherStore, useLocationStore), const coordinatesInput = ref()
}, const loading = ref(false)
const locationAccessBlocked = ref(false)
methods: {
useCurrentLocation() { function useCurrentLocation() {
if (this.locationAccessBlocked) { if (locationAccessBlocked.value) {
alert("You must refresh the page first, then try again.") alert("You must refresh the page first, then try again.")
return return
} }
navigator.geolocation.getCurrentPosition(loc => { navigator.geolocation.getCurrentPosition(loc => {
this.coordinates = `${loc.coords.latitude},${loc.coords.longitude}` coordinates.value = `${loc.coords.latitude},${loc.coords.longitude}`
this.loadCoordinates() loadCoordinates()
}, error => { }, error => {
if (error.code == 1) { // PERMISSION_DENIED if (error.code == 1) { // PERMISSION_DENIED
this.locationAccessBlocked = true locationAccessBlocked.value = true
} }
alert(`error.code = ${error.code}\n\n${error.message}`) alert(`error.code = ${error.code}\n\n${error.message}`)
}) })
}, }
editLocations() {
this.$router.push('/edit-list')
},
async loadCoordinates() { function editLocations() {
if (!this.coordinates) { router.push('/edit-list')
this.$refs.coordinates.focus() }
async function loadCoordinates() {
if (!coordinates.value) {
coordinatesInput.value.focus()
return return
} }
const parts = this.coordinates.split(/(?: +| *\, *)/) const parts = coordinates.value.split(/(?: +| *\, *)/)
const pattern = /^ *-?\d+(?:\.\d+)? *$/ const pattern = /^ *-?\d+(?:\.\d+)? *$/
if (parts.length != 2 if (parts.length != 2
|| !parts[0].match(pattern) || !parts[0].match(pattern)
|| !parts[1].match(pattern)) { || !parts[1].match(pattern)) {
this.$oruga.notification.open({ oruga.notification.open({
variant: 'warning', variant: 'warning',
message: "Coordinates are not valid.", message: "Coordinates are not valid.",
position: 'bottom', position: 'bottom',
}) })
this.$refs.coordinates.focus() coordinatesInput.value.focus()
return return
} }
this.coordinates = `${parts[0]},${parts[1]}` coordinates.value = `${parts[0]},${parts[1]}`
this.loading = true loading.value = true
const url = `https://api.weather.gov/points/${this.coordinates}` const url = `https://api.weather.gov/points/${coordinates.value}`
const response = await fetch(url) const response = await fetch(url)
const weather = await response.json() const weather = await response.json()
this.loading = false loading.value = false
if (weather.status == 404) { if (weather.status == 404) {
this.$oruga.notification.open({ oruga.notification.open({
variant: 'warning', variant: 'warning',
message: weather.title || "Data not found!", message: weather.title || "Data not found!",
position: 'bottom', position: 'bottom',
@ -86,24 +84,24 @@ export default {
const state = weather.properties.relativeLocation.properties.state const state = weather.properties.relativeLocation.properties.state
const cityState = `${city}, ${state}` const cityState = `${city}, ${state}`
this.locationStore.addLocation(coords, cityState) locationStore.addLocation(coords, cityState)
this.weatherStore.setCoordinates(coords) weatherStore.setCoordinates(coords)
this.weatherStore.setCityState(cityState) weatherStore.setCityState(cityState)
this.weatherStore.setWeather(weather) weatherStore.setWeather(weather)
// clear this so user sees empty input when they return // clear this so user sees empty input when they return
this.coordinates = null coordinates.value = null
this.$router.push('/weather') router.push('/weather')
},
showWeather(location) {
this.weatherStore.clearWeather()
this.weatherStore.setCoordinates(location.coordinates)
this.weatherStore.setCityState(location.cityState)
this.$router.push('/weather')
},
},
} }
function showWeather(location) {
weatherStore.clearWeather()
weatherStore.setCoordinates(location.coordinates)
weatherStore.setCityState(location.cityState)
router.push('/weather')
}
</script> </script>
<template> <template>
@ -112,7 +110,7 @@ export default {
<o-field grouped> <o-field grouped>
<o-input v-model="coordinates" <o-input v-model="coordinates"
ref="coordinates" ref="coordinatesInput"
placeholder="coordinates" placeholder="coordinates"
clearable /> clearable />
<o-button variant="primary" <o-button variant="primary"

View file

@ -1,45 +1,34 @@
<script setup> <script setup>
import { mapStores } from 'pinia' import { ref, onActivated } from 'vue'
import { useWeatherStore } from '../stores/weather' import { useWeatherStore } from '../stores/weather'
</script>
<script>
export default {
data() { const weatherStore = useWeatherStore()
return {
coordinates: null, const coordinates = ref(null)
hourly: null, const hourly = ref(null)
chunks: [], const chunks = ref([])
onActivated(() => {
if (coordinates.value != weatherStore.coordinates) {
hourly.value = null
chunks.value = []
fetchHourly()
} }
}, })
computed: { async function fetchHourly() {
...mapStores(useWeatherStore),
},
activated() { const weather = await weatherStore.getWeather()
if (this.coordinates != this.weatherStore.coordinates) { coordinates.value = weatherStore.coordinates
this.hourly = null
this.chunks = []
this.fetchHourly()
}
},
methods: {
async fetchHourly() {
const weather = await this.weatherStore.getWeather()
this.coordinates = this.weatherStore.coordinates
const url = weather.properties.forecastHourly const url = weather.properties.forecastHourly
const response = await fetch(url) const response = await fetch(url)
this.hourly = await response.json() hourly.value = await response.json()
this.chunks = [] chunks.value = []
let chunk = null let chunk = null
for (let period of this.hourly.properties.periods.slice(0, 12)) { for (let period of hourly.value.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',
}) })
@ -48,18 +37,17 @@ export default {
date, date,
periods: [], periods: [],
} }
this.chunks.push(chunk) chunks.value.push(chunk)
} }
chunk.periods.push(period) chunk.periods.push(period)
} }
}, }
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'})
},
},
} }
</script> </script>
<template> <template>

View file

@ -1,66 +1,63 @@
<script setup> <script setup>
import { mapStores } from 'pinia' import { ref, computed, onActivated } from 'vue'
import { useRouter } from 'vue-router'
import { useWeatherStore } from '../stores/weather' import { useWeatherStore } from '../stores/weather'
import { useLocationStore } from '../stores/location' import { useLocationStore } from '../stores/location'
</script>
<script>
export default {
data() { const router = useRouter()
return { const locationStore = useLocationStore()
coordinates: null, const weatherStore = useWeatherStore()
alerts: null,
}
},
computed: { const coordinates = ref(null)
...mapStores(useWeatherStore, useLocationStore), const alerts = ref(null)
panelHeadingTitle() {
if (!this.weatherStore.forecast) { const panelHeadingTitle = computed(() => {
if (!weatherStore.forecast) {
return "Forecast" return "Forecast"
} }
let generated = new Date(this.weatherStore.forecast.properties.generatedAt) let generated = new Date(weatherStore.forecast.properties.generatedAt)
generated = generated.toLocaleTimeString('en-US', {timeStyle: 'short'}) generated = generated.toLocaleTimeString('en-US', {timeStyle: 'short'})
return `Forecast @ ${generated}` return `Forecast @ ${generated}`
}, })
},
activated() {
this.fetchWeather()
},
methods: { onActivated(() => {
fetchWeather()
})
coordinatesUpdated(coordinates) {
this.weatherStore.clearWeather()
this.weatherStore.setCoordinates(coordinates)
this.fetchWeather()
},
async fetchWeather() { function coordinatesUpdated(coords) {
weatherStore.clearWeather()
weatherStore.setCoordinates(coords)
fetchWeather()
}
if (!this.weatherStore.coordinates) {
this.$router.push('/') async function fetchWeather() {
if (!weatherStore.coordinates) {
router.push('/')
return return
} }
const forecast = await this.weatherStore.getForecast() const forecast = await weatherStore.getForecast()
this.coordinates = this.weatherStore.coordinates coordinates.value = weatherStore.coordinates
this.alerts = this.weatherStore.alerts alerts.value = weatherStore.alerts
},
getShortForecast(period) {
return period.shortForecast.replace(/Showers And Thunderstorms/g, 'T-storms')
},
showHourly(period) {
this.$router.push('/hourly')
},
},
} }
function getShortForecast(period) {
return period.shortForecast.replace(/Showers And Thunderstorms/g, 'T-storms')
}
function showHourly(period) {
router.push('/hourly')
}
</script> </script>
<template> <template>