The timezone now auto-corrects with DST (but still displays the same offset in the settings screen to the user)
This commit is contained in:
parent
149911e4ad
commit
4c546b14dc
@ -208,50 +208,6 @@ const uint8_t movement_dst_jump_table[] = {
|
|||||||
0 // 40 AST + 1 = UTC
|
0 // 40 AST + 1 = UTC
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t movement_dst_inverse_jump_table[] = {
|
|
||||||
40, // 0
|
|
||||||
0, // 1
|
|
||||||
1, // 2
|
|
||||||
2, // 3
|
|
||||||
4, // 4
|
|
||||||
3, // 5
|
|
||||||
4, // 6
|
|
||||||
5, // 7
|
|
||||||
6, // 8
|
|
||||||
9, // 9
|
|
||||||
7, // 10
|
|
||||||
8, // 11
|
|
||||||
10, // 12
|
|
||||||
12, // 13
|
|
||||||
14, // 14
|
|
||||||
13, // 15
|
|
||||||
16, // 16
|
|
||||||
15, // 17
|
|
||||||
16, // 18
|
|
||||||
17, // 19
|
|
||||||
19, // 20
|
|
||||||
21, // 21
|
|
||||||
20, // 22
|
|
||||||
21, // 23
|
|
||||||
24, // 24
|
|
||||||
25, // 25
|
|
||||||
25, // 26
|
|
||||||
26, // 27
|
|
||||||
28, // 28
|
|
||||||
27, // 29
|
|
||||||
29, // 30
|
|
||||||
30, // 31
|
|
||||||
31, // 32
|
|
||||||
32, // 33
|
|
||||||
34, // 34
|
|
||||||
33, // 35
|
|
||||||
34, // 36
|
|
||||||
35, // 37
|
|
||||||
36, // 38
|
|
||||||
37, // 39
|
|
||||||
39 // 40
|
|
||||||
};
|
|
||||||
|
|
||||||
const char movement_valid_position_0_chars[] = " AaBbCcDdEeFGgHhIiJKLMNnOoPQrSTtUuWXYZ-='+\\/0123456789";
|
const char movement_valid_position_0_chars[] = " AaBbCcDdEeFGgHhIiJKLMNnOoPQrSTtUuWXYZ-='+\\/0123456789";
|
||||||
const char movement_valid_position_1_chars[] = " ABCDEFHlJLNORTtUX-='01378";
|
const char movement_valid_position_1_chars[] = " ABCDEFHlJLNORTtUX-='01378";
|
||||||
|
|
||||||
|
@ -130,7 +130,6 @@ typedef struct {
|
|||||||
|
|
||||||
extern const int16_t movement_timezone_offsets[];
|
extern const int16_t movement_timezone_offsets[];
|
||||||
extern const uint8_t movement_dst_jump_table[];
|
extern const uint8_t movement_dst_jump_table[];
|
||||||
extern const uint8_t movement_dst_inverse_jump_table[];
|
|
||||||
extern const char movement_valid_position_0_chars[];
|
extern const char movement_valid_position_0_chars[];
|
||||||
extern const char movement_valid_position_1_chars[];
|
extern const char movement_valid_position_1_chars[];
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void
|
|||||||
case EVENT_ACTIVATE:
|
case EVENT_ACTIVATE:
|
||||||
case EVENT_TICK:
|
case EVENT_TICK:
|
||||||
date_time = watch_rtc_get_date_time();
|
date_time = watch_rtc_get_date_time();
|
||||||
centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_timezone_offsets[settings->bit.time_zone]);
|
centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, get_timezone_offset(settings->bit.time_zone, date_time));
|
||||||
if (centibeats == state->last_centibeat_displayed) {
|
if (centibeats == state->last_centibeat_displayed) {
|
||||||
// we missed this update, try again next subsecond
|
// we missed this update, try again next subsecond
|
||||||
state->next_subsecond_update = (event.subsecond + 1) % BEAT_REFRESH_FREQUENCY;
|
state->next_subsecond_update = (event.subsecond + 1) % BEAT_REFRESH_FREQUENCY;
|
||||||
@ -76,7 +76,7 @@ bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void
|
|||||||
case EVENT_LOW_ENERGY_UPDATE:
|
case EVENT_LOW_ENERGY_UPDATE:
|
||||||
if (!watch_tick_animation_is_running()) watch_start_tick_animation(432);
|
if (!watch_tick_animation_is_running()) watch_start_tick_animation(432);
|
||||||
date_time = watch_rtc_get_date_time();
|
date_time = watch_rtc_get_date_time();
|
||||||
centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_timezone_offsets[settings->bit.time_zone]);
|
centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, get_timezone_offset(settings->bit.time_zone, date_time));
|
||||||
sprintf(buf, "bt %4lu ", centibeats / 100);
|
sprintf(buf, "bt %4lu ", centibeats / 100);
|
||||||
|
|
||||||
watch_display_string(buf, 0);
|
watch_display_string(buf, 0);
|
||||||
|
@ -62,7 +62,8 @@ void day_night_percentage_face_setup(movement_settings_t *settings, uint8_t watc
|
|||||||
if (*context_ptr == NULL) {
|
if (*context_ptr == NULL) {
|
||||||
*context_ptr = malloc(sizeof(day_night_percentage_state_t));
|
*context_ptr = malloc(sizeof(day_night_percentage_state_t));
|
||||||
day_night_percentage_state_t *state = (day_night_percentage_state_t *)*context_ptr;
|
day_night_percentage_state_t *state = (day_night_percentage_state_t *)*context_ptr;
|
||||||
watch_date_time utc_now = watch_utility_date_time_convert_zone(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60, 0);
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
|
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60, 0);
|
||||||
recalculate(utc_now, state);
|
recalculate(utc_now, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +78,7 @@ bool day_night_percentage_face_loop(movement_event_t event, movement_settings_t
|
|||||||
|
|
||||||
char buf[12];
|
char buf[12];
|
||||||
watch_date_time date_time = watch_rtc_get_date_time();
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0);
|
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60, 0);
|
||||||
|
|
||||||
switch (event.event_type) {
|
switch (event.event_type) {
|
||||||
case EVENT_ACTIVATE:
|
case EVENT_ACTIVATE:
|
||||||
|
@ -70,7 +70,7 @@ static void _h_to_hms(mars_clock_hms_t *date_time, double h) {
|
|||||||
static void _update(movement_settings_t *settings, mars_time_state_t *state) {
|
static void _update(movement_settings_t *settings, mars_time_state_t *state) {
|
||||||
char buf[11];
|
char buf[11];
|
||||||
watch_date_time date_time = watch_rtc_get_date_time();
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
|
uint32_t now = watch_utility_date_time_to_unix_time(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60);
|
||||||
// TODO: I'm skipping over some steps here.
|
// TODO: I'm skipping over some steps here.
|
||||||
// https://www.giss.nasa.gov/tools/mars24/help/algorithm.html
|
// https://www.giss.nasa.gov/tools/mars24/help/algorithm.html
|
||||||
double jdut = 2440587.5 + ((double)now / 86400.0);
|
double jdut = 2440587.5 + ((double)now / 86400.0);
|
||||||
|
@ -165,6 +165,7 @@ static bool mode_display(movement_event_t event, movement_settings_t *settings,
|
|||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
uint32_t previous_date_time;
|
uint32_t previous_date_time;
|
||||||
watch_date_time date_time;
|
watch_date_time date_time;
|
||||||
|
int16_t tz;
|
||||||
|
|
||||||
switch (event.event_type) {
|
switch (event.event_type) {
|
||||||
case EVENT_ACTIVATE:
|
case EVENT_ACTIVATE:
|
||||||
@ -183,8 +184,9 @@ static bool mode_display(movement_event_t event, movement_settings_t *settings,
|
|||||||
|
|
||||||
/* Determine current time at time zone and store date/time */
|
/* Determine current time at time zone and store date/time */
|
||||||
date_time = watch_rtc_get_date_time();
|
date_time = watch_rtc_get_date_time();
|
||||||
timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
|
tz = get_timezone_offset(settings->bit.time_zone, date_time);
|
||||||
date_time = watch_utility_date_time_from_unix_time(timestamp, movement_timezone_offsets[state->current_zone] * 60);
|
timestamp = watch_utility_date_time_to_unix_time(date_time, tz * 60);
|
||||||
|
date_time = watch_utility_date_time_from_unix_time(timestamp, tz * 60);
|
||||||
previous_date_time = state->previous_date_time;
|
previous_date_time = state->previous_date_time;
|
||||||
state->previous_date_time = date_time.reg;
|
state->previous_date_time = date_time.reg;
|
||||||
|
|
||||||
@ -284,7 +286,7 @@ static bool mode_settings(movement_event_t event, movement_settings_t *settings,
|
|||||||
watch_clear_indicator(WATCH_INDICATOR_PM);
|
watch_clear_indicator(WATCH_INDICATOR_PM);
|
||||||
refresh_face = false;
|
refresh_face = false;
|
||||||
}
|
}
|
||||||
result = div(movement_timezone_offsets[state->current_zone], 60);
|
result = div(get_timezone_offset(state->current_zone, watch_rtc_get_date_time()), 60);
|
||||||
hours = result.quot;
|
hours = result.quot;
|
||||||
minutes = result.rem;
|
minutes = result.rem;
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ void world_clock_face_activate(movement_settings_t *settings, void *context) {
|
|||||||
static bool world_clock_face_do_display_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) {
|
static bool world_clock_face_do_display_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) {
|
||||||
char buf[11];
|
char buf[11];
|
||||||
uint8_t pos;
|
uint8_t pos;
|
||||||
|
int16_t tz;
|
||||||
|
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
uint32_t previous_date_time;
|
uint32_t previous_date_time;
|
||||||
@ -67,8 +68,9 @@ static bool world_clock_face_do_display_mode(movement_event_t event, movement_se
|
|||||||
case EVENT_TICK:
|
case EVENT_TICK:
|
||||||
case EVENT_LOW_ENERGY_UPDATE:
|
case EVENT_LOW_ENERGY_UPDATE:
|
||||||
date_time = watch_rtc_get_date_time();
|
date_time = watch_rtc_get_date_time();
|
||||||
timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
|
tz = get_timezone_offset(settings->bit.time_zone, date_time);
|
||||||
date_time = watch_utility_date_time_from_unix_time(timestamp, movement_timezone_offsets[state->settings.bit.timezone_index] * 60);
|
timestamp = watch_utility_date_time_to_unix_time(date_time, tz * 60);
|
||||||
|
date_time = watch_utility_date_time_from_unix_time(timestamp, tz * 60);
|
||||||
previous_date_time = state->previous_date_time;
|
previous_date_time = state->previous_date_time;
|
||||||
state->previous_date_time = date_time.reg;
|
state->previous_date_time = date_time.reg;
|
||||||
|
|
||||||
@ -125,6 +127,8 @@ static bool world_clock_face_do_display_mode(movement_event_t event, movement_se
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool _world_clock_face_do_settings_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) {
|
static bool _world_clock_face_do_settings_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) {
|
||||||
|
watch_date_time date_time;
|
||||||
|
int16_t tz;
|
||||||
switch (event.event_type) {
|
switch (event.event_type) {
|
||||||
case EVENT_MODE_BUTTON_UP:
|
case EVENT_MODE_BUTTON_UP:
|
||||||
if (state->backup_register) watch_store_backup_data(state->settings.reg, state->backup_register);
|
if (state->backup_register) watch_store_backup_data(state->settings.reg, state->backup_register);
|
||||||
@ -168,11 +172,13 @@ static bool _world_clock_face_do_settings_mode(movement_event_t event, movement_
|
|||||||
}
|
}
|
||||||
|
|
||||||
char buf[13];
|
char buf[13];
|
||||||
|
date_time = watch_rtc_get_date_time();
|
||||||
|
tz = get_timezone_offset(settings->bit.time_zone, date_time);
|
||||||
sprintf(buf, "%c%c %3d%02d ",
|
sprintf(buf, "%c%c %3d%02d ",
|
||||||
movement_valid_position_0_chars[state->settings.bit.char_0],
|
movement_valid_position_0_chars[state->settings.bit.char_0],
|
||||||
movement_valid_position_1_chars[state->settings.bit.char_1],
|
movement_valid_position_1_chars[state->settings.bit.char_1],
|
||||||
(int8_t) (movement_timezone_offsets[state->settings.bit.timezone_index] / 60),
|
(int8_t) (tz / 60),
|
||||||
(int8_t) (movement_timezone_offsets[state->settings.bit.timezone_index] % 60) * (movement_timezone_offsets[state->settings.bit.timezone_index] < 0 ? -1 : 1));
|
(int8_t) (tz % 60) * (tz < 0 ? -1 : 1));
|
||||||
watch_set_colon();
|
watch_set_colon();
|
||||||
watch_clear_indicator(WATCH_INDICATOR_PM);
|
watch_clear_indicator(WATCH_INDICATOR_PM);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ static void _astronomy_face_recalculate(movement_settings_t *settings, astronomy
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
watch_date_time date_time = watch_rtc_get_date_time();
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
|
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60);
|
||||||
date_time = watch_utility_date_time_from_unix_time(timestamp, 0);
|
date_time = watch_utility_date_time_from_unix_time(timestamp, 0);
|
||||||
double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
|
double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ static void abort_quick_ticks(countdown_state_t *state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t get_tz_offset(movement_settings_t *settings) {
|
static inline int32_t get_tz_offset(movement_settings_t *settings, watch_date_time date_time) {
|
||||||
return movement_timezone_offsets[settings->bit.time_zone] * 60;
|
return get_timezone_offset(settings->bit.time_zone, date_time) * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void store_countdown(countdown_state_t *state) {
|
static inline void store_countdown(countdown_state_t *state) {
|
||||||
@ -70,11 +70,12 @@ static inline void button_beep(movement_settings_t *settings) {
|
|||||||
|
|
||||||
static void start(countdown_state_t *state, movement_settings_t *settings) {
|
static void start(countdown_state_t *state, movement_settings_t *settings) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
|
int16_t tz = get_tz_offset(settings, now);
|
||||||
|
|
||||||
state->mode = cd_running;
|
state->mode = cd_running;
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, tz);
|
||||||
state->target_ts = watch_utility_offset_timestamp(state->now_ts, state->hours, state->minutes, state->seconds);
|
state->target_ts = watch_utility_offset_timestamp(state->now_ts, state->hours, state->minutes, state->seconds);
|
||||||
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, get_tz_offset(settings));
|
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, tz);
|
||||||
movement_schedule_background_task(target_dt);
|
movement_schedule_background_task(target_dt);
|
||||||
watch_set_indicator(WATCH_INDICATOR_BELL);
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
}
|
}
|
||||||
@ -176,7 +177,7 @@ void countdown_face_activate(movement_settings_t *settings, void *context) {
|
|||||||
countdown_state_t *state = (countdown_state_t *)context;
|
countdown_state_t *state = (countdown_state_t *)context;
|
||||||
if(state->mode == cd_running) {
|
if(state->mode == cd_running) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings, now));
|
||||||
watch_set_indicator(WATCH_INDICATOR_BELL);
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
}
|
}
|
||||||
watch_set_colon();
|
watch_set_colon();
|
||||||
|
@ -59,8 +59,9 @@ static void _update(movement_settings_t *settings, moon_phase_state_t *state, ui
|
|||||||
(void)state;
|
(void)state;
|
||||||
char buf[11];
|
char buf[11];
|
||||||
watch_date_time date_time = watch_rtc_get_date_time();
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60) + offset;
|
int16_t tz = get_timezone_offset(settings->bit.time_zone, date_time);
|
||||||
date_time = watch_utility_date_time_from_unix_time(now, movement_timezone_offsets[settings->bit.time_zone] * 60);
|
uint32_t now = watch_utility_date_time_to_unix_time(date_time, tz * 60) + offset;
|
||||||
|
date_time = watch_utility_date_time_from_unix_time(now, tz * 60);
|
||||||
double currentfrac = fmod(now - FIRST_MOON, LUNAR_SECONDS) / LUNAR_SECONDS;
|
double currentfrac = fmod(now - FIRST_MOON, LUNAR_SECONDS) / LUNAR_SECONDS;
|
||||||
double currentday = currentfrac * LUNAR_DAYS;
|
double currentday = currentfrac * LUNAR_DAYS;
|
||||||
uint8_t phase_index = 0;
|
uint8_t phase_index = 0;
|
||||||
|
@ -48,7 +48,7 @@ static const char orrery_celestial_body_names[NUM_AVAILABLE_BODIES][3] = {
|
|||||||
|
|
||||||
static void _orrery_face_recalculate(movement_settings_t *settings, orrery_state_t *state) {
|
static void _orrery_face_recalculate(movement_settings_t *settings, orrery_state_t *state) {
|
||||||
watch_date_time date_time = watch_rtc_get_date_time();
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
|
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60);
|
||||||
date_time = watch_utility_date_time_from_unix_time(timestamp, 0);
|
date_time = watch_utility_date_time_from_unix_time(timestamp, 0);
|
||||||
double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
|
double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
|
||||||
double et = astro_convert_jd_to_julian_millenia_since_j2000(jd);
|
double et = astro_convert_jd_to_julian_millenia_since_j2000(jd);
|
||||||
|
@ -134,7 +134,8 @@ static void _planetary_solar_phases(movement_settings_t *settings, planetary_hou
|
|||||||
state->no_location = false;
|
state->no_location = false;
|
||||||
|
|
||||||
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
||||||
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0); // the current date / time in UTC
|
int16_t tz = get_timezone_offset(settings->bit.time_zone, date_time);
|
||||||
|
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, tz * 60, 0); // the current date / time in UTC
|
||||||
watch_date_time scratch_time; // scratchpad, contains different values at different times
|
watch_date_time scratch_time; // scratchpad, contains different values at different times
|
||||||
watch_date_time midnight;
|
watch_date_time midnight;
|
||||||
scratch_time.reg = midnight.reg = utc_now.reg;
|
scratch_time.reg = midnight.reg = utc_now.reg;
|
||||||
@ -147,7 +148,7 @@ static void _planetary_solar_phases(movement_settings_t *settings, planetary_hou
|
|||||||
double lon = (double)lon_centi / 100.0;
|
double lon = (double)lon_centi / 100.0;
|
||||||
|
|
||||||
// save UTC offset
|
// save UTC offset
|
||||||
state->utc_offset = ((double)movement_timezone_offsets[settings->bit.time_zone]) / 60.0;
|
state->utc_offset = ((double)tz) / 60.0;
|
||||||
|
|
||||||
// calculate sunrise and sunset of current day in decimal hours after midnight
|
// calculate sunrise and sunset of current day in decimal hours after midnight
|
||||||
sun_rise_set(scratch_time.unit.year + WATCH_RTC_REFERENCE_YEAR, scratch_time.unit.month, scratch_time.unit.day, lon, lat, &sunrise, &sunset);
|
sun_rise_set(scratch_time.unit.year + WATCH_RTC_REFERENCE_YEAR, scratch_time.unit.month, scratch_time.unit.day, lon, lat, &sunrise, &sunset);
|
||||||
@ -237,7 +238,7 @@ static void _planetary_hours(movement_settings_t *settings, planetary_hours_stat
|
|||||||
|
|
||||||
// get current time
|
// get current time
|
||||||
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
||||||
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0); // the current date / time in UTC
|
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60, 0); // the current date / time in UTC
|
||||||
current_hour_epoch = watch_utility_date_time_to_unix_time(utc_now, 0);
|
current_hour_epoch = watch_utility_date_time_to_unix_time(utc_now, 0);
|
||||||
|
|
||||||
// set the current planetary hour as default screen
|
// set the current planetary hour as default screen
|
||||||
|
@ -129,7 +129,8 @@ static void _planetary_solar_phase(movement_settings_t *settings, planetary_time
|
|||||||
state->no_location = false;
|
state->no_location = false;
|
||||||
|
|
||||||
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
||||||
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0); // the current date / time in UTC
|
int16_t tz = get_timezone_offset(settings->bit.time_zone, date_time);
|
||||||
|
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, tz * 60, 0); // the current date / time in UTC
|
||||||
watch_date_time scratch_time; // scratchpad, contains different values at different times
|
watch_date_time scratch_time; // scratchpad, contains different values at different times
|
||||||
watch_date_time midnight;
|
watch_date_time midnight;
|
||||||
scratch_time.reg = midnight.reg = utc_now.reg;
|
scratch_time.reg = midnight.reg = utc_now.reg;
|
||||||
@ -142,7 +143,7 @@ static void _planetary_solar_phase(movement_settings_t *settings, planetary_time
|
|||||||
double lon = (double)lon_centi / 100.0;
|
double lon = (double)lon_centi / 100.0;
|
||||||
|
|
||||||
// save UTC offset
|
// save UTC offset
|
||||||
state->utc_offset = ((double)movement_timezone_offsets[settings->bit.time_zone]) / 60.0;
|
state->utc_offset = ((double)tz) / 60.0;
|
||||||
|
|
||||||
// get UNIX epoch time
|
// get UNIX epoch time
|
||||||
now_epoch = watch_utility_date_time_to_unix_time(utc_now, 0);
|
now_epoch = watch_utility_date_time_to_unix_time(utc_now, 0);
|
||||||
@ -206,11 +207,12 @@ static void _planetary_time(movement_event_t event, movement_settings_t *setting
|
|||||||
double night_hour_count = 0.0;
|
double night_hour_count = 0.0;
|
||||||
uint8_t weekday, planet, planetary_hour;
|
uint8_t weekday, planet, planetary_hour;
|
||||||
double hour_duration, current_hour, current_minute, current_second;
|
double hour_duration, current_hour, current_minute, current_second;
|
||||||
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
|
|
||||||
watch_set_colon();
|
watch_set_colon();
|
||||||
|
|
||||||
// get current time and convert to UTC
|
// get current time and convert to UTC
|
||||||
state->scratch = watch_utility_date_time_convert_zone(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60, 0);
|
state->scratch = watch_utility_date_time_convert_zone(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60, 0);
|
||||||
|
|
||||||
// when current phase ends calculate the next phase
|
// when current phase ends calculate the next phase
|
||||||
if ( watch_utility_date_time_to_unix_time(state->scratch, 0) >= state->phase_end ) {
|
if ( watch_utility_date_time_to_unix_time(state->scratch, 0) >= state->phase_end ) {
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
#define sl_SELECTIONS 6
|
#define sl_SELECTIONS 6
|
||||||
#define DEFAULT_MINUTES { 5,4,1,0,0,0 }
|
#define DEFAULT_MINUTES { 5,4,1,0,0,0 }
|
||||||
|
|
||||||
static inline int32_t get_tz_offset(movement_settings_t *settings) {
|
static inline int32_t get_tz_offset(movement_settings_t *settings, watch_date_time date_time) {
|
||||||
return movement_timezone_offsets[settings->bit.time_zone] * 60;
|
return get_timezone_offset(settings->bit.time_zone, date_time) * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lap = 0;
|
static int lap = 0;
|
||||||
@ -165,7 +165,8 @@ static void ring(sailing_state_t *state, movement_settings_t *settings) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state->nextbeep_ts = state->target_ts - beepseconds[beepflag+1];
|
state->nextbeep_ts = state->target_ts - beepseconds[beepflag+1];
|
||||||
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->nextbeep_ts, get_tz_offset(settings));
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
|
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->nextbeep_ts, get_tz_offset(settings, now));
|
||||||
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
|
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
|
||||||
//background task is set, now we have time to play the tune. If this is cancelled accidentally, the next alarm will still ring. Sound is implemented non-blocking, so that neither buttons nor display output are compromised.
|
//background task is set, now we have time to play the tune. If this is cancelled accidentally, the next alarm will still ring. Sound is implemented non-blocking, so that neither buttons nor display output are compromised.
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
@ -194,7 +195,7 @@ static void start(sailing_state_t *state, movement_settings_t *settings) {//gets
|
|||||||
}
|
}
|
||||||
if (state->index > 5 || state->minutes[state->index] == 0) {
|
if (state->index > 5 || state->minutes[state->index] == 0) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings, now));
|
||||||
state->target_ts = state->now_ts;
|
state->target_ts = state->now_ts;
|
||||||
if (alarmflag != 0){
|
if (alarmflag != 0){
|
||||||
watch_buzzer_play_sequence(long_beep, NULL);
|
watch_buzzer_play_sequence(long_beep, NULL);
|
||||||
@ -205,7 +206,7 @@ static void start(sailing_state_t *state, movement_settings_t *settings) {//gets
|
|||||||
movement_request_tick_frequency(1); //synchronises tick with the moment the button was pressed. Solves 1s offset between sound and display, solves up to +-0.5s offset between button action and display.
|
movement_request_tick_frequency(1); //synchronises tick with the moment the button was pressed. Solves 1s offset between sound and display, solves up to +-0.5s offset between button action and display.
|
||||||
state->mode = sl_running;
|
state->mode = sl_running;
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings, now));
|
||||||
state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, state->minutes[state->index], 0);
|
state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, state->minutes[state->index], 0);
|
||||||
ring(state, settings);
|
ring(state, settings);
|
||||||
}
|
}
|
||||||
@ -253,11 +254,11 @@ void sailing_face_activate(movement_settings_t *settings, void *context) {
|
|||||||
sailing_state_t *state = (sailing_state_t *)context;
|
sailing_state_t *state = (sailing_state_t *)context;
|
||||||
if(state->mode == sl_running) {
|
if(state->mode == sl_running) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings, now));
|
||||||
}
|
}
|
||||||
if(state->mode == sl_counting) {
|
if(state->mode == sl_counting) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings, now));
|
||||||
watch_set_indicator(WATCH_INDICATOR_LAP);
|
watch_set_indicator(WATCH_INDICATOR_LAP);
|
||||||
}
|
}
|
||||||
switch (alarmflag) {
|
switch (alarmflag) {
|
||||||
|
@ -123,9 +123,10 @@ static watch_date_time jde_to_date_time(double JDE) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void calculate_datetimes(solstice_state_t *state, movement_settings_t *settings) {
|
static void calculate_datetimes(solstice_state_t *state, movement_settings_t *settings) {
|
||||||
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
// TODO: handle DST changes
|
// TODO: handle DST changes
|
||||||
state->datetimes[i] = jde_to_date_time(calculate_solstice_equinox(2020 + state->year, i) + (movement_timezone_offsets[settings->bit.time_zone] / (60.0*24.0)));
|
state->datetimes[i] = jde_to_date_time(calculate_solstice_equinox(2020 + state->year, i) + (get_timezone_offset(settings->bit.time_zone, date_time) / (60.0*24.0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ static void _sunrise_sunset_face_update(movement_settings_t *settings, sunrise_s
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
|
||||||
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0); // the current date / time in UTC
|
int16_t tz = get_timezone_offset(settings->bit.time_zone, date_time);
|
||||||
|
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, tz * 60, 0); // the current date / time in UTC
|
||||||
watch_date_time scratch_time; // scratchpad, contains different values at different times
|
watch_date_time scratch_time; // scratchpad, contains different values at different times
|
||||||
scratch_time.reg = utc_now.reg;
|
scratch_time.reg = utc_now.reg;
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ static void _sunrise_sunset_face_update(movement_settings_t *settings, sunrise_s
|
|||||||
// sunriset returns the rise/set times as signed decimal hours in UTC.
|
// sunriset returns the rise/set times as signed decimal hours in UTC.
|
||||||
// this can mean hours below 0 or above 31, which won't fit into a watch_date_time struct.
|
// this can mean hours below 0 or above 31, which won't fit into a watch_date_time struct.
|
||||||
// to deal with this, we set aside the offset in hours, and add it back before converting it to a watch_date_time.
|
// to deal with this, we set aside the offset in hours, and add it back before converting it to a watch_date_time.
|
||||||
double hours_from_utc = ((double)movement_timezone_offsets[settings->bit.time_zone]) / 60.0;
|
double hours_from_utc = ((double)tz) / 60.0;
|
||||||
|
|
||||||
// we loop twice because if it's after sunset today, we need to recalculate to display values for tomorrow.
|
// we loop twice because if it's after sunset today, we need to recalculate to display values for tomorrow.
|
||||||
for(int i = 0; i < 2; i++) {
|
for(int i = 0; i < 2; i++) {
|
||||||
|
@ -36,8 +36,8 @@ static const int8_t _sound_seq_start[] = {BUZZER_NOTE_C8, 2, 0};
|
|||||||
|
|
||||||
static uint8_t _beeps_to_play; // temporary counter for ring signals playing
|
static uint8_t _beeps_to_play; // temporary counter for ring signals playing
|
||||||
|
|
||||||
static inline int32_t _get_tz_offset(movement_settings_t *settings) {
|
static inline int32_t _get_tz_offset(movement_settings_t *settings, watch_date_time date_time) {
|
||||||
return movement_timezone_offsets[settings->bit.time_zone] * 60;
|
return get_timezone_offset(settings->bit.time_zone, date_time) * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _signal_callback() {
|
static void _signal_callback() {
|
||||||
@ -50,7 +50,8 @@ static void _signal_callback() {
|
|||||||
static void _start(timer_state_t *state, movement_settings_t *settings, bool with_beep) {
|
static void _start(timer_state_t *state, movement_settings_t *settings, bool with_beep) {
|
||||||
if (state->timers[state->current_timer].value == 0) return;
|
if (state->timers[state->current_timer].value == 0) return;
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, _get_tz_offset(settings));
|
int32_t tz = _get_tz_offset(settings, now);
|
||||||
|
state->now_ts = watch_utility_date_time_to_unix_time(now, tz);
|
||||||
if (state->mode == pausing)
|
if (state->mode == pausing)
|
||||||
state->target_ts = state->now_ts + state->paused_left;
|
state->target_ts = state->now_ts + state->paused_left;
|
||||||
else
|
else
|
||||||
@ -58,7 +59,7 @@ static void _start(timer_state_t *state, movement_settings_t *settings, bool wit
|
|||||||
state->timers[state->current_timer].unit.hours,
|
state->timers[state->current_timer].unit.hours,
|
||||||
state->timers[state->current_timer].unit.minutes,
|
state->timers[state->current_timer].unit.minutes,
|
||||||
state->timers[state->current_timer].unit.seconds);
|
state->timers[state->current_timer].unit.seconds);
|
||||||
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, _get_tz_offset(settings));
|
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, tz);
|
||||||
state->mode = running;
|
state->mode = running;
|
||||||
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
|
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
|
||||||
watch_set_indicator(WATCH_INDICATOR_BELL);
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
@ -210,7 +211,7 @@ void timer_face_activate(movement_settings_t *settings, void *context) {
|
|||||||
watch_set_colon();
|
watch_set_colon();
|
||||||
if(state->mode == running) {
|
if(state->mode == running) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, _get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, _get_tz_offset(settings, now));
|
||||||
watch_set_indicator(WATCH_INDICATOR_BELL);
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
} else {
|
} else {
|
||||||
state->pausing_seconds = 1;
|
state->pausing_seconds = 1;
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
static uint8_t focus_min = 25;
|
static uint8_t focus_min = 25;
|
||||||
static uint8_t break_min = 5;
|
static uint8_t break_min = 5;
|
||||||
|
|
||||||
static inline int32_t get_tz_offset(movement_settings_t *settings) {
|
static inline int32_t get_tz_offset(movement_settings_t *settings, watch_date_time date_time) {
|
||||||
return movement_timezone_offsets[settings->bit.time_zone] * 60;
|
return get_timezone_offset(settings->bit.time_zone, date_time) * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t get_length(tomato_state_t *state) {
|
static uint8_t get_length(tomato_state_t *state) {
|
||||||
@ -47,12 +47,13 @@ static uint8_t get_length(tomato_state_t *state) {
|
|||||||
|
|
||||||
static void tomato_start(tomato_state_t *state, movement_settings_t *settings) {
|
static void tomato_start(tomato_state_t *state, movement_settings_t *settings) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
|
int32_t tz = get_tz_offset(settings, now);
|
||||||
int8_t length = (int8_t) get_length(state);
|
int8_t length = (int8_t) get_length(state);
|
||||||
|
|
||||||
state->mode = tomato_run;
|
state->mode = tomato_run;
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, tz);
|
||||||
state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, length, 0);
|
state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, length, 0);
|
||||||
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, get_tz_offset(settings));
|
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, tz);
|
||||||
movement_schedule_background_task(target_dt);
|
movement_schedule_background_task(target_dt);
|
||||||
watch_set_indicator(WATCH_INDICATOR_BELL);
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
}
|
}
|
||||||
@ -126,7 +127,7 @@ void tomato_face_activate(movement_settings_t *settings, void *context) {
|
|||||||
tomato_state_t *state = (tomato_state_t *)context;
|
tomato_state_t *state = (tomato_state_t *)context;
|
||||||
if (state->mode == tomato_run) {
|
if (state->mode == tomato_run) {
|
||||||
watch_date_time now = watch_rtc_get_date_time();
|
watch_date_time now = watch_rtc_get_date_time();
|
||||||
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
|
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings, now));
|
||||||
watch_set_indicator(WATCH_INDICATOR_BELL);
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
}
|
}
|
||||||
watch_set_colon();
|
watch_set_colon();
|
||||||
|
@ -157,8 +157,9 @@ static void totp_generate_and_display(totp_state_t *totp_state) {
|
|||||||
totp_display(totp_state);
|
totp_display(totp_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t totp_compute_base_timestamp(movement_settings_t *settings) {
|
static uint32_t totp_compute_base_timestamp(movement_settings_t *settings) {
|
||||||
return watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60);
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
|
return watch_utility_date_time_to_unix_time(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) {
|
void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) {
|
||||||
|
@ -210,7 +210,8 @@ void totp_face_lfs_activate(movement_settings_t *settings, void *context) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
totp_state->timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60);
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
|
totp_state->timestamp = watch_utility_date_time_to_unix_time(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60);
|
||||||
totp_face_set_record(totp_state, 0);
|
totp_face_set_record(totp_state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ static void start_reading(accelerometer_data_acquisition_state_t *state, movemen
|
|||||||
|
|
||||||
accelerometer_data_acquisition_record_t record;
|
accelerometer_data_acquisition_record_t record;
|
||||||
watch_date_time date_time = watch_rtc_get_date_time();
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
state->starting_timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
|
state->starting_timestamp = watch_utility_date_time_to_unix_time(date_time, get_timezone_offset(settings->bit.time_zone, date_time) * 60);
|
||||||
record.header.info.record_type = ACCELEROMETER_DATA_ACQUISITION_HEADER;
|
record.header.info.record_type = ACCELEROMETER_DATA_ACQUISITION_HEADER;
|
||||||
record.header.info.range = ACCELEROMETER_RANGE;
|
record.header.info.range = ACCELEROMETER_RANGE;
|
||||||
record.header.info.temperature = lis2dw_get_temperature();
|
record.header.info.temperature = lis2dw_get_temperature();
|
||||||
|
@ -232,12 +232,13 @@ bool set_time_hackwatch_face_loop(movement_event_t event, movement_settings_t *s
|
|||||||
watch_clear_colon();
|
watch_clear_colon();
|
||||||
sprintf(buf, "%s ", set_time_hackwatch_face_titles[current_page]);
|
sprintf(buf, "%s ", set_time_hackwatch_face_titles[current_page]);
|
||||||
} else {
|
} else {
|
||||||
|
int16_t tz = get_timezone_offset(settings->bit.time_zone, date_time_settings);
|
||||||
watch_set_colon();
|
watch_set_colon();
|
||||||
sprintf(buf,
|
sprintf(buf,
|
||||||
"%s %3d%02d ",
|
"%s %3d%02d ",
|
||||||
set_time_hackwatch_face_titles[current_page],
|
set_time_hackwatch_face_titles[current_page],
|
||||||
(int8_t)(movement_timezone_offsets[settings->bit.time_zone] / 60),
|
(int8_t)(tz / 60),
|
||||||
(int8_t)(movement_timezone_offsets[settings->bit.time_zone] % 60) * (movement_timezone_offsets[settings->bit.time_zone] < 0 ? -1 : 1));
|
(int8_t)(tz % 60) * (tz < 0 ? -1 : 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user