From 593f8afc909e166260f32a9e97f8d54d941802e6 Mon Sep 17 00:00:00 2001
From: Dick Wolff <dckwlff@gmail.com>
Date: Tue, 12 Jan 2021 11:35:57 +0100
Subject: Added OpenWeather service component.

---
 src/components/services/OpenWeather.vue | 99 +++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 src/components/services/OpenWeather.vue

(limited to 'src/components/services/OpenWeather.vue')

diff --git a/src/components/services/OpenWeather.vue b/src/components/services/OpenWeather.vue
new file mode 100644
index 0000000..30abb2d
--- /dev/null
+++ b/src/components/services/OpenWeather.vue
@@ -0,0 +1,99 @@
+<template>
+  <div>
+    <div class="card" :class="item.class">
+      <a :href="item.url" :target="item.target" rel="noreferrer">
+        <div class="card-content">
+          <div class="media">
+            <div v-if="image" class="media-left">
+              <figure class="image is-48x48">
+                <img :src="`http://openweathermap.org/img/wn/` + image + `@2x.png`" :alt="conditions" :title="conditions" />
+              </figure>
+            </div>
+            <div v-if="item.icon" class="media-left">
+              <figure class="image is-48x48">
+                <i style="font-size: 35px" :class="['fa-fw', item.icon]"></i>
+              </figure>
+            </div>
+            <div class="media-content">
+              <p class="title is-4">{{ item.location }}</p>
+              <p class="subtitle is-6">
+                <template v-if="item.subtitle">
+                  {{ item.subtitle }}
+                </template>
+                <template v-else-if="api">
+                  {{ temp }} 
+				  <span v-if="this.item.units == 'metric'">&deg;C</span>
+				  <span v-else-if="this.item.units == 'imperial'">&deg;F</span>				  
+				  <span v-else>K</span>
+                </template>
+              </p>
+            </div>
+          </div>
+          <div class="tag" :class="item.tagstyle" v-if="item.tag">
+            <strong class="tag-text">#{{ item.tag }}</strong>
+          </div>
+        </div>
+      </a>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "OpenWeather",
+  props: {
+    item: Object,
+  },
+  data: () => ({
+    api: {
+      name: "",
+	  weather: [{
+		main: "",
+		description: "",
+		icon: ""
+	  }],
+      main: {
+		temp: "",
+		humidity: ""
+	  }
+    }
+  }),
+  computed: {
+    temp: function () {
+      if (this.api) {
+		return parseInt(this.api.main.temp).toFixed(1);
+      }
+      return "";
+    },
+	image: function () {
+	  if (this.api) {
+		return this.api.weather[0].icon;
+	  }
+	  return "";
+	},
+	conditions: function () {
+	  if (this.api) {
+		return this.api.weather[0].description;
+	  }
+	  return "";
+	}
+  },
+  created() {
+    this.fetchStatus();
+  },
+  methods: {
+    fetchStatus: async function () {
+      const url = `${this.item.url}?q=${this.item.location}&appid=${this.item.apiKey}&units=${this.item.units}`;
+      this.api = await fetch(url)
+        .then((response) => response.json())
+        .catch((e) => console.log(e));
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.media-left img {
+  max-height: 100%;
+}
+</style>
\ No newline at end of file
-- 
cgit v1.2.3


From b79561bc9c59d79875a9931d235774333579a363 Mon Sep 17 00:00:00 2001
From: Dick Wolff <dckwlff@gmail.com>
Date: Tue, 12 Jan 2021 11:39:27 +0100
Subject: Format file.

---
 src/components/services/OpenWeather.vue | 62 ++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 28 deletions(-)

(limited to 'src/components/services/OpenWeather.vue')

diff --git a/src/components/services/OpenWeather.vue b/src/components/services/OpenWeather.vue
index 30abb2d..a9310ee 100644
--- a/src/components/services/OpenWeather.vue
+++ b/src/components/services/OpenWeather.vue
@@ -6,7 +6,11 @@
           <div class="media">
             <div v-if="image" class="media-left">
               <figure class="image is-48x48">
-                <img :src="`http://openweathermap.org/img/wn/` + image + `@2x.png`" :alt="conditions" :title="conditions" />
+                <img
+                  :src="`http://openweathermap.org/img/wn/` + image + `@2x.png`"
+                  :alt="conditions"
+                  :title="conditions"
+                />
               </figure>
             </div>
             <div v-if="item.icon" class="media-left">
@@ -21,10 +25,10 @@
                   {{ item.subtitle }}
                 </template>
                 <template v-else-if="api">
-                  {{ temp }} 
-				  <span v-if="this.item.units == 'metric'">&deg;C</span>
-				  <span v-else-if="this.item.units == 'imperial'">&deg;F</span>				  
-				  <span v-else>K</span>
+                  {{ temp }}
+                  <span v-if="this.item.units == 'metric'">&deg;C</span>
+                  <span v-else-if="this.item.units == 'imperial'">&deg;F</span>
+                  <span v-else>K</span>
                 </template>
               </p>
             </div>
@@ -47,36 +51,38 @@ export default {
   data: () => ({
     api: {
       name: "",
-	  weather: [{
-		main: "",
-		description: "",
-		icon: ""
-	  }],
+      weather: [
+        {
+          main: "",
+          description: "",
+          icon: "",
+        },
+      ],
       main: {
-		temp: "",
-		humidity: ""
-	  }
-    }
+        temp: "",
+        humidity: "",
+      },
+    },
   }),
   computed: {
     temp: function () {
       if (this.api) {
-		return parseInt(this.api.main.temp).toFixed(1);
+        return parseInt(this.api.main.temp).toFixed(1);
+      }
+      return "";
+    },
+    image: function () {
+      if (this.api) {
+        return this.api.weather[0].icon;
+      }
+      return "";
+    },
+    conditions: function () {
+      if (this.api) {
+        return this.api.weather[0].description;
       }
       return "";
     },
-	image: function () {
-	  if (this.api) {
-		return this.api.weather[0].icon;
-	  }
-	  return "";
-	},
-	conditions: function () {
-	  if (this.api) {
-		return this.api.weather[0].description;
-	  }
-	  return "";
-	}
   },
   created() {
     this.fetchStatus();
@@ -96,4 +102,4 @@ export default {
 .media-left img {
   max-height: 100%;
 }
-</style>
\ No newline at end of file
+</style>
-- 
cgit v1.2.3


From fd12de9ebd7a75ca2f31e8b28bd2c5ac10c46e21 Mon Sep 17 00:00:00 2001
From: Dick Wolff <dckwlff@gmail.com>
Date: Wed, 13 Jan 2021 21:22:35 +0100
Subject: Improvements

---
 src/components/services/OpenWeather.vue | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

(limited to 'src/components/services/OpenWeather.vue')

diff --git a/src/components/services/OpenWeather.vue b/src/components/services/OpenWeather.vue
index a9310ee..b1e5c57 100644
--- a/src/components/services/OpenWeather.vue
+++ b/src/components/services/OpenWeather.vue
@@ -4,7 +4,7 @@
       <a :href="item.url" :target="item.target" rel="noreferrer">
         <div class="card-content">
           <div class="media">
-            <div v-if="image" class="media-left">
+            <div v-if="image" class="media-left" :class="item.background">
               <figure class="image is-48x48">
                 <img
                   :src="`http://openweathermap.org/img/wn/` + image + `@2x.png`"
@@ -99,7 +99,29 @@ export default {
 </script>
 
 <style scoped lang="scss">
-.media-left img {
-  max-height: 100%;
+.media-left {
+  &.circle,
+  &.square {
+    background-color: #e4e4e4;
+  }
+
+  &.circle {
+    border-radius: 90%;
+  }
+
+  img {
+    max-height: 100%;
+  }
+}
+
+// Add a circular border around the weather image when in dark mode.
+// Otherwise the image is not distinguishable.
+.is-dark {
+  .media-left {
+    &.circle,
+    &.square {
+      background-color: #909090;
+    }
+  }
 }
 </style>
-- 
cgit v1.2.3


From 9e0ef05efe00ffd98ff6c7314a67e8a05505dcc4 Mon Sep 17 00:00:00 2001
From: Dick Wolff <dckwlff@gmail.com>
Date: Wed, 13 Jan 2021 21:27:19 +0100
Subject: Removed URL and made fixed.

---
 src/components/services/OpenWeather.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/components/services/OpenWeather.vue')

diff --git a/src/components/services/OpenWeather.vue b/src/components/services/OpenWeather.vue
index b1e5c57..c535a89 100644
--- a/src/components/services/OpenWeather.vue
+++ b/src/components/services/OpenWeather.vue
@@ -89,7 +89,7 @@ export default {
   },
   methods: {
     fetchStatus: async function () {
-      const url = `${this.item.url}?q=${this.item.location}&appid=${this.item.apiKey}&units=${this.item.units}`;
+      const url = `https://api.openweathermap.org/data/2.5/weather?q=${this.item.location}&appid=${this.item.apiKey}&units=${this.item.units}`;
       this.api = await fetch(url)
         .then((response) => response.json())
         .catch((e) => console.log(e));
-- 
cgit v1.2.3


From fb158d4767b85160c0c2c5fea5c6429c265576a9 Mon Sep 17 00:00:00 2001
From: Dick Wolff <dckwlff@gmail.com>
Date: Wed, 13 Jan 2021 22:19:17 +0100
Subject: Error handling and fixed link to city.

---
 src/components/services/OpenWeather.vue | 40 +++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 9 deletions(-)

(limited to 'src/components/services/OpenWeather.vue')

diff --git a/src/components/services/OpenWeather.vue b/src/components/services/OpenWeather.vue
index c535a89..8029716 100644
--- a/src/components/services/OpenWeather.vue
+++ b/src/components/services/OpenWeather.vue
@@ -1,7 +1,7 @@
 <template>
   <div>
     <div class="card" :class="item.class">
-      <a :href="item.url" :target="item.target" rel="noreferrer">
+      <a :href="`https://openweathermap.org/city/` + locationId" :target="item.target" rel="noreferrer">
         <div class="card-content">
           <div class="media">
             <div v-if="image" class="media-left" :class="item.background">
@@ -25,10 +25,15 @@
                   {{ item.subtitle }}
                 </template>
                 <template v-else-if="api">
-                  {{ temp }}
-                  <span v-if="this.item.units == 'metric'">&deg;C</span>
-                  <span v-else-if="this.item.units == 'imperial'">&deg;F</span>
-                  <span v-else>K</span>
+                  <template v-if="temp !== ''">
+                    {{ temp }}
+                    <span v-if="this.item.units === 'metric'">&deg;C</span>
+                    <span v-else-if="this.item.units === 'imperial'">&deg;F</span>
+                    <span v-else>K</span>
+                  </template>
+                  <template v-else> 
+                    <span class="error">Data could not be retrieved</span>                      
+                  </template>
                 </template>
               </p>
             </div>
@@ -49,7 +54,9 @@ export default {
     item: Object,
   },
   data: () => ({
+    error: false,
     api: {
+      id: "",
       name: "",
       weather: [
         {
@@ -65,8 +72,14 @@ export default {
     },
   }),
   computed: {
-    temp: function () {
+    locationId: function () {
       if (this.api) {
+        return this.api.id;
+      }
+      return "";
+    },
+    temp: function () {
+      if (this.api && this.api.main.temp !== "") {
         return parseInt(this.api.main.temp).toFixed(1);
       }
       return "";
@@ -92,13 +105,19 @@ export default {
       const url = `https://api.openweathermap.org/data/2.5/weather?q=${this.item.location}&appid=${this.item.apiKey}&units=${this.item.units}`;
       this.api = await fetch(url)
         .then((response) => response.json())
-        .catch((e) => console.log(e));
+        .catch((e) => { 
+          this.error = true; 
+          console.log(e) 
+        });
     },
   },
 };
 </script>
 
 <style scoped lang="scss">
+
+// Add a border around the weather image.
+// Otherwise the image is not always distinguishable.
 .media-left {
   &.circle,
   &.square {
@@ -114,8 +133,11 @@ export default {
   }
 }
 
-// Add a circular border around the weather image when in dark mode.
-// Otherwise the image is not distinguishable.
+.error {
+  color: #de0000;
+}
+
+// Change background color in dark mode.
 .is-dark {
   .media-left {
     &.circle,
-- 
cgit v1.2.3


From 551e32e2035c58dd1be0d5f57a648772819f66de Mon Sep 17 00:00:00 2001
From: Dick Wolff <dckwlff@gmail.com>
Date: Thu, 28 Jan 2021 12:58:29 +0100
Subject: Added location id

---
 src/components/services/OpenWeather.vue | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

(limited to 'src/components/services/OpenWeather.vue')

diff --git a/src/components/services/OpenWeather.vue b/src/components/services/OpenWeather.vue
index 8029716..0fc1fe5 100644
--- a/src/components/services/OpenWeather.vue
+++ b/src/components/services/OpenWeather.vue
@@ -19,7 +19,7 @@
               </figure>
             </div>
             <div class="media-content">
-              <p class="title is-4">{{ item.location }}</p>
+              <p class="title is-4">{{ locationName }}</p>
               <p class="subtitle is-6">
                 <template v-if="item.subtitle">
                   {{ item.subtitle }}
@@ -78,6 +78,12 @@ export default {
       }
       return "";
     },
+    locationName: function () {
+      if (this.api) {
+        return this.api.name;
+      }
+      return "";
+    },
     temp: function () {
       if (this.api && this.api.main.temp !== "") {
         return parseInt(this.api.main.temp).toFixed(1);
@@ -102,7 +108,16 @@ export default {
   },
   methods: {
     fetchStatus: async function () {
-      const url = `https://api.openweathermap.org/data/2.5/weather?q=${this.item.location}&appid=${this.item.apiKey}&units=${this.item.units}`;
+      let locationQuery;
+
+      // If a specific location ID was specified, use it. Otherwise retrieve value from location (name).
+      if (this.item.locationId) {
+        locationQuery = `id=${this.item.locationId}`;
+      } else {
+        locationQuery = `q=${this.item.location}`;
+      }
+
+      const url = `https://api.openweathermap.org/data/2.5/weather?${locationQuery}&appid=${this.item.apiKey}&units=${this.item.units}`;
       this.api = await fetch(url)
         .then((response) => response.json())
         .catch((e) => { 
-- 
cgit v1.2.3


From f11b1c9dcff418a2995a1089fa91fd9e44d6fe8b Mon Sep 17 00:00:00 2001
From: Bastien Wirtz <bastien.wirtz@gmail.com>
Date: Mon, 13 Sep 2021 23:13:26 +0200
Subject: Weather service refactoring

---
 src/components/services/OpenWeather.vue | 133 +++++++++++++-------------------
 1 file changed, 52 insertions(+), 81 deletions(-)

(limited to 'src/components/services/OpenWeather.vue')

diff --git a/src/components/services/OpenWeather.vue b/src/components/services/OpenWeather.vue
index 0fc1fe5..09ff76a 100644
--- a/src/components/services/OpenWeather.vue
+++ b/src/components/services/OpenWeather.vue
@@ -1,41 +1,30 @@
 <template>
   <div>
     <div class="card" :class="item.class">
-      <a :href="`https://openweathermap.org/city/` + locationId" :target="item.target" rel="noreferrer">
+      <a
+        :href="`https://openweathermap.org/city/${id}`"
+        :target="item.target"
+        rel="noreferrer"
+      >
         <div class="card-content">
           <div class="media">
-            <div v-if="image" class="media-left" :class="item.background">
+            <div v-if="icon" class="media-left" :class="item.background">
               <figure class="image is-48x48">
                 <img
-                  :src="`http://openweathermap.org/img/wn/` + image + `@2x.png`"
+                  :src="`https://openweathermap.org/img/wn/${icon}@2x.png`"
                   :alt="conditions"
                   :title="conditions"
                 />
               </figure>
             </div>
-            <div v-if="item.icon" class="media-left">
-              <figure class="image is-48x48">
-                <i style="font-size: 35px" :class="['fa-fw', item.icon]"></i>
-              </figure>
-            </div>
             <div class="media-content">
-              <p class="title is-4">{{ locationName }}</p>
-              <p class="subtitle is-6">
-                <template v-if="item.subtitle">
-                  {{ item.subtitle }}
-                </template>
-                <template v-else-if="api">
-                  <template v-if="temp !== ''">
-                    {{ temp }}
-                    <span v-if="this.item.units === 'metric'">&deg;C</span>
-                    <span v-else-if="this.item.units === 'imperial'">&deg;F</span>
-                    <span v-else>K</span>
-                  </template>
-                  <template v-else> 
-                    <span class="error">Data could not be retrieved</span>                      
-                  </template>
-                </template>
-              </p>
+              <p v-if="error" class="error">Data could not be retrieved</p>
+              <div v-else>
+                <p class="title is-4">{{ name }}</p>
+                <p class="subtitle is-6">
+                  {{ temp | tempSuffix(this.item.units) }}
+                </p>
+              </div>
             </div>
           </div>
           <div class="tag" :class="item.tagstyle" v-if="item.tag">
@@ -54,63 +43,21 @@ export default {
     item: Object,
   },
   data: () => ({
+    id: null,
+    icon: null,
+    name: null,
+    temp: null,
+    conditions: null,
     error: false,
-    api: {
-      id: "",
-      name: "",
-      weather: [
-        {
-          main: "",
-          description: "",
-          icon: "",
-        },
-      ],
-      main: {
-        temp: "",
-        humidity: "",
-      },
-    },
   }),
-  computed: {
-    locationId: function () {
-      if (this.api) {
-        return this.api.id;
-      }
-      return "";
-    },
-    locationName: function () {
-      if (this.api) {
-        return this.api.name;
-      }
-      return "";
-    },
-    temp: function () {
-      if (this.api && this.api.main.temp !== "") {
-        return parseInt(this.api.main.temp).toFixed(1);
-      }
-      return "";
-    },
-    image: function () {
-      if (this.api) {
-        return this.api.weather[0].icon;
-      }
-      return "";
-    },
-    conditions: function () {
-      if (this.api) {
-        return this.api.weather[0].description;
-      }
-      return "";
-    },
-  },
   created() {
-    this.fetchStatus();
+    this.fetchWeather();
   },
   methods: {
-    fetchStatus: async function () {
+    fetchWeather: async function () {
       let locationQuery;
 
-      // If a specific location ID was specified, use it. Otherwise retrieve value from location (name).
+      // Use location ID if specified, otherwise retrieve value from location (name).
       if (this.item.locationId) {
         locationQuery = `id=${this.item.locationId}`;
       } else {
@@ -118,19 +65,43 @@ export default {
       }
 
       const url = `https://api.openweathermap.org/data/2.5/weather?${locationQuery}&appid=${this.item.apiKey}&units=${this.item.units}`;
-      this.api = await fetch(url)
-        .then((response) => response.json())
-        .catch((e) => { 
-          this.error = true; 
-          console.log(e) 
+      fetch(url)
+        .then((response) => {
+          if (!response.ok) {
+            throw Error(response.statusText);
+          }
+          return response.json();
+        })
+        .then((weather) => {
+          this.id = weather.id;
+          this.name = weather.name;
+          this.temp = parseInt(weather.main.temp).toFixed(1);
+          this.icon = weather.weather[0].icon;
+          this.conditions = weather.weather[0].description;
+        })
+        .catch((e) => {
+          console.log(e);
+          this.error = true;
         });
     },
   },
+  filters: {
+    tempSuffix: function (value, type) {
+      if (!value) return "";
+
+      let unit = "K";
+      if (type === "metric") {
+        unit = "°C";
+      } else if (type === "imperial") {
+        unit = "°F";
+      }
+      return `${value} ${unit}`;
+    },
+  },
 };
 </script>
 
 <style scoped lang="scss">
-
 // Add a border around the weather image.
 // Otherwise the image is not always distinguishable.
 .media-left {
-- 
cgit v1.2.3

