Skip to content

Commit

Permalink
Merge pull request #21 from fredrikburmester/develop
Browse files Browse the repository at this point in the history
Weather widget
  • Loading branch information
fredrikburmester authored Nov 1, 2022
2 parents 858ac3a + 96e51e0 commit 2187217
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 27 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Current features:

The plex widget enables you to see current streams on your server. Due to SSL certificates you'll need to supply a SSL certified Plex domain like `https://plex.domain.com`, or if you host this startpage without SSL you can just supply the external IP address and port of your Plex server like so: `http://<EXTERNAL_IP>:32400`.

### Weather

![Weather](assets/weather-widget.png)

The weather widget enables you to see the current weather. The weather is fetched from [OpenWeatherMap](https://openweathermap.org/). You'll need to supply an API key from OpenWeatherMap long and lat coordinates.

## 🐞 Bugs

Sometimes all it takes is a reload of the page to fix!
Expand Down Expand Up @@ -88,8 +94,4 @@ Locally preview production build:

```bash
yarn preview
```




```
Binary file added assets/weather-widget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 46 additions & 8 deletions components/AddLinkButtonModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
<input type="checkbox" id="my-modal-6" class="modal-toggle" @click="disableEdit"/>
<div class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<h3 class="font-bold text-lg">Add a link button</h3>
<p class="py-4">Here you can add a new button with any link, text and color you want. Make sure the link starts with
<code class="bg-primary rounded p-1 text-sm">https://</code> and that the color is a hex code.
<h3 class="font-bold text-3xl">Add a badge</h3>
<p class="">Here you can add a new button with any link, text and color you want. Make sure the link starts with
<code class="bg-primary rounded p-1 text-sm">https://</code> and that the color is a hex code. You can change a badge after the fact by right clicking it.
</p>
<div class="form-control w-full max-w-xs">
<label class="label">
<span class="label-text">Link name</span>
<span class="label-text">Badge name</span>
</label>
<input v-model="name" type="text" placeholder="(ex. Github)" class="input input-bordered w-full max-w-xs" >
<label class="label">
<span class="label-text">Link url</span>
<span class="label-text">URL</span>
</label>
<input v-model="url" type="text" placeholder="(ex. https://github.com)" class="input input-bordered w-full max-w-xs" >
<label class="label">
<span class="label-text">Group</span>
<span class="label-text">Category</span>
</label>
<input v-model="group" type="text" placeholder="(ex. Productivity)" class="input input-bordered w-full max-w-xs" >
<div class="mt-2 flex flex-row flex-wrap">
Expand All @@ -32,7 +32,7 @@

<div class="mt-2 flex flex-row flex-wrap">
<span class="badge cursor-pointer mr-1 mb-1" @click="color = ''">Follow theme</span>
<span v-for="c in colors" class="badge cursor-pointer mr-1 mb-1 border-none" :style="`background-color: ${c.color}`" @click="color = c.color" >{{ c.name }}</span>
<span v-for="c in colors" class="badge cursor-pointer mr-2 mb-2 border-none text-white" :style="`background-color: ${c.color}`" @click="color = c.color" >{{ c.name }}</span>
</div>

</div>
Expand All @@ -51,7 +51,7 @@ import { useAlertStore } from '~~/stores/alert'
import { useSettingsStore } from '~~/stores/settings'
import { Link } from '~~/types/types'
const groups = ['Productivity', 'School', 'Work', 'Home', 'Entertainment', 'Other']
const groups = ['Productivity', 'School', 'Work', 'Home', 'Entertainment', 'Server', 'Training', 'Other']
const colors = [
{
name: 'Red',
Expand All @@ -61,6 +61,14 @@ const colors = [
name: 'Blue',
color: '#2563eb'
},
{
name:'Blue',
color: '#166088'
},
{
name: 'Blue',
color: '#161925'
},
{
name: 'Green',
color: '#059669'
Expand All @@ -73,6 +81,10 @@ const colors = [
name: 'Purple',
color: '#8b5cf6'
},
{
name: 'Purple',
color: '#7D83FF'
},
{
name: 'Pink',
color: '#ec4899'
Expand All @@ -85,6 +97,32 @@ const colors = [
name: 'Black',
color: '#111827'
},
{
name: 'Black',
color: '#000000'
},
{
name: 'Navy Blue',
color: '#0D3B66'
},
{
name: 'Lime',
color: '#31D843'
},
{
name: 'Brown',
color: '#AF7A6D'
},
{
name: 'Brown',
color: '#653239'
},
{
name: 'Blue Gray',
color: '#4F6D7A'
},
]
Expand Down
4 changes: 0 additions & 4 deletions components/AlertComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ const alert = ref<boolean>(alertStore.getAlertStatus())
const alertMessage = computed(() => alertStore.alertMessage)
const alertType = computed(() => alertStore.alertType)
onMounted(() => {
console.log(alertStore.alert)
})
watch(() => alertStore.alert, (newAlert: boolean) => {
alert.value = newAlert
})
Expand Down
2 changes: 1 addition & 1 deletion components/ClockComponent.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<span class="countdown font-mono text-6xl p-0">
<span class="countdown font-mono text-6xl p-0 text-primary">
<span ref="hours"></span>:
<span ref="minutes"></span>:
<span ref="seconds"></span>
Expand Down
4 changes: 1 addition & 3 deletions components/DateComponent.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<template>
<div>
<p class="text-2xl" ref="dateRef">{{dateString}}</p>
</div>
<p class="text-xl" ref="dateRef">{{dateString}}</p>
</template>

<script lang="ts" setup>
Expand Down
9 changes: 8 additions & 1 deletion components/ImageComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ const images = ['https://mj-gallery.com/2812b085-5451-4cfe-a511-b797a8adb6fb/gri
'https://mj-gallery.com/f7b965ff-71eb-4e75-b788-1651c20cdcd5/grid_0.png',
'https://mj-gallery.com/c4bd6b31-5824-4f86-a6a1-9c4408f7c091/grid_0.png',
'https://mj-gallery.com/c30016e1-ca57-4b19-840b-21b5e9c05a83/grid_0.png',
'https://mj-gallery.com/f433feae-fb29-44ca-9712-4cf538bf6e8e/grid_0.png']
'https://mj-gallery.com/b2f7ecab-725a-476b-9e6d-d08f535f0d4e/grid_0.png',
'https://mj-gallery.com/47ef2540-f911-41f6-8a68-75b49be79a2d/grid_0.png',
'https://mj-gallery.com/f2e9fd82-a879-4c63-8827-a0e316d669f9/grid_0.png',
'https://mj-gallery.com/473c2fdd-8207-4ddb-bd20-ffa0833cdca2/grid_0.png',
'https://mj-gallery.com/8009e2a6-062a-4057-bbf6-bdcb0508d558/grid_0.png',
'https://mj-gallery.com/b0129365-3bac-453b-a198-9bc3ce176b98/grid_0.png',
'https://mj-gallery.com/0c6b3646-c95e-4e10-b486-3276c2cd0a7b/grid_0.png',
]
const store = useSettingsStore()
Expand Down
41 changes: 41 additions & 0 deletions components/SettingsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,33 @@
</div>
<label class="label text-xs italic opacity-80">Requires reload of page</label>
</div>
<h1 class="text-xl font-bold mb-2 mt-4">Weather Widget</h1>
<p>
</p>
<div class="form-control">
<label class="label">
<span class="label-text">Open Weather API token</span>
</label>
<label class="input-group">
<input v-model="weatherToken" type="text" placeholder="(ex. g432YRTEWy5g454ytrgQ)" class="flex-1 input input-bordered" />
</label>
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Latitude</span>
</label>
<label class="input-group">
<input v-model="weatherLat" type="text" placeholder="(ex. 50.23)" class="flex-1 input input-bordered" />
</label>
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Longitude</span>
</label>
<label class="input-group">
<input v-model="weatherLon" type="text" placeholder="(ex. 16.17)" class="flex-1 input input-bordered" />
</label>
</div>
<div class="modal-action">
<label for="settings-modal" class="btn mr-auto bg-red-900 text-white" @click="clearAllData">Clear all data</label>
<label for="settings-modal" class="btn">Cancel</label>
Expand All @@ -102,8 +129,10 @@
<script lang="ts" setup>
import { useSettingsStore } from '@/stores/settings'
import { useLinksStore } from '~~/stores/links'
import { useWeatherStore } from '~~/stores/weather'
const store = useSettingsStore()
const linksStore = useLinksStore()
const weatherStore = useWeatherStore()
const image = ref<string>(store.getImage)
const username = ref<string>(store.username)
Expand All @@ -118,6 +147,18 @@ const plexUpdateInterval = ref(computed({
get: () => store.plexUpdateInterval,
set: (value: number) => store.setPlexUpdateInterval(value)
}))
const weatherToken = ref(computed({
get: () => weatherStore.token,
set: (value: string) => weatherStore.setToken(value)
}))
const weatherLat = ref(computed({
get: () => weatherStore.lat,
set: (value: number) => weatherStore.setLat(value)
}))
const weatherLon = ref(computed({
get: () => weatherStore.lon,
set: (value: number) => weatherStore.setLon(value)
}))
const save = () => {
store.setImage(image.value)
Expand Down
59 changes: 59 additions & 0 deletions components/WeatherComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<div v-if="loaded" class="flex flex-row justify-items-center items-center capitalize space-x-4">
<img :src="iconURL" alt="Weather icon">
<div>
<p>{{ weatherData.weather[0].description }}</p>
<p class="opacity-50">{{ weatherData.name }}</p>
</div>
<div class="flex flex-row place-content-start items-start">
<span class="text-2xl">{{ parseInt(weatherData.main.temp) }}</span>
<span class="text-sm">°C</span>
</div>
</div>
</template>

<script lang="ts" setup>
import { useWeatherStore } from '~~/stores/weather'
const weatherStore = useWeatherStore()
const token = ref(computed(() => weatherStore.token))
const lat = ref(computed(() => weatherStore.lat))
const lon = ref(computed(() => weatherStore.lon))
const weatherData = ref(null)
const iconURL = ref('')
const loaded = ref(false)
const getWeather = async () => {
if(token.value) {
const url = 'https://api.openweathermap.org/data/2.5/weather?'
const { data } = await useFetch(`${url}lat=${lat.value}&lon=${lon.value}&appid=${token.value}&units=metric`)
weatherData.value = data.value
iconURL.value = "http://openweathermap.org/img/w/" + weatherData.value.weather[0].icon + ".png"
loaded.value = true
}
}
onMounted(() => {
getWeather()
})
watch(() => weatherStore.token, () => {
getWeather()
})
watch(() => weatherStore.lat, () => {
getWeather()
})
watch(() => weatherStore.lon, () => {
getWeather()
})
// Update weather every 10 minutes
setInterval(() => {
getWeather()
}, 600000)
</script>
1 change: 0 additions & 1 deletion layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const background = computed(() => settingsStore.getBackgroundImage)
const main = ref(null)
onMounted(() => {
console.log(background.value)
main.value.style.backgroundImage = `url(${background.value})`
main.value.style.backgroundSize = 'cover'
})
Expand Down
9 changes: 5 additions & 4 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
<div class="grid grid-cols-1 md:place-items-center justify-around md:px-24 max-w-scren h-screen">
<div class="grid grid-cols-1 md:grid-cols-6 md:grid-rows-1 items-center gap-2 md:gap-16 py-16 xl:py-24 max-h-screen">
<ImageComponent class="overflow-clip h-[calc(40vh)] md:h-full md:col-span-2"/>
<div class="flex flex-col space-y-2 min-w-[calc(50%)] items-start mt-4 md:mt-0 justify-between md:col-span-4 self-start">
<div class="flex flex-col space-y-4 min-w-[calc(50%)] items-start mt-4 md:mt-0 justify-between md:col-span-4 self-start">
<WeatherComponent />
<SearchBar v-if="showSearchBar" />
<h1 class="font-bold text-4xl md:text-5xl">{{ useGreetingText() }} {{ username }}</h1>
<DateComponent v-if="showDate" />
<ClockComponent v-if="showClock" />
<div class="flex flex-row overflow-x-scroll" style="max-width: -webkit-fill-available;" :key="store.linkChanged">
<DateComponent v-if="showDate" />
<div class="flex flex-row overflow-x-scroll pt-2" style="max-width: -webkit-fill-available;" :key="store.linkChanged">
<div v-for="c in uniqueCategories" class="flex flex-col flex-wrap justify-items-start mr-4">
<h1 class="text-xl p-1">{{ c }}</h1>
<h1 class="text-xl">{{ c }}</h1>
<LinkBadge v-for="l in links.filter(l => l.group == c)" :key="l.name" :link="l" />
</div>
</div>
Expand Down
22 changes: 22 additions & 0 deletions stores/weather.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

import { defineStore } from 'pinia'
import { useStorage } from '@vueuse/core'

export const useWeatherStore = defineStore('weather', {
state: () => ({
lat: useStorage('lat', 0),
lon: useStorage('lon', 0),
token: useStorage('token', ''),
}),
actions: {
setToken(token: string) {
this.token = token
},
setLat(lat: number) {
this.lat = lat
},
setLon(lon: number) {
this.lon = lon
}
},
})

0 comments on commit 2187217

Please sign in to comment.