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

feat: new title bar design #617

Merged
merged 5 commits into from
Apr 18, 2024
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
11 changes: 11 additions & 0 deletions src/authentication/authentication.window.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ function createAuthenticationWindow() {
preload: AUTHENTICATION_WINDOW_PRELOAD_WEBPACK_ENTRY,
},
icon: getBrowserWindowIcon(),
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#00669E00', // Transparent
symbolColor: '#FFFFFF', // White
height: 50,
},
// Position of the top left corner of the traffic light on Mac
trafficLightPosition: {
x: 12, // Same as on Talk Window
y: (50 - 16) / 2, // 16 is the default traffic light button diameter
},
})

// TODO: return this on release
Expand Down
2 changes: 2 additions & 0 deletions src/authentication/renderer/AuthenticationApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ export default {
flex-direction: column;
align-items: center;
user-select: none;
app-region: drag;
}

.spacer {
Expand Down Expand Up @@ -246,6 +247,7 @@ export default {
border-radius: var(--border-radius-large);
box-shadow: 0 0 10px var(--color-box-shadow);
width: 300px;
app-region: no-drag;
}

.login-box__header {
Expand Down
138 changes: 58 additions & 80 deletions src/talk/renderer/DesktopHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,74 +20,59 @@
-->

<template>
<header class="header">
<!-- Nextcloud Apps use #header selector to get its height -->
<!-- This is invisible stub with the same height -->
<div id="header" class="header-stub" />

<a class="header__root-link" @click.prevent="pushToRoot">
nickvergessen marked this conversation as resolved.
Show resolved Hide resolved
<img class="header__logo" src="~@talk/img/app.svg" alt="Talk Logo">
</a>

<div>
<span class="header__title">Nextcloud Talk</span>
<span class="header__preview-badge">Preview</span>
</div>

<div class="spacer" />

<div class="header__item">
<NcButton :aria-label="t('talk_desktop', 'Search')"
type="tertiary-no-background"
class="header__button"
@click="showNotSupportedAlert('Search')">
<template #icon>
<MdiMagnify />
</template>
</NcButton>
</div>

<div class="header__item">
<NcButton :aria-label="t('talk_desktop', 'Notifications')"
type="tertiary-no-background"
class="header__button"
@click="showNotSupportedAlert('Notifications')">
<template #icon>
<MdiBell />
</template>
</NcButton>
</div>

<div class="header__item">
<UserMenu :user="$options.userMetadata" @logout="logout" />
<header id="header" class="header">
<div class="header__inner">
<div v-if="!OS.isMac"
class="header__title-wrapper"
role="button"
tabindex="0"
@click="pushToRoot">
<span class="header__title">Nextcloud Talk</span>
<span class="header__preview-badge">Preview</span>
</div>

<div class="spacer" />

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

<script>
import MdiBell from 'vue-material-design-icons/Bell.vue'
import MdiMagnify from 'vue-material-design-icons/Magnify.vue'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import UserMenu from './components/UserMenu.vue'
import { appData } from '../../app/AppData.js'

export default {
name: 'DesktopHeader',

userMetadata: appData.userMetadata,

components: {
MdiBell,
MdiMagnify,
NcButton,
UserMenu,
},

inject: ['router'],
setup() {
return {
user: appData.userMetadata,
OS: window.OS,
}
},

mounted() {
window.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && document.activeElement === document.body) {
this.pushToRoot()
}
}, { capture: true })
},

methods: {
getTalkRouter() {
return window.OCA.Talk.instance.$router
},

pushToRoot() {
this.router.push({ name: 'root' }).catch(() => {})
this.getTalkRouter().push({ name: 'root' }).catch(() => {})
},

logout() {
Expand All @@ -102,25 +87,22 @@ export default {
</script>

<style scoped>
.header__root-link {
cursor: pointer;
}

.header-stub {
height: 100%;
position: absolute;
z-index: -1;
}

.header {
height: 50px;
box-sizing: border-box;
margin-bottom: -50px;
color: #FFF;
user-select: none;
}

.header__inner {
padding: 0 calc(var(--body-container-margin) + 4px) 0 var(--body-container-margin);
display: flex;
align-items: center;
user-select: none;
height: 100%;
/* Save space for native title bar buttons */
margin-inline-start: env(titlebar-area-x, 0);
width: env(titlebar-area-width, 100%);
}

.header__item {
Expand All @@ -129,35 +111,31 @@ export default {
justify-content: center;
}

.header__logo {
height: 32px;
margin: 0 14px 0 20px;
.header__title-wrapper {
display: flex;
align-items: center;
height: 100%;
margin-inline-start: calc(var(--default-grid-baseline) * 3);
position: relative;

&:focus-visible::after {
bottom: 0;
}
}

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

.header__preview-badge {
margin-left: var(--default-grid-baseline);
}

.header__button {
opacity: .85;
/* We have to use !important here because NcButton already has !important */
color: inherit !important;
transition: opacity ease var(--animation-quick) !important;
}

.header__button:hover,
.header__button:active,
.header__button:focus-visible {
color: inherit !important;
opacity: 1;
margin-inline-start: var(--default-grid-baseline);
}

.spacer {
flex: 1 0 auto;
height: 100%;
/* Allow to drag the window using header */
app-region: drag;
}
</style>
15 changes: 15 additions & 0 deletions src/talk/renderer/Viewer/ViewerApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
id="viewer"
:show.sync="isOpen"
class="viewer-modal"
:class="{ 'viewer-modal--open': isOpen }"
:name="file.basename"
size="full"
:close-button-contained="false"
Expand Down Expand Up @@ -97,7 +98,21 @@ export default {
}
</script>

<style>
.header {
transition: background-color 250ms; /* Same as NcModal transition timing */
}

body:has(.viewer-modal--open) .header {
background: black;
}
</style>

<style scoped>
.viewer-modal {
top: 50px !important;
}

.viewer-modal :deep(.modal-container) {
background: none !important;
}
Expand Down
2 changes: 1 addition & 1 deletion src/talk/renderer/assets/overrides.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
}

#content-vue {
border-radius: var(--body-container-radius) var(--body-container-radius) 0 0 !important;
border-radius: 0 !important;
}
1 change: 1 addition & 0 deletions src/talk/renderer/components/UserMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ export default {
.user-menu__trigger {
display: flex;
align-items: center;
margin: 0 !important; /* Re-define server default styles */
}

.user-menu__avatar {
Expand Down
14 changes: 2 additions & 12 deletions src/talk/renderer/desktop.app.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,8 @@ Vue.prototype.t = translate
Vue.prototype.n = translatePlural

/**
* @param {import('VueRouter').Router} router - Vue Router instance
* @return {import('vue').ComponentPublicInstance}
*/
export function createDesktopApp(router) {
// eslint-disable-next-line vue/require-name-property
return new Vue({
provide() {
return {
router,
}
},

render: (h) => h(DesktopHeader),
}).$mount('#desktop-header')
export function createDesktopApp() {
return new Vue(DesktopHeader).$mount('#desktop-header')
}
18 changes: 7 additions & 11 deletions src/talk/renderer/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ import { appData } from '../../app/AppData.js'
import { getCapabilities } from '../../shared/ocs.service.js'

/**
* Initialize Talk application: styles, localization etc.
*
* @return {Promise<object>}
* @return {Promise<void>}
*/
export async function init() {
export async function initServerStyles() {
// Load application styles from server
await Promise.all([
loadServerCss('/apps/theming/css/default.css'),
Expand All @@ -53,16 +51,14 @@ export async function init() {
window.TALK_DESKTOP.quit()
}
})
}

/**
* @return {Promise<void>}
*/
export async function initLocalStyles() {
// Load styles overrides
await import('./assets/overrides.css')

// Get Talk's modules
const { default: router } = await import('@talk/src/router/router.js')

return {
router,
}
}

/**
Expand Down
9 changes: 5 additions & 4 deletions src/talk/renderer/talk.main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import '@talk/css/icons.css'
import './assets/styles.css'

import 'regenerator-runtime' // TODO: Why isn't it added on bundling
import { init, initTalkHashIntegration } from './init.js'
import { initLocalStyles, initServerStyles, initTalkHashIntegration } from './init.js'
import { setupWebPage } from '../../shared/setupWebPage.js'
import { createViewer } from './Viewer/Viewer.js'
import { createDesktopApp } from './desktop.app.js'

// Initially open the welcome page, if not specified
if (!window.location.hash) {
Expand All @@ -34,10 +35,10 @@ if (!window.location.hash) {

await setupWebPage()

const { router } = await init()
await initServerStyles()
await initLocalStyles()

const { createDesktopApp } = await import('./desktop.app.js')
createDesktopApp(router)
createDesktopApp()

window.OCA.Viewer = createViewer()

Expand Down
13 changes: 12 additions & 1 deletion src/talk/talk.window.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,23 @@ function createTalkWindow() {
const talkWindowOptions = {
minWidth: 600,
minHeight: 400,
backgroundColor: '#171717',
backgroundColor: '#00669E',
autoHideMenuBar: true,
webPreferences: {
preload: TALK_WINDOW_PRELOAD_WEBPACK_ENTRY,
},
icon: getBrowserWindowIcon(),
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#00669E00', // Transparent
symbolColor: '#FFFFFF', // White
height: 50,
},
// Position of the top left corner of the traffic light on Mac
trafficLightPosition: {
x: 12, // In line with SearchBox
y: (50 - 16) / 2, // 16 is the default traffic light button diameter
},
}

const window = new BrowserWindow({
Expand Down
Loading
Loading