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'
</script>
<script>
export default {
data() {
return {
appsettings,
}
},
}
</script>
<template>
<div class="about">
<h4 class="is-size-4">{{ appsettings.appTitle }} {{ appsettings.appVersion }}</h4>

View file

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

View file

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

View file

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

View file

@ -1,65 +1,53 @@
<script setup>
import { mapStores } from 'pinia'
import { ref, onActivated } from 'vue'
import { useWeatherStore } from '../stores/weather'
</script>
<script>
export default {
data() {
return {
coordinates: null,
hourly: null,
chunks: [],
}
},
const weatherStore = useWeatherStore()
computed: {
...mapStores(useWeatherStore),
},
const coordinates = ref(null)
const hourly = ref(null)
const chunks = ref([])
activated() {
if (this.coordinates != this.weatherStore.coordinates) {
this.hourly = null
this.chunks = []
this.fetchHourly()
}
},
onActivated(() => {
if (coordinates.value != weatherStore.coordinates) {
hourly.value = null
chunks.value = []
fetchHourly()
}
})
methods: {
async function fetchHourly() {
async fetchHourly() {
const weather = await weatherStore.getWeather()
coordinates.value = weatherStore.coordinates
const weather = await this.weatherStore.getWeather()
this.coordinates = this.weatherStore.coordinates
const url = weather.properties.forecastHourly
const response = await fetch(url)
hourly.value = await response.json()
const url = weather.properties.forecastHourly
const response = await fetch(url)
this.hourly = await response.json()
this.chunks = []
let chunk = null
for (let period of this.hourly.properties.periods.slice(0, 12)) {
const date = new Date(period.startTime).toLocaleDateString('en-US', {
dateStyle: 'full',
})
if (!chunk || chunk.date != date) {
chunk = {
date,
periods: [],
}
this.chunks.push(chunk)
}
chunk.periods.push(period)
chunks.value = []
let chunk = null
for (let period of hourly.value.properties.periods.slice(0, 12)) {
const date = new Date(period.startTime).toLocaleDateString('en-US', {
dateStyle: 'full',
})
if (!chunk || chunk.date != date) {
chunk = {
date,
periods: [],
}
},
renderTime(period) {
const date = new Date(period.startTime)
return date.toLocaleTimeString('en-US', {timeStyle: 'short'})
},
},
chunks.value.push(chunk)
}
chunk.periods.push(period)
}
}
function renderTime(period) {
const date = new Date(period.startTime)
return date.toLocaleTimeString('en-US', {timeStyle: 'short'})
}
</script>
<template>

View file

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