Skip to content

Commit

Permalink
Add Prime Flow to Layout Editor v2 (#2521)
Browse files Browse the repository at this point in the history
* Port over theme changes

* Add light theme and prime check

* Add SideNav dropdown

* Add WelcomeToPrime window

* Add translations

* Render WelcomeToPrime

* Style WelcomeToPrime

* Fix migration

* Finetune theme colors and add theme toggle

* Add prime socket

* Fix reactivity to prime check and add design tweaks

* Fix icon in prime themes

* Add magic link and fix add tab function

* Address Code Review, move prime checks to login/logout
  • Loading branch information
gettinToasty authored Mar 19, 2020
1 parent 40353b6 commit 6c000e1
Show file tree
Hide file tree
Showing 37 changed files with 606 additions and 174 deletions.
13 changes: 12 additions & 1 deletion app/app.g.less
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ label {

background: var(--accent);
font-size: 12px;
color: var(--white);
color: var(--action-button-text);
padding: 0 4px;
line-height: 16px;
}
Expand Down Expand Up @@ -420,6 +420,17 @@ select {
opacity: 0;
}

.sidenav-slide-enter,
.sidenav-slide-leave-to {
transform: translateY(-20px);
opacity: 0;
}

.sidenav-slide-enter-active,
.sidenav-slide-leave-active {
transition: all 0.3s ease;
}

.v--modal-overlay {
background: var(--modal-overlay);
}
Expand Down
1 change: 1 addition & 0 deletions app/components/NavTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default class SideNav extends Vue {

openDevTools() {
electron.ipcRenderer.send('openDevTools');
this.userService.showPrimeWindow();
}

handleAuth() {
Expand Down
25 changes: 24 additions & 1 deletion app/components/SideNav.m.less
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,32 @@
}
}

.primary-tab {
position: relative;

.studio-dropdown {
position: absolute;
bottom: 2px;
right: 4px;
font-size: 10px;
color: var(--title);
}

&.active {
.studio-dropdown {
color: var(--background);
}
}
}

.studio-tabs {
max-height: 230px;
position: absolute;
top: 46px;
left: 0;
overflow-y: auto;
background-color: var(--background);
z-index: 10;

&::-webkit-scrollbar {
display: none;
Expand Down Expand Up @@ -79,7 +102,7 @@

.new-badge {
background: var(--teal);
color: var(--white);
color: var(--action-button-text);
font-size: 9px;
position: absolute;
right: 2px;
Expand Down
61 changes: 46 additions & 15 deletions app/components/SideNav.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Vue from 'vue';
import cx from 'classnames';
import { Component, Prop, Watch } from 'vue-property-decorator';
import { Component, Prop } from 'vue-property-decorator';
import { Inject } from 'services/core/injector';
import { CustomizationService } from 'services/customization';
import { NavigationService, TAppPage } from 'services/navigation';
Expand All @@ -27,6 +27,7 @@ export default class SideNav extends Vue {
@Inject() incrementalRolloutService: IncrementalRolloutService;

availableChatbotPlatforms = ['twitch', 'mixer', 'youtube'];
showTabDropdown = false;

get availableFeatures() {
return EAvailableFeatures;
Expand Down Expand Up @@ -80,21 +81,51 @@ export default class SideNav extends Vue {
return this.appService.state.loading;
}

get studioTabElements() {
get primaryStudioTab() {
return (
<div class={styles.studioTabs}>
{this.studioTabs.map(page => (
<div
class={cx(styles.mainCell, {
[styles.active]:
this.page === 'Studio' && this.layoutService.state.currentTab === page.target,
})}
onClick={() => this.navigateToStudioTab(page.target)}
title={page.title}
>
<i class={page.icon} />
<div
onMouseenter={() => (this.showTabDropdown = true)}
onMouseleave={() => (this.showTabDropdown = false)}
>
<div
class={cx(styles.primaryTab, {
[styles.active]:
this.page === 'Studio' && this.layoutService.state.currentTab === 'default',
})}
>
{this.studioTab(this.studioTabs[0])}
{this.studioTabs.length > 1 && this.userService.isPrime && (
<i class={cx('icon-down', styles.studioDropdown)} />
)}
</div>
{this.additionalStudioTabs}
</div>
);
}

get additionalStudioTabs() {
return (
<transition name="sidenav-slide">
{this.userService.isPrime && this.showTabDropdown && (
<div class={styles.studioTabs}>
{this.studioTabs.slice(1).map(page => this.studioTab(page))}
</div>
))}
)}
</transition>
);
}

studioTab(page: { target: string; title: string; icon: string }) {
return (
<div
class={cx(styles.mainCell, {
[styles.active]:
this.page === 'Studio' && this.layoutService.state.currentTab === page.target,
})}
onClick={() => this.navigateToStudioTab(page.target)}
title={page.title}
>
<i class={page.icon} />
</div>
);
}
Expand All @@ -111,7 +142,7 @@ export default class SideNav extends Vue {

return (
<div class={cx('side-nav', styles.container, { [styles.leftDock]: this.leftDock })}>
{this.studioTabElements}
{this.primaryStudioTab}
{pageData.map(page => (
<div
class={cx(styles.mainCell, {
Expand Down
49 changes: 49 additions & 0 deletions app/components/TitleBar.m.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@import '../styles/index';

.titlebar {
display: flex;
flex-direction: row;
align-items: center;
height: 30px;
flex: 0 0 30px;
background: var(--titlebar);
-webkit-app-region: drag;
}

.titlebar-icon {
padding-left: 16px;
width: 32px;
}

.titlebar svg {
width: auto;
height: 14px;
padding: 3px;
margin-left: 2px;
margin-right: 8px;
margin-bottom: 8px;
overflow: visible;

path {
opacity: 1;
fill: var(--prime);
}
}

.titlebar-title {
flex-grow: 1;
padding-left: 10px;
color: var(--icon);
}

.titlebar-actions {
-webkit-app-region: no-drag;
}

.titlebar-action {
.icon-hover();

color: var(--icon);
cursor: pointer;
margin-right: 16px;
}
26 changes: 26 additions & 0 deletions app/components/TitleBar.vue.ts → app/components/TitleBar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import electron from 'electron';
import cx from 'classnames';
import { CustomizationService } from 'services/customization';
import { Inject } from 'services/core/injector';
import { StreamingService } from 'services/streaming';
import KevinSvg from 'components/shared/KevinSvg';
import Utils from 'services/utils';
import { $t } from 'services/i18n';
import styles from './TitleBar.m.less';

@Component({})
export default class TitleBar extends Vue {
Expand Down Expand Up @@ -43,4 +46,27 @@ export default class TitleBar extends Vue {
get theme() {
return this.customizationService.currentTheme;
}

get primeTheme() {
return /prime/.test(this.theme);
}

render() {
return (
<div class={cx(styles.titlebar, this.theme)}>
{!this.primeTheme && (
<img class={styles.titlebarIcon} src={require('../../media/images/icon.ico')} />
)}
{this.primeTheme && <KevinSvg class={styles.titlebarIcon} />}
<div class={styles.titlebarTitle}>{this.title}</div>
<div class={styles.titlebarActions}>
<i class={cx('icon-subtract', styles.titlebarAction)} onClick={() => this.minimize()} />
{this.isMaximizable && (
<i class={cx('icon-expand-1', styles.titlebarAction)} onClick={() => this.maximize()} />
)}
<i class={cx('icon-close', styles.titlebarAction)} onClick={() => this.close()} />
</div>
</div>
);
}
}
52 changes: 0 additions & 52 deletions app/components/TitleBar.vue

This file was deleted.

1 change: 0 additions & 1 deletion app/components/editor/elements/Browser.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import StudioEditor from 'components/StudioEditor.vue';
import { Component } from 'vue-property-decorator';
import BaseElement from './BaseElement';
import BrowserView from 'components/shared/BrowserView';
Expand Down
26 changes: 22 additions & 4 deletions app/components/pages/AddTabModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cx from 'classnames';
import electron from 'electron';
import TsxComponent, { createProps } from 'components/tsx-component';
import { Component } from 'vue-property-decorator';
import ModalLayout from 'components/ModalLayout.vue';
Expand All @@ -8,6 +8,8 @@ import { ImagePickerInput } from 'components/shared/inputs/inputs';
import { Inject } from 'services/core/injector';
import { LayoutService } from 'services/layout';
import { $t } from 'services/i18n';
import { UserService } from 'services/user';
import { MagicLinkService } from 'services/magic-link';

const ICONS = [
{ title: '', value: 'icon-studio', description: 'icon-studio' },
Expand All @@ -31,13 +33,23 @@ class AddTabModalProps {
@Component({ props: createProps(AddTabModalProps) })
export default class AddTabModal extends TsxComponent<AddTabModalProps> {
@Inject() private layoutService: LayoutService;
@Inject() private userService: UserService;
@Inject() private magicLinkService: MagicLinkService;

name = '';
icon = '';

createTab() {
async createTab() {
this.layoutService.addTab(this.name, this.icon);
this.$emit('close');
if (!this.userService.isPrime) {
try {
const link = await this.magicLinkService.getDashboardMagicLink('prime');
electron.remote.shell.openExternal(link);
} catch (e) {
console.error('Error generating dashboard magic link', e);
}
}
}

cancel() {
Expand All @@ -48,6 +60,12 @@ export default class AddTabModal extends TsxComponent<AddTabModalProps> {
return !!this.icon && !!this.name;
}

get buttonInfo() {
return this.userService.isPrime
? { text: $t('Save New Tab'), class: 'button button--action' }
: { text: $t('Add New Tab With Prime'), class: 'button button--prime' };
}

render() {
return (
<ModalLayout
Expand All @@ -67,11 +85,11 @@ export default class AddTabModal extends TsxComponent<AddTabModalProps> {
{$t('Cancel')}
</button>
<button
class="button button--action"
class={this.buttonInfo.class}
onClick={() => this.createTab()}
disabled={!this.canSave}
>
{$t('Save New Tab')}
{this.buttonInfo.text}
</button>
</div>
</ModalLayout>
Expand Down
Loading

0 comments on commit 6c000e1

Please sign in to comment.