diff --git a/frontend/src/App.vue b/frontend/src/App.vue index a68a404..97b52bb 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -11,6 +11,7 @@ import { import { useRoute, useRouter } from 'vue-router' import PhoneHomeIndicator from '@/components/PhoneHomeIndicator.vue' +import PhoneControlCenter from '@/components/PhoneControlCenter.vue' import PhoneMediaCapture from '@/components/PhoneMediaCapture.vue' import PhoneLockScreen from '@/components/PhoneLockScreen.vue' import PhoneNotifications from '@/components/PhoneNotifications.vue' @@ -140,6 +141,7 @@ const appTransitionName = computed(() => ) const isLocked = ref(false) const isUnlocking = ref(false) +const controlCenterOpened = ref(false) const simPicker = ref(null) const systemColorScheme = window.matchMedia('(prefers-color-scheme: dark)') const viewportScale = ref(getViewportScale()) @@ -150,6 +152,11 @@ const phoneResolutionStyle = computed(() => ({ '--phone-zoom': phoneBaseZoom.value * (phone.preferences.settings.phoneScale / 100), })) +const phoneDisplayStyle = computed(() => ({ + '--phone-display-dim': String( + ((100 - phone.preferences.settings.screenBrightness) / 100) * 0.8, + ), +})) const phoneFrameImage = computed( () => PHONE_FRAME_IMAGES[phone.preferences.settings.frame], ) @@ -339,17 +346,26 @@ function onMessage(event: MessageEvent): void { } else if (event.data?.type === 'darkchat:new' && event.data.data) { const data = event.data.data as DarkChatEventData void darkchat.refreshInbox() - if (data.conversationId && darkchat.activeConversation?.id === data.conversationId) { + if ( + data.conversationId && + darkchat.activeConversation?.id === data.conversationId + ) { void darkchat.openThread(data.conversationId) } if (data.notificationMode !== 'hidden') { const notification: PhoneNotificationInput = { appId: 'darkchat', subtitle: data.sender, - text: data.text ?? data.preview ?? phone.t('Apps.darkchat.privateNotification'), + text: + data.text ?? + data.preview ?? + phone.t('Apps.darkchat.privateNotification'), title: data.title ?? phone.t('Apps.darkchat.name'), } - if (data.device && (!phone.isOpen || data.device.imei !== phone.device?.imei)) { + if ( + data.device && + (!phone.isOpen || data.device.imei !== phone.device?.imei) + ) { notification.device = { imei: data.device.imei, name: data.device.name, @@ -368,6 +384,7 @@ function onMessage(event: MessageEvent): void { event.data.data ) { calls.applyCallState(event.data.data as PhoneCall) + controlCenterOpened.value = false isLocked.value = false isUnlocking.value = false window.setTimeout(() => void router.push('/apps/phone'), 0) @@ -380,6 +397,10 @@ function onMessage(event: MessageEvent): void { function onKeydown(event: KeyboardEvent): void { if (event.key !== 'Escape' || !phone.isOpen) return + if (controlCenterOpened.value) { + controlCenterOpened.value = false + return + } phone.close() void nuiCall('close') } @@ -402,6 +423,11 @@ function unlockPhone(): void { }, 720) } +function toggleControlCenter(): void { + if (isLocked.value) return + controlCenterOpened.value = !controlCenterOpened.value +} + function unlockCamera(): void { unlockPhone() window.setTimeout(() => void router.push('/apps/camera'), 0) @@ -488,11 +514,13 @@ watch( if (unlockTimer !== undefined) window.clearTimeout(unlockTimer) if (!isOpen) { weather.stop() + controlCenterOpened.value = false isLocked.value = false isUnlocking.value = false return } isLocked.value = true + controlCenterOpened.value = false weather.start() isUnlocking.value = false phone.setLaunchOrigin(null) @@ -500,6 +528,13 @@ watch( }, ) +watch( + () => phone.cameraLandscape, + (landscape) => { + if (landscape) controlCenterOpened.value = false + }, +) + onBeforeUnmount(() => { weather.stop() if (clockTicker) clearInterval(clockTicker) @@ -562,13 +597,18 @@ onBeforeUnmount(() => { :dark="phone.isDarkMode" safe-areas class="phone-app" + :style="phoneDisplayStyle" :class="{ dark: phone.isDarkMode, 'phone-app--light': !phone.isDarkMode, 'phone-app--unlocking': isUnlocking, }" > - + @@ -580,6 +620,10 @@ onBeforeUnmount(() => { + { :notification="notifications.current" @close="notifications.dismissCurrent()" /> + button:not(.messages-inbox-header__edit), .messages-chat-header__back, -.messages-inbox-toolbar > button, .messages-messagebar__tools button { border: 1px solid rgb(255 255 255 / 78%); background: linear-gradient(145deg, rgb(255 255 255 / 90%), rgb(236 238 244 / 68%)); @@ -4256,9 +4302,7 @@ button { .phone-app.dark .messages-contact-details__fields input { color: #f5f5f7; } -.phone-app.dark .messages-inbox-header > button:not(.messages-inbox-header__edit), .phone-app.dark .messages-chat-header__back, -.phone-app.dark .messages-inbox-toolbar > button, .phone-app.dark .messages-messagebar__tools button, .phone-app.dark .messages-attachment-menu > button { border-color: rgb(255 255 255 / 10%); @@ -4644,9 +4688,6 @@ button { padding: 0; display: grid; place-items: center; - border: 1px solid var(--messages-inbox-control-border); - background: var(--messages-inbox-control); - box-shadow: var(--messages-inbox-control-shadow); color: var(--messages-inbox-primary); line-height: 1; } @@ -4769,9 +4810,6 @@ button { padding: 0; display: grid; place-items: center; - border-color: var(--messages-inbox-control-border); - background: var(--messages-inbox-control); - box-shadow: var(--messages-inbox-control-shadow); color: var(--messages-inbox-primary); } .messages-inbox-page .messages-inbox-toolbar > button svg { @@ -4794,9 +4832,7 @@ button { --messages-inbox-separator: #2c2c2e; } .phone-app.dark .messages-inbox-page .messages-inbox-header, -.phone-app.dark .messages-inbox-page .messages-inbox-header > button, -.phone-app.dark .messages-inbox-page .messages-inbox-toolbar label, -.phone-app.dark .messages-inbox-page .messages-inbox-toolbar > button { +.phone-app.dark .messages-inbox-page .messages-inbox-toolbar label { background: var(--messages-inbox-control); box-shadow: none; } diff --git a/frontend/src/components/PhoneControlCenter.vue b/frontend/src/components/PhoneControlCenter.vue new file mode 100644 index 0000000..c84fc5c --- /dev/null +++ b/frontend/src/components/PhoneControlCenter.vue @@ -0,0 +1,927 @@ + + + + + diff --git a/frontend/src/components/PhoneStatusBar.vue b/frontend/src/components/PhoneStatusBar.vue index c336e26..74ae40d 100644 --- a/frontend/src/components/PhoneStatusBar.vue +++ b/frontend/src/components/PhoneStatusBar.vue @@ -1,9 +1,13 @@ - + +