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

refactor: TitleBar #1032

Merged
merged 7 commits into from
Jan 17, 2025
Merged
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
15 changes: 15 additions & 0 deletions src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ declare module '@nextcloud/vue/dist/Components/*.js' {
const component: Component
export default component
}
declare module '@nextcloud/vue/dist/Composables/useHotKey.js' {
export function useHotKey(
keysOrFilter: string | string[] | ((event: KeyboardEvent) => boolean) | true,
callback: (event: KeyboardEvent) => void,
options?: {
push?: boolean
prevent?: boolean
stop?: boolean
ctrl?: boolean
alt?: boolean
shift?: boolean
caseSensitive?: boolean
}
): () => void
}

// Built-time constants
declare const IS_DESKTOP: true
Expand Down
2 changes: 1 addition & 1 deletion src/talk/renderer/Settings/appConfig.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { readonly, ref, set, watch, watchEffect } from 'vue'
import { defineStore } from 'pinia'
import { getAppConfig } from '../../../shared/appConfig.service.ts'
import { setInitialState } from '../../../shared/initialState.service.js'
import { useUserStatusStore } from '../UserStatus/userStatus.store.js'
import { useUserStatusStore } from '../UserStatus/userStatus.store.ts'

export const useAppConfigStore = defineStore('appConfig', () => {
const appConfig: Ref<AppConfig> = ref(getAppConfig())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
<!--
- SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
-->

<script setup>
import { onMounted, onUnmounted } from 'vue'
<script setup lang="ts">
import { useHotKey } from '@nextcloud/vue/dist/Composables/useHotKey.js'
import MainMenu from './components/MainMenu.vue'
import UserMenu from './components/UserMenu.vue'
import { appData } from '../../app/AppData.js'
import { useUserStatusStore } from './UserStatus/userStatus.store.js'
import { useAppConfigStore } from './Settings/appConfig.store.ts'
import { useUserStatusHeartbeat } from './UserStatus/useUserStatusHeartbeat.js'
import { appData } from '../../../app/AppData.js'
import { useUserStatusStore } from '../UserStatus/userStatus.store.ts'
import { useAppConfigStore } from '../Settings/appConfig.store.ts'
import { useUserStatusHeartbeat } from '../UserStatus/useUserStatusHeartbeat.ts'

useUserStatusStore()
useUserStatusHeartbeat()
useAppConfigStore()

const isPreview = false

const user = appData.userMetadata
// TODO: add a proper type for userMetadata
const user = appData.userMetadata! as { id: string; 'display-name': string }
const OS = window.systemInfo

/**
Expand All @@ -35,60 +36,45 @@ function logout() {
window.TALK_DESKTOP.logout()
}

/**
* Handle the global escape key to unselect any chat
* @param {KeyboardEvent} event - Keyboard event
*/
function handleGlobalEscape(event) {
if (event.key === 'Escape' && document.activeElement === document.body) {
pushToRoot()
}
}

onMounted(() => {
window.addEventListener('keydown', handleGlobalEscape, { capture: true })
})

onUnmounted(() => {
window.removeEventListener('keydown', handleGlobalEscape, { capture: true })
})
// Unselect chat by escape key
useHotKey('Escape', pushToRoot)
</script>

<template>
<header id="header" class="header">
<div class="header__inner">
<header id="header" class="title-bar">
<div class="title-bar__inner">
<div v-if="!OS.isMac"
class="header__title-wrapper"
class="title-bar__title-wrapper"
role="button"
tabindex="0"
@click="pushToRoot">
<span class="header__title">Nextcloud Talk</span>
<span v-if="isPreview" class="header__preview-badge">Preview</span>
<span class="title-bar__title">Nextcloud Talk</span>
<span v-if="isPreview" class="title-bar__preview-badge">Preview</span>
</div>

<div class="spacer" />

<div class="header__item" data-theme-dark>
<div class="title-bar__item" data-theme-dark>
<MainMenu />
</div>

<div class="header__item">
<div class="title-bar__item">
<UserMenu :user="user" @logout="logout" />
</div>
</div>
</header>
</template>

<style scoped>
.header {
.title-bar {
height: var(--header-height);
margin-bottom: calc(-1 * var(--header-height));
box-sizing: border-box;
color: var(--color-header-contrast);
user-select: none;
}

.header__inner {
.title-bar__inner {
padding: 0 calc(var(--body-container-margin) + 4px) 0 var(--body-container-margin);
display: flex;
align-items: center;
Expand All @@ -98,13 +84,13 @@ onUnmounted(() => {
width: env(titlebar-area-width, 100%);
}

.header__item {
.title-bar__item {
width: var(--header-height); /* Make it square */
display: flex;
justify-content: center;
}

.header__title-wrapper {
.title-bar__title-wrapper {
display: flex;
align-items: center;
height: 100%;
Expand All @@ -116,19 +102,19 @@ onUnmounted(() => {
}
}

.header__title {
.title-bar__title {
font-size: 18px;
font-weight: bold;
}

.header__preview-badge {
.title-bar__preview-badge {
margin-inline-start: var(--default-grid-baseline);
}

.spacer {
flex: 1 0 auto;
height: 100%;
/* Allow to drag the window using header */
app-region: drag;
-webkit-app-region: drag;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup>
<script setup lang="ts">
import { computed } from 'vue'

import IconCog from 'vue-material-design-icons/Cog.vue'
import IconReload from 'vue-material-design-icons/Reload.vue'
import IconWeb from 'vue-material-design-icons/Web.vue'
import IconBug from 'vue-material-design-icons/Bug.vue'
import IconInformationOutline from 'vue-material-design-icons/InformationOutline.vue'
import IconMenu from 'vue-material-design-icons/Menu.vue'

import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'

import { t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup>
<script setup lang="ts">
import type { CSSProperties } from 'vue'
import { computed } from 'vue'
import { appData } from '../../../app/AppData.js'
import { appData } from '../../../../app/AppData.js'

const props = defineProps({
size: {
type: [Number, String],
default: 20,
},
const props = withDefaults(defineProps<{
size: number | string
}>(), {
size: 20,
})

const theming = appData.capabilities.theming
const logoUrl = theming.logo
const primaryColor = theming.color

const cssVars = computed(() => ({
const cssVars = computed<CSSProperties>(() => ({
'--ThemeLogo-size': typeof props.size === 'number' ? `${props.size}px` : props.size,
'--ThemeLogo-background-color': primaryColor,
}))
Expand All @@ -30,7 +30,7 @@ const cssVars = computed(() => ({
</span>
</template>

<style scoped lang="scss">
<style scoped>
.theme-logo {
display: flex;
align-items: stretch;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup>
<script setup lang="ts">
</script>

<template>
Expand All @@ -15,9 +15,6 @@
</template>

<style scoped>
.menu {
}

.menu__inner {
display: flex;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script>
<script setup lang="ts">
import type { Component } from 'vue'

withDefaults(defineProps<{
tag: string | Component
}>(), {
tag: 'button',
})
</script>

<script lang="ts">
export default {
inheritAttrs: false,
}
</script>

<script setup>
defineProps({
tag: {
type: [String, Object, Function],
default: 'button',
},
})
</script>

<template>
<li class="menu-item">
<component :is="tag" class="menu-item__action unstyled-action" v-bind="$attrs">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup></script>
<script setup lang="ts">
</script>

<template>
<li class="menu-item-separator" />
</template>

<style scoped lang="scss">
<style scoped>
.menu-item-separator {
border-top: 1px solid var(--color-border-dark);
margin: 2px 0;
Expand Down
Loading