Skip to content
Draft
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
3 changes: 3 additions & 0 deletions app/assets/icons/arrows-pointing-in.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app/assets/icons/arrows-pointing-out.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions app/components/Fullscreen.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<template>
<div class="h-full w-full">
<Artboard id="123" :height="height" :width="width" :hide-chrome="true" :webcontext-active-override="true" />
</div>
</template>

<script setup lang="ts">
import Artboard from './Screens/Artboard.vue';

// The height and width should be 100% viewport even when resized
const height = ref(0) // TODO: Need to subtract the height of the header
const width = ref(0)

// Get the height and width of the viewport
onMounted(() => {
height.value = window.innerHeight
width.value = window.innerWidth
})

// Resize the viewport when the window is resized
onMounted(() => {
window.addEventListener('resize', () => {
height.value = window.innerHeight
width.value = window.innerWidth
})
})
</script>

<style scoped></style>
142 changes: 65 additions & 77 deletions app/components/Screens/Artboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,94 +2,66 @@
<!-- Allow pointer-events when panzoom is enabled -->
<!-- The 'panzoom-exclude' class allows us to ignore Panzoom click events on a certain element -->
<!-- ... and then we use Selection to select just one artboard -->
<div
class="artboard-container"
:class="{ 'panzoom-exclude': state.panzoomEnabled }"
>
<div
v-show="isVisible"
ref="artboard"
:artboard-id="props.id"
class="artboard"
:class="{
<template v-if="!props.hideChrome">
<div class="artboard-container" :class="{ 'panzoom-exclude': state.panzoomEnabled }">
<div v-show="isVisible" ref="artboard" :artboard-id="props.id" class="artboard" :class="{
'is-hover': state.isHover,
'is-selected': state.isSelected,
}"
@mouseover="hoverStart(props.id)"
@mouseout="hoverEnd(props.id)"
@click.right="rightClickHandler()"
>
<div class="artboard__top">
<div>
<span class="title">{{ props.title }}</span>
<span class="dimension">{{ props.width }} x {{ props.height }}</span>
</div>
<!-- Show a loader when state.isLoading == true -->
<div v-show="state.isLoading" class="artboard__loader is-loading">
<div class="content">
<div class="lds-ripple">
<div />
<div />
}" @mouseover="hoverStart(props.id)" @mouseout="hoverEnd(props.id)" @click.right="rightClickHandler()">
<div class="artboard__top">
<div>
<span class="title">{{ props.title }}</span>
<span class="dimension">{{ props.width }} x {{ props.height }}</span>
</div>
<!-- Show a loader when state.isLoading == true -->
<div v-show="state.isLoading" class="artboard__loader is-loading">
<div class="content">
<div class="lds-ripple">
<div />
<div />
</div>
</div>
</div>
</div>
</div>
<div class="artboard__keypoints" />
<div class="flex gap-8">
<div
ref="artboardResizable"
class="artboard__content"
:class="{
<div class="artboard__keypoints" />
<div class="flex gap-8">
<div ref="artboardResizable" class="artboard__content" :class="{
'layout--horizontal': state.horizontalLayout,
'is-hover': state.isHover,
'is-selected': state.isSelected,
}"
>
<div
class="content__frame"
@mousedown="$emit('clicked', props.id, $event)"
>
<WebPage
:id="props.id"
:artboard-id="props.id"
ref="frame"
:allow-interactions="state.canInteractWithWebContext"
class="webview"
@loadstart="state.isLoading = true"
@loadend="state.isLoading = false"
@scroll="updateScrollPosition"
:style="{
height: props.height + 'px',
width: props.width + 'px',
}"
/>
}">
<div class="content__frame" @mousedown="$emit('clicked', props.id, $event)">
<WebPage :id="props.id" :artboard-id="props.id" ref="frame"
:allow-interactions="state.canInteractWithWebContext" class="webview" @loadstart="state.isLoading = true"
@loadend="state.isLoading = false" @scroll="updateScrollPosition" :style="{
height: props.height + 'px',
width: props.width + 'px',
}" />
</div>
<div v-show="state.isHover" class="artboard__handles">
<div class="handle_right" title="Resize" @mousedown="triggerResize($event, 'horizontal')" />
<div class="handle_bottom" title="Resize" @mousedown="triggerResize($event, 'vertical')" />
</div>
</div>
<div v-show="state.isHover" class="artboard__handles">
<div
class="handle_right"
title="Resize"
@mousedown="triggerResize($event, 'horizontal')"
/>
<div
class="handle_bottom"
title="Resize"
@mousedown="triggerResize($event, 'vertical')"
/>
<div class="artboard__cross-browser-screenshots">
<CrossBrowserScreenshots ref="cross-browser-DOM" :height="height" :width="width" :x="scrollPosition.x"
:y="scrollPosition.y" :artboard-id="props.id" />
</div>
</div>
<div class="artboard__cross-browser-screenshots">
<CrossBrowserScreenshots
ref="cross-browser-DOM"
:height="height"
:width="width"
:x="scrollPosition.x"
:y="scrollPosition.y"
:artboard-id="props.id"
/>
</div>
</div>
</div>
</div>
</template>

<template v-if="props.hideChrome">
<div @mousedown="$emit('clicked', props.id, $event)">
<WebPage :id="props.id" :artboard-id="props.id" ref="frame" :allow-interactions="state.canInteractWithWebContext"
class="webview" @loadstart="state.isLoading = true" @loadend="state.isLoading = false"
@scroll="updateScrollPosition" :style="{
height: props.height + 'px',
width: props.width + 'px',
}" />
</div>
</template>
</template>

<script setup lang="ts">
Expand Down Expand Up @@ -131,6 +103,11 @@ const state = reactive({
* and the user is not dragging a selection area
*/
canInteractWithWebContext: computed(() => {
// Override: Always allow interactions with the Web Context
if (props.webcontextActiveOverride) {
return true
}

// This artboard must be 'selected'
if (!state.isSelected) {
return false
Expand Down Expand Up @@ -185,11 +162,22 @@ const props = defineProps({
type: Array,
default: () => [],
},
isVisible: Boolean,
isVisible: {
type: Boolean,
default: true,
},
viewportObserver: {
type: IntersectionObserver,
default: null,
},
hideChrome: {
type: Boolean,
default: false,
},
webcontextActiveOverride: {
type: Boolean,
default: false,
},
})

const emit = defineEmits(['resize', 'clicked'])
Expand Down Expand Up @@ -399,7 +387,7 @@ $artboard-handle-height: 1.5rem;
justify-content: space-between;
margin-bottom: 0.5rem;

& > *:not(:first-child) {
&>*:not(:first-child) {
margin-left: 16px;
}

Expand Down
2 changes: 1 addition & 1 deletion app/components/Screens/WebPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<webview
ref="frame"
class="frame"
:style="{ pointerEvents: allowInteractions ? 'auto' : 'none' }"
v-bind="webviewOptions"
:electronConfig="webpreferences"
/>
Expand Down Expand Up @@ -495,6 +496,5 @@ webview {
height: 100%;
width: 100%;
position: relative;
pointer-events: none; // Prevent interactions/events by default
}
</style>
13 changes: 13 additions & 0 deletions app/components/ToolBar/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
@click="toggleSiteTree()"
data-testid="toggle-site-tree"
/>
<Button
role="ghost"
:icon="data.isFullscreenArtboard ? 'arrows-pointing-in' : 'arrows-pointing-out'"
:is-pressed="data.isFullscreenArtboard"
:tight="false"
:title="data.isFullscreenArtboard ? 'Exit Fullscreen' : 'Fullscreen'"
@click="toggleFSArtboard()"
/>
</div>
<div class="draggable" @dblclick="toggleWindowMaximize" />
<div v-if="data.artboards.length" id="toolbar__url-container">
Expand Down Expand Up @@ -96,6 +104,7 @@ const data = reactive({
favicon: computed(() => history.currentPage.favicon),
sidebar: computed(() => gui.sidebar),
siteTreeEnabled: computed(() => gui.siteTree),
isFullscreenArtboard: computed(() => gui.isFullscreenArtboard),
})

const state = reactive({
Expand Down Expand Up @@ -171,6 +180,10 @@ function toggleFullscreen() {
// const window = remote.getCurrentWindow()
// state.isFullScreen = !!window.isFullScreen()
}

function toggleFSArtboard() {
gui.toggleGui('isFullscreenArtboard')
}
</script>

<style lang="scss" scoped>
Expand Down
16 changes: 13 additions & 3 deletions app/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
<SidePanel />
<SiteTree />
<Screenshots />
<Panzoom>
<Artboards />
</Panzoom>
<template v-if="!isFullscreenArtboard">
<Panzoom>
<Artboards />
</Panzoom>
</template>
<template v-if="isFullscreenArtboard">
<Fullscreen />
</template>
</div>
</template>

Expand All @@ -19,8 +24,13 @@ import Artboards from '@/components/Screens/Artboards.vue'
import useEventHandler from '@/components/Screens/useEventHandler'
import DevModeHud from '~/components/DevModeHud.vue'
import SiteTree from '@/components/SiteTree/index.vue'
import Fullscreen from '@/components/Fullscreen.vue'
import { useGuiStore } from "@/store/gui"

const { init } = useEventHandler() // init event handling
const gui = useGuiStore()

const isFullscreenArtboard = computed(() => gui.isFullscreenArtboard)

onMounted(() => {
init() // initialize
Expand Down
3 changes: 3 additions & 0 deletions app/store/gui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ interface State {
discoMode: boolean
siteTree: boolean
isScreensFullHeight: boolean
isFullscreenArtboard: boolean
}

export const useGuiStore = defineStore('gui', {
Expand All @@ -15,6 +16,7 @@ export const useGuiStore = defineStore('gui', {
discoMode: false,
siteTree: false,
isScreensFullHeight: false,
isFullscreenArtboard: false,
}),
getters: {},
actions: {
Expand All @@ -28,6 +30,7 @@ export const useGuiStore = defineStore('gui', {
setGui(key: keyof State, value: boolean) {
this[key] = value
},

},
// Save this store in localStorage
persist: true,
Expand Down