Signed-off-by: Julien Veyssier <eneiluj@posteo.net>tags/v21.0.0beta1
@@ -30,5 +30,7 @@ return [ | |||
['name' => 'WeatherStatus#getLocation', 'url' => '/api/v1/location', 'verb' => 'GET'], | |||
['name' => 'WeatherStatus#setLocation', 'url' => '/api/v1/location', 'verb' => 'PUT'], | |||
['name' => 'WeatherStatus#getForecast', 'url' => '/api/v1/forecast', 'verb' => 'GET'], | |||
['name' => 'WeatherStatus#getFavorites', 'url' => '/api/v1/favorites', 'verb' => 'GET'], | |||
['name' => 'WeatherStatus#setFavorites', 'url' => '/api/v1/favorites', 'verb' => 'PUT'], | |||
], | |||
]; |
@@ -121,4 +121,27 @@ class WeatherStatusController extends OCSController { | |||
return new DataResponse($forecast); | |||
} | |||
} | |||
/** | |||
* @NoAdminRequired | |||
* | |||
* Get favorites list | |||
* | |||
* @return DataResponse which contains the favorite list | |||
*/ | |||
public function getFavorites(): DataResponse { | |||
return new DataResponse($this->service->getFavorites()); | |||
} | |||
/** | |||
* @NoAdminRequired | |||
* | |||
* Set favorites list | |||
* | |||
* @param array $favorites | |||
* @return DataResponse success state | |||
*/ | |||
public function setFavorites(array $favorites): DataResponse { | |||
return new DataResponse($this->service->setFavorites($favorites)); | |||
} | |||
} |
@@ -133,6 +133,26 @@ class WeatherStatusService { | |||
return ['success' => true]; | |||
} | |||
/** | |||
* Get favorites list | |||
* @param array $favorites | |||
* @return array success state | |||
*/ | |||
public function getFavorites(): array { | |||
$favoritesJson = $this->config->getUserValue($this->userId, Application::APP_ID, 'favorites', ''); | |||
return json_decode($favoritesJson, true) ?: []; | |||
} | |||
/** | |||
* Set favorites list | |||
* @param array $favorites | |||
* @return array success state | |||
*/ | |||
public function setFavorites(array $favorites): array { | |||
$this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites)); | |||
return ['success' => true]; | |||
} | |||
/** | |||
* Try to use the address set in user personal settings as weather location | |||
* |
@@ -26,13 +26,18 @@ | |||
class="weather-status-menu-item__subheader" | |||
:default-icon="weatherIcon" | |||
:menu-title="visibleMessage"> | |||
<ActionLink v-if="address && !errorMessage" | |||
<ActionLink v-if="gotWeather" | |||
icon="icon-address" | |||
target="_blank" | |||
:href="weatherLinkTarget" | |||
:close-after-click="true"> | |||
{{ locationText }} | |||
</ActionLink> | |||
<ActionButton v-if="gotWeather" | |||
:icon="addRemoveFavoriteIcon" | |||
@click="onAddRemoveFavoriteClick"> | |||
{{ addRemoveFavoriteText }} | |||
</ActionButton> | |||
<ActionSeparator v-if="address && !errorMessage" /> | |||
<ActionButton | |||
icon="icon-crosshair" | |||
@@ -49,6 +54,18 @@ | |||
@submit="onAddressSubmit"> | |||
{{ t('weather_status', 'Set custom address') }} | |||
</ActionInput> | |||
<ActionButton | |||
v-show="favorites.length > 0" | |||
:icon="toggleFavoritesIcon" | |||
@click="showFavorites = !showFavorites"> | |||
{{ t('weather_status', 'Favorites') }} | |||
</ActionButton> | |||
<ActionButton v-for="f in displayedFavorites" | |||
:key="f" | |||
icon="icon-starred" | |||
@click="onFavoriteClick(f)"> | |||
{{ f }} | |||
</ActionButton> | |||
</Actions> | |||
</div> | |||
</li> | |||
@@ -160,6 +177,8 @@ export default { | |||
lon: null, | |||
forecasts: [], | |||
loop: null, | |||
favorites: [], | |||
showFavorites: false, | |||
} | |||
}, | |||
computed: { | |||
@@ -217,6 +236,34 @@ export default { | |||
weatherLinkTarget() { | |||
return 'https://www.windy.com/-Rain-thunder-rain?rain,' + this.lat + ',' + this.lon + ',11' | |||
}, | |||
gotWeather() { | |||
return this.address && !this.errorMessage | |||
}, | |||
addRemoveFavoriteIcon() { | |||
return this.currentAddressIsFavorite | |||
? 'icon-starred' | |||
: 'icon-star' | |||
}, | |||
addRemoveFavoriteText() { | |||
return this.currentAddressIsFavorite | |||
? t('weather_status', 'Remove from favorites') | |||
: t('weather_status', 'Add as favorite') | |||
}, | |||
currentAddressIsFavorite() { | |||
return this.favorites.find((f) => { | |||
return f === this.address | |||
}) | |||
}, | |||
toggleFavoritesIcon() { | |||
return this.showFavorites | |||
? 'icon-triangle-s' | |||
: 'icon-triangle-e' | |||
}, | |||
displayedFavorites() { | |||
return this.showFavorites | |||
? this.favorites | |||
: [] | |||
}, | |||
}, | |||
mounted() { | |||
this.initWeatherStatus() | |||
@@ -235,6 +282,8 @@ export default { | |||
} else if (this.mode === MODE_MANUAL_LOCATION) { | |||
this.startLoop() | |||
} | |||
const favs = await network.getFavorites() | |||
this.favorites = favs | |||
} catch (err) { | |||
if (err?.code === 'ECONNABORTED') { | |||
console.info('The weather status request was cancelled because the user navigates.') | |||
@@ -378,6 +427,23 @@ export default { | |||
? ((celcius * (9 / 5)) + 32).toFixed(1) | |||
: celcius | |||
}, | |||
onAddRemoveFavoriteClick() { | |||
const currentIsFavorite = this.currentAddressIsFavorite | |||
if (currentIsFavorite) { | |||
const i = this.favorites.indexOf(currentIsFavorite) | |||
if (i !== -1) { | |||
this.favorites.splice(i, 1) | |||
} | |||
} else { | |||
this.favorites.push(this.address) | |||
} | |||
network.saveFavorites(this.favorites) | |||
}, | |||
onFavoriteClick(favAddress) { | |||
if (favAddress !== this.address) { | |||
this.setAddress(favAddress) | |||
} | |||
}, | |||
}, | |||
} | |||
</script> |
@@ -106,6 +106,33 @@ const fetchForecast = async() => { | |||
return response.data.ocs.data | |||
} | |||
/** | |||
* Fetches the location favorites | |||
* | |||
* @param {String} address The location | |||
* @returns {Promise<Object>} | |||
*/ | |||
const getFavorites = async() => { | |||
const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'favorites' | |||
const response = await HttpClient.get(url) | |||
return response.data.ocs.data | |||
} | |||
/** | |||
* | |||
* @param {Array} favorites List of favorite addresses | |||
* @returns {Promise<Object>} | |||
*/ | |||
const saveFavorites = async(favorites) => { | |||
const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'favorites' | |||
const response = await HttpClient.put(url, { | |||
favorites, | |||
}) | |||
return response.data.ocs.data | |||
} | |||
export { | |||
usePersonalAddress, | |||
setMode, | |||
@@ -113,4 +140,6 @@ export { | |||
setLocation, | |||
setAddress, | |||
fetchForecast, | |||
getFavorites, | |||
saveFavorites, | |||
} |