Skip to content

Commit 244b838

Browse files
committed
fix(update): many updates
1 parent 784a613 commit 244b838

7 files changed

Lines changed: 115 additions & 32 deletions

File tree

packages/app/components/editor/dialog/RoomSettings.vue

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@
1515
name="description"
1616
label="Description"
1717
@update:model-value="val => (model!.info.description = val)" />
18+
<cww-form-field-select
19+
v-model="model!.info.timezone"
20+
label="Timezone"
21+
name="timezone">
22+
<option
23+
v-for="option in timezoneOptions"
24+
:key="option.value"
25+
:value="option.value">
26+
{{ option.label }}
27+
</option>
28+
</cww-form-field-select>
1829
</form>
1930
<teleport to="#teleports">
2031
<cw-room-editor-dialog-room-grid-resize ref="dialogRoomGridResize" />
@@ -31,10 +42,11 @@
3142
</template>
3243

3344
<script lang="ts" setup>
34-
import { ref } from 'vue';
45+
import { computed, ref } from 'vue';
3546
import CwDialog from '../../../components/Dialog.vue';
3647
import CwFormFieldTextfield from '../../../components/formField/Textfield.vue';
3748
import CwFormFieldTextarea from '../../../components/formField/Textarea.vue';
49+
import CwwFormFieldSelect from '../../formField/Select.vue';
3850
import CwButton from '../../../components/Button.vue';
3951
import CwRoomEditorDialogRoomGridResize from './RoomGridResize.vue';
4052
@@ -58,6 +70,13 @@ defineOptions({
5870
inheritAttrs: false
5971
});
6072
73+
const timezoneOptions = computed(() => {
74+
return Intl.supportedValuesOf('timeZone').map(tz => ({
75+
label: tz,
76+
value: tz
77+
}));
78+
});
79+
6180
function onClickSave() {
6281
formEl.value?.requestSubmit();
6382
}
@@ -85,8 +104,10 @@ function onSubmit(
85104
const formData = new FormData(e.target as HTMLFormElement);
86105
model.value.info = {
87106
name: String(formData.get('name')),
88-
description: String(formData.get('description'))
107+
description: String(formData.get('description')),
108+
timezone: String(formData.get('timezone'))
89109
};
110+
$props.app.enterRoom(model.value);
90111
close<RoomDescription>(model.value);
91112
}
92113

packages/app/components/panel/TimeControl.vue

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
<template>
22
<cw-panel class="cw-panel-time-control" hide-title title="Time Control">
3-
<span class="time">
4-
<input
5-
size="5"
6-
:value="preparedTime"
7-
@focus="pause()"
8-
@blur="onBlurInput" />
9-
Uhr
10-
</span>
11-
12-
<cw-button @click="onClickSpeed">
13-
{{ availableSpeeds[lastSpeedIndex]?.title }}
14-
</cw-button>
15-
<cw-button @click="onClickTogglePlayPause">
16-
<base-icon size="very-small" :name="paused ? 'play' : 'pause'" />
17-
</cw-button>
3+
<div class="controls">
4+
<span class="time">
5+
<input
6+
size="5"
7+
:value="preparedTime"
8+
@focus="pause()"
9+
@blur="onBlurInput" />
10+
Uhr
11+
</span>
12+
<cw-button @click="onClickSpeed">
13+
{{ availableSpeeds[lastSpeedIndex]?.title }}
14+
</cw-button>
15+
<cw-button @click="onClickTogglePlayPause">
16+
<base-icon size="very-small" :name="paused ? 'play' : 'pause'" />
17+
</cw-button>
18+
</div>
19+
<div class="timezone">{{ timezone }}</div>
1820
</cw-panel>
1921
</template>
2022

@@ -52,6 +54,13 @@ const dayTime = ref(0);
5254
const paused = ref(false);
5355
const subscription = new Subscription();
5456
57+
const timezone = ref($props.app.modules.time.state.timezone);
58+
subscription.add(
59+
$props.app.modules.time.observables.timezone$.subscribe(tz => {
60+
timezone.value = tz;
61+
})
62+
);
63+
5564
const preparedTime = computed(() => {
5665
const totalMinutes = dayTime.value * 24 * 60;
5766
@@ -149,12 +158,12 @@ onMounted(() => {
149158
.subscribe(void 0)
150159
);
151160
152-
//#region debug
161+
// //#region debug
153162
154-
console.warn('Setting time to noon for debug purposes');
155-
$props.app.modules.time.setDayTime(0.62);
163+
// console.warn('Setting time to noon for debug purposes');
164+
// $props.app.modules.time.setDayTime(0.62);
156165
157-
//#endregion
166+
// //#endregion
158167
});
159168
160169
onUnmounted(() => {
@@ -199,9 +208,7 @@ function onClickTogglePlayPause() {
199208
<style lang="postcss" scoped>
200209
.cw-panel-time-control {
201210
& :deep(.content) {
202-
display: flex;
203-
flex-direction: row;
204-
gap: var(--cw-spacing-medium);
211+
gap: var(--cw-spacing-small);
205212
}
206213
207214
& .time {
@@ -224,5 +231,18 @@ function onClickTogglePlayPause() {
224231
border: none;
225232
}
226233
}
234+
235+
& .controls {
236+
display: flex;
237+
flex-direction: row;
238+
gap: var(--cw-spacing-medium);
239+
}
240+
241+
& .timezone {
242+
flex: 1;
243+
font-size: 12px;
244+
font-weight: bold;
245+
text-align: center;
246+
}
227247
}
228248
</style>

packages/app/lib/classes/App.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import LightAppModule from './appModule/Light';
2727
import type { UnitIdentifier } from '../types/unit';
2828
import type { Vector3 } from 'three';
2929

30+
const DEFAULT_TIMEZONE = 'UTC';
31+
3032
type AppModuleList = (
3133
| typeof CursorAppModule
3234
| typeof UnitFocusAppModule
@@ -191,6 +193,10 @@ export class BaseApp<
191193

192194
const room = await this.loadRoom(roomDescription);
193195

196+
this.modules.time.setTimezone(
197+
room.description.info.timezone ?? DEFAULT_TIMEZONE
198+
);
199+
194200
playerModule.getPlayers().forEach(player => {
195201
if (player.client) {
196202
roomModule.addPlayer(player, targetTeleporterUnitId);

packages/app/lib/classes/Room.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ export default class Room<Modules extends RoomModules = RoomModules> {
116116
id: description.id,
117117
info: {
118118
name: this.description?.info.name ?? '',
119-
description: this.description?.info.description ?? ''
119+
description: this.description?.info.description ?? '',
120+
timezone: this.description.info.timezone ?? ''
120121
},
121122
gridSize: this.gridSize,
122123
walls: this.modules.wall.getWalls().map(wall => wall.toDescription()),

packages/app/lib/classes/appModule/Time.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { concatMap, ReplaySubject } from 'rxjs';
55

66
interface Observables extends AppModuleObservables {
77
dayTime$: ReplaySubject<number>;
8+
timezone$: ReplaySubject<string | null>;
89
speed$: ReplaySubject<number>;
910
paused$: ReplaySubject<boolean>;
1011
}
@@ -15,6 +16,7 @@ interface State extends AppModuleState {
1516
auto: boolean;
1617
dayTime: number;
1718
speed: number;
19+
timezone: string | null;
1820
}
1921

2022
const DAY_LENGTH_SECONDS = 24 * 60 * 60; // 5 Minuten
@@ -27,13 +29,15 @@ export default class TimeAppModule extends AppModule<State, Observables> {
2729
auto: true,
2830
dayLengthSeconds: DAY_LENGTH_SECONDS,
2931
dayTime: 0,
30-
speed: 1
32+
speed: 1,
33+
timezone: null
3134
};
3235

3336
constructor(app: App) {
3437
super(app);
3538
//#region observables
3639
this.observables.dayTime$ = new ReplaySubject<number>(1);
40+
this.observables.timezone$ = new ReplaySubject<string | null>(1);
3741
this.observables.speed$ = new ReplaySubject<number>(1);
3842
this.observables.paused$ = new ReplaySubject<boolean>(1);
3943
//#endregion
@@ -45,11 +49,7 @@ export default class TimeAppModule extends AppModule<State, Observables> {
4549
.pipe(concatMap(this.onUpdate.bind(this)))
4650
.subscribe(void 0)
4751
);
48-
const currentDate = new Date();
49-
const hours = currentDate.getHours();
50-
const minutes = currentDate.getMinutes();
51-
const dayTime = (hours * 60 + minutes) / (24 * 60);
52-
this.state.dayTime = dayTime;
52+
this.state.dayTime = this.getTimeInTimezone(this.state.timezone);
5353
}
5454

5555
setSpeed(speed: number) {
@@ -92,4 +92,38 @@ export default class TimeAppModule extends AppModule<State, Observables> {
9292
this.lastTime = time;
9393
}
9494
}
95+
96+
setTimezone(tz: string | null) {
97+
this.state.timezone = tz;
98+
99+
this.state.dayTime = this.getTimeInTimezone(tz);
100+
this.observables.timezone$.next(this.state.timezone);
101+
this.observables.dayTime$.next(this.state.dayTime);
102+
}
103+
104+
private getTimeInTimezone(tz: string | null): number {
105+
const date = new Date();
106+
107+
let hours: number;
108+
let minutes: number;
109+
110+
if (tz) {
111+
const formatter = new Intl.DateTimeFormat('en-US', {
112+
timeZone: tz,
113+
hour: 'numeric',
114+
minute: 'numeric',
115+
hour12: false
116+
});
117+
118+
const parts = formatter.formatToParts(date);
119+
hours = Number(parts.find(p => p.type === 'hour')?.value);
120+
minutes = Number(parts.find(p => p.type === 'minute')?.value);
121+
} else {
122+
// local fallback
123+
hours = date.getHours();
124+
minutes = date.getMinutes();
125+
}
126+
127+
return (hours * 60 + minutes) / (24 * 60);
128+
}
95129
}

packages/app/lib/types/room.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface RoomDescription<
2626
info: {
2727
name: string;
2828
description?: string;
29+
timezone: string;
2930
};
3031
gridSize: GridSize;
3132

packages/frontend/public/rooms/default.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)