Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to set weather forecast offset #24193

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/weather_status/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
['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'],
['name' => 'WeatherStatus#getOptions', 'url' => '/api/v1/options', 'verb' => 'GET'],
['name' => 'WeatherStatus#setOptions', 'url' => '/api/v1/options', 'verb' => 'PUT'],
],
];
17 changes: 9 additions & 8 deletions apps/weather_status/lib/Controller/WeatherStatusController.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,23 +125,24 @@ public function getForecast(): DataResponse {
/**
* @NoAdminRequired
*
* Get favorites list
* Get option values
*
* @return DataResponse which contains the favorite list
* @return DataResponse
*/
public function getFavorites(): DataResponse {
return new DataResponse($this->service->getFavorites());
public function getOptions(): DataResponse {
return new DataResponse($this->service->getOptions());
}

/**
* @NoAdminRequired
*
* Set favorites list
* Set option values
*
* @param array $favorites
* @param ?array $favorites
* @param ?int $forecastOffset
* @return DataResponse success state
*/
public function setFavorites(array $favorites): DataResponse {
return new DataResponse($this->service->setFavorites($favorites));
public function setOptions(?array $favorites = null, ?int $forecastOffset = null): DataResponse {
return new DataResponse($this->service->setOptions($favorites, $forecastOffset));
}
}
27 changes: 18 additions & 9 deletions apps/weather_status/lib/Service/WeatherStatusService.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,31 @@ public function setMode(int $mode): array {
}

/**
* Get favorites list
* @param array $favorites
* @return array success state
* Get option values
* @return array the values
*/
public function getFavorites(): array {
public function getOptions(): array {
$favoritesJson = $this->config->getUserValue($this->userId, Application::APP_ID, 'favorites', '');
return json_decode($favoritesJson, true) ?: [];
$forecastOffset = $this->config->getUserValue($this->userId, Application::APP_ID, 'forecastOffset', '5');
return [
'favorites' => json_decode($favoritesJson, true) ?: [],
'forecastOffset' => $forecastOffset,
];
}

/**
* Set favorites list
* @param array $favorites
* Set option values
* @param ?array $favorites
* @param ?int $forecastOffset
* @return array success state
*/
public function setFavorites(array $favorites): array {
$this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites));
public function setOptions(?array $favorites, ?int $forecastOffset): array {
if (!is_null($favorites)) {
$this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites));
}
if (!is_null($forecastOffset)) {
$this->config->setUserValue($this->userId, Application::APP_ID, 'forecastOffset', strval($forecastOffset));
}
return ['success' => true];
}

Expand Down
88 changes: 67 additions & 21 deletions apps/weather_status/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
<Actions
class="weather-status-menu-item__subheader"
:default-icon="weatherIcon"
:menu-title="visibleMessage">
:menu-title="visibleMessage"
@close="showFavorites = false; showOptions = false">
<ActionLink v-if="gotWeather"
icon="icon-address"
target="_blank"
Expand Down Expand Up @@ -66,13 +67,32 @@
@click="onFavoriteClick(f)">
{{ f }}
</ActionButton>
<ActionButton
:icon="toggleOptionsIcon"
@click="showOptions = !showOptions">
{{ t('weather_status', 'Settings') }}
</ActionButton>
<ActionInput
v-show="showOptions"
ref="forecastOffsetInput"
icon="icon-play-next"
type="number"
step="1"
min="0"
max="9"
class="classic-number-input"
:value="forecastOffset"
@update:value="onForecastOffsetSubmit"
@submit="onForecastOffsetSubmit">
{{ t('weather_status', '{offset} Forecast offset (hours)', { offset: forecastOffset }) }}
</ActionInput>
</Actions>
</div>
</li>
</template>

<script>
import { showError } from '@nextcloud/dialogs'
import { showError, showWarning } from '@nextcloud/dialogs'
import moment from '@nextcloud/moment'
import { getLocale } from '@nextcloud/l10n'
import Actions from '@nextcloud/vue/dist/Components/Actions'
Expand Down Expand Up @@ -179,6 +199,8 @@ export default {
loop: null,
favorites: [],
showFavorites: false,
showOptions: false,
forecastOffset: 5,
}
},
computed: {
Expand All @@ -191,25 +213,27 @@ export default {
locationText() {
return t('weather_status', 'More weather for {adr}', { adr: this.address })
},
sixHoursTempForecast() {
return this.forecasts.length > 5 ? this.forecasts[5].data.instant.details.air_temperature : ''
temperatureForecast() {
return this.forecasts.length > this.forecastOffset
? this.forecasts[this.forecastOffset].data.instant.details.air_temperature
: ''
},
sixHoursWeatherForecast() {
return this.forecasts.length > 5 ? this.forecasts[5].data.next_1_hours.summary.symbol_code : ''
weatherForecast() {
return this.forecasts.length > this.forecastOffset
? this.forecasts[this.forecastOffset].data.next_1_hours.summary.symbol_code
: ''
},
sixHoursFormattedTime() {
if (this.forecasts.length > 5) {
const date = moment(this.forecasts[5].time)
return date.format('LT')
}
return ''
formattedForecastTime() {
return this.forecasts.length > this.forecastOffset
? moment(this.forecasts[this.forecastOffset].time).format('LT')
: ''
},
weatherIcon() {
if (this.loading) {
return 'icon-loading-small'
} else {
return this.sixHoursWeatherForecast && this.sixHoursWeatherForecast in weatherOptions
? weatherOptions[this.sixHoursWeatherForecast].icon
return this.weatherForecast && this.weatherForecast in weatherOptions
? weatherOptions[this.weatherForecast].icon
: 'icon-fair-day'
}
},
Expand All @@ -224,11 +248,11 @@ export default {
} else if (this.errorMessage) {
return this.errorMessage
} else {
return this.sixHoursWeatherForecast && this.sixHoursWeatherForecast in weatherOptions
? weatherOptions[this.sixHoursWeatherForecast].text(
this.getLocalizedTemperature(this.sixHoursTempForecast),
return this.weatherForecast && this.weatherForecast in weatherOptions
? weatherOptions[this.weatherForecast].text(
this.getLocalizedTemperature(this.temperatureForecast),
this.temperatureUnit,
this.sixHoursFormattedTime,
this.formattedForecastTime,
)
: t('weather_status', 'Set location for weather')
}
Expand Down Expand Up @@ -259,6 +283,11 @@ export default {
? 'icon-triangle-s'
: 'icon-triangle-e'
},
toggleOptionsIcon() {
return this.showOptions
? 'icon-triangle-s'
: 'icon-triangle-e'
},
displayedFavorites() {
return this.showFavorites
? this.favorites
Expand All @@ -282,8 +311,9 @@ export default {
} else if (this.mode === MODE_MANUAL_LOCATION) {
this.startLoop()
}
const favs = await network.getFavorites()
this.favorites = favs
const optionValues = await network.getOptionValues()
this.favorites = optionValues.favorites
this.forecastOffset = optionValues.forecastOffset
} catch (err) {
if (err?.code === 'ECONNABORTED') {
console.info('The weather status request was cancelled because the user navigates.')
Expand Down Expand Up @@ -422,6 +452,17 @@ export default {
const newAddress = this.$refs.addressInput.$el.querySelector('input[type="text"]').value
this.setAddress(newAddress)
},
onForecastOffsetSubmit() {
const input = this.$refs.forecastOffsetInput.$el.querySelector('input[type="number"]')
const newOffset = parseInt(input.value)
if (!isNaN(newOffset) && newOffset >= 0 && newOffset <= 9) {
// input.value = ''
this.forecastOffset = newOffset
network.saveOptionValues({ forecastOffset: newOffset })
} else {
showWarning(t('weather_status', 'Forecast offset must be a number between 0 and 9.'))
}
},
getLocalizedTemperature(celcius) {
return this.useFahrenheitLocale
? ((celcius * (9 / 5)) + 32).toFixed(1)
Expand All @@ -437,7 +478,7 @@ export default {
} else {
this.favorites.push(this.address)
}
network.saveFavorites(this.favorites)
network.saveOptionValues({ favorites: this.favorites })
},
onFavoriteClick(favAddress) {
if (favAddress !== this.address) {
Expand Down Expand Up @@ -575,4 +616,9 @@ li:not(.inline) .weather-status-menu-item {
li {
list-style-type: none;
}

.classic-number-input input[type="number"] {
-moz-appearance: number-input !important;
-webkit-appearance: initial !important;
}
</style>
20 changes: 10 additions & 10 deletions apps/weather_status/src/services/weatherStatusService.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,27 +107,27 @@ const fetchForecast = async() => {
}

/**
* Fetches the location favorites
* Fetches option values like favorites and weather offset
*
* @param {String} address The location
* @returns {Promise<Object>}
*/
const getFavorites = async() => {
const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'favorites'
const getOptionValues = async() => {
const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'options'
const response = await HttpClient.get(url)

return response.data.ocs.data
}

/**
* Saves multiple option values
*
* @param {Array} favorites List of favorite addresses
* @param {Object} optionValues key/val option values
* @returns {Promise<Object>}
*/
const saveFavorites = async(favorites) => {
const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'favorites'
const saveOptionValues = async(optionValues) => {
const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'options'
const response = await HttpClient.put(url, {
favorites,
...optionValues,
})

return response.data.ocs.data
Expand All @@ -140,6 +140,6 @@ export {
setLocation,
setAddress,
fetchForecast,
getFavorites,
saveFavorites,
getOptionValues,
saveOptionValues,
}