Initial commit

Co-Authored-By: Eric Tuvesson <eric.tuvesson@gmail.com>
Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com>
Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com>
Co-Authored-By: Anders Larsson <64838990+anders-topp@users.noreply.github.com>
Co-Authored-By: Johan  <4934465+joolsus@users.noreply.github.com>
Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com>
Co-Authored-By: victoratndl <99176179+victoratndl@users.noreply.github.com>
This commit is contained in:
Michael Cartner
2024-01-26 11:52:55 +01:00
commit b9c60b07dc
2789 changed files with 868795 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.8332 5.34199L14.6582 4.16699L9.99984 8.82533L5.3415 4.16699L4.1665 5.34199L8.82484 10.0003L4.1665 14.6587L5.3415 15.8337L9.99984 11.1753L14.6582 15.8337L15.8332 14.6587L11.1748 10.0003L15.8332 5.34199Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.6667 6.66667H14.325C13.95 6.01667 13.4334 5.45833 12.8084 5.03333L14.1667 3.675L12.9917 2.5L11.1834 4.30833C10.8 4.21667 10.4084 4.16667 10 4.16667C9.59171 4.16667 9.20004 4.21667 8.82504 4.30833L7.00837 2.5L5.83337 3.675L7.18337 5.03333C6.56671 5.45833 6.05004 6.01667 5.67504 6.66667H3.33337V8.33333H5.07504C5.03337 8.60833 5.00004 8.88333 5.00004 9.16667V10H3.33337V11.6667H5.00004V12.5C5.00004 12.7833 5.03337 13.0583 5.07504 13.3333H3.33337V15H5.67504C6.54171 16.4917 8.15004 17.5 10 17.5C11.85 17.5 13.4584 16.4917 14.325 15H16.6667V13.3333H14.925C14.9667 13.0583 15 12.7833 15 12.5V11.6667H16.6667V10H15V9.16667C15 8.88333 14.9667 8.60833 14.925 8.33333H16.6667V6.66667ZM13.3334 10V12.5C13.3334 12.6833 13.3084 12.8917 13.275 13.0833L13.1917 13.625L12.8834 14.1667C12.2834 15.2 11.1834 15.8333 10 15.8333C8.81671 15.8333 7.71671 15.1917 7.11671 14.1667L6.80837 13.6333L6.72504 13.0917C6.69171 12.9 6.66671 12.6917 6.66671 12.5V9.16667C6.66671 8.975 6.69171 8.76667 6.72504 8.58333L6.80837 8.04167L7.11671 7.5C7.36671 7.06667 7.71671 6.69167 8.12504 6.40833L8.60004 6.08333L9.21671 5.93333C9.47504 5.86667 9.74171 5.83333 10 5.83333C10.2667 5.83333 10.525 5.86667 10.7917 5.93333L11.3584 6.06667L11.8667 6.41667C12.2834 6.7 12.625 7.06667 12.875 7.50833L13.1917 8.05L13.275 8.59167C13.3084 8.775 13.3334 8.98333 13.3334 9.16667V10ZM8.33337 11.6667H11.6667V13.3333H8.33337V11.6667ZM8.33337 8.33333H11.6667V10H8.33337V8.33333Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,3 @@
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.86612 3.77664C3.10054 3.54222 3.41848 3.41052 3.75 3.41052H8.33333C8.67851 3.41052 8.95833 3.69034 8.95833 4.03552C8.95833 4.3807 8.67851 4.66052 8.33333 4.66052L3.75 4.66052L3.75 17.1605H16.25V12.5772C16.25 12.232 16.5298 11.9522 16.875 11.9522C17.2202 11.9522 17.5 12.232 17.5 12.5772V17.1605C17.5 17.492 17.3683 17.81 17.1339 18.0444C16.8995 18.2788 16.5815 18.4105 16.25 18.4105H3.75C3.41848 18.4105 3.10054 18.2788 2.86612 18.0444C2.6317 17.81 2.5 17.492 2.5 17.1605V4.66052C2.5 4.329 2.6317 4.01106 2.86612 3.77664ZM12.2136 3.43904L16.854 3.43904C17.0198 3.43904 17.1787 3.50489 17.2959 3.6221C17.4132 3.73931 17.479 3.89828 17.479 4.06404V8.70443C17.479 9.04961 17.1992 9.32943 16.854 9.32943C16.5088 9.32943 16.229 9.04961 16.229 8.70443V5.57176L10.4417 11.3527C10.1975 11.5967 9.80176 11.5964 9.55782 11.3522C9.31387 11.108 9.31409 10.7123 9.5583 10.4683L15.3439 4.68904L12.2136 4.68904C11.8684 4.68904 11.5886 4.40922 11.5886 4.06404C11.5886 3.71887 11.8684 3.43904 12.2136 3.43904Z" fill="#F5F5F5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.5001 10.9168V17.3335H3.66674V4.50016H8.2684C8.31424 3.84933 8.47007 3.23516 8.7084 2.66683H3.66674C2.6584 2.66683 1.8334 3.49183 1.8334 4.50016V17.3335C1.8334 18.3418 2.6584 19.1668 3.66674 19.1668H16.5001C17.5084 19.1668 18.3334 18.3418 18.3334 17.3335V12.7502L16.5001 10.9168ZM17.6917 7.14933C18.0951 6.50766 18.3334 5.76516 18.3334 4.9585C18.3334 2.676 16.4909 0.833496 14.2084 0.833496C11.9259 0.833496 10.0834 2.676 10.0834 4.9585C10.0834 7.241 11.9259 9.0835 14.1992 9.0835C15.0059 9.0835 15.7576 8.84516 16.3901 8.44183L19.2501 11.3018L20.5517 10.0002L17.6917 7.14933ZM14.2084 7.25016C12.9434 7.25016 11.9167 6.2235 11.9167 4.9585C11.9167 3.6935 12.9434 2.66683 14.2084 2.66683C15.4734 2.66683 16.5001 3.6935 16.5001 4.9585C16.5001 6.2235 15.4734 7.25016 14.2084 7.25016Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 911 B

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.65 6.35C16.2 4.9 14.21 4 12 4C7.58001 4 4.01001 7.58 4.01001 12C4.01001 16.42 7.58001 20 12 20C15.73 20 18.84 17.45 19.73 14H17.65C16.83 16.33 14.61 18 12 18C8.69001 18 6.00001 15.31 6.00001 12C6.00001 8.69 8.69001 6 12 6C13.66 6 15.14 6.69 16.22 7.78L13 11H20V4L17.65 6.35Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@@ -0,0 +1,140 @@
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
src: url('./Inter-Regular.ttf');
}
body,
html {
font-family: 'Inter';
width: 100%;
height: 100%;
border: 0;
padding: 0;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.sidebar-panel-header {
width: 100%;
height: 35px;
line-height: 30px;
cursor: default;
background-color: #2e2e2e;
border-bottom: 2px solid #000000;
display: flex;
-webkit-app-region: drag;
user-select: none;
}
.titlebar-icon {
width: 20px;
height: 20px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.titlebar-icon-external {
content: url('./icons/external.svg');
}
.titlebar-icon-debug {
content: url('./icons/debug.svg');
}
.titlebar-icon-refresh {
content: url('./icons/refrsh_24.svg');
}
.titlebar-icon-inspect {
content: url('./icons/inspect_22.svg');
}
.titlebar-icon-close {
content: url('./icons/close_20.svg');
}
.icon-container {
display: flex;
justify-content: center;
align-items: center;
width: 35px;
height: 35px;
background-color: transparent;
color: #a7a7a7;
font-size: 12px;
position: relative;
-webkit-app-region: no-drag;
opacity: 0.7;
cursor: pointer;
}
.icon-container:hover {
opacity: 1;
color: #f8f8f8;
background-color: #555555;
}
.viewer-no-root-alert {
background-color: #755000;
color: #eeeeee;
margin: 5px;
padding: 10px;
-webkit-transition: opacity 500ms;
visibility: hidden;
}
.viewer-no-root-alert-asterisk {
background-color: rgba(0, 0, 0, 0.6);
padding: 5px;
}
.viewer-icon-highlighted {
opacity: 1;
}
.title {
display: block;
color: #ccc;
margin-left: 16px;
font-size: 12px;
line-height: 35px;
}
.title:hover {
color: white;
}
.hidden {
display: none !important;
}
.webview-container {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
background-color: var(--theme-color-bg-1);
background-image: linear-gradient(45deg, var(--theme-color-bg-0) 25%, transparent 25%),
linear-gradient(-45deg, var(--theme-color-bg-0) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, var(--theme-color-bg-0) 75%),
linear-gradient(-45deg, transparent 75%, var(--theme-color-bg-0) 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
}
.dialog-layer {
position: absolute;
z-index: 666;
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Noodl Viewer</title>
<link href="../../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet">
<link href="assets/style.css" rel="stylesheet">
<script type="text/javascript" src="../../assets/lib/jquery-min.js"></script>
<script>
const path = process.env.devMode !== 'yes' ? '.' : 'http://localhost:8080/src/frames/viewer-frame';
document.write(`<script defer src="${path}/index.bundle.js"><\/script>`);
</script>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,17 @@
import '../../editor/src/styles/custom-properties/animations.css';
import '../../editor/src/styles/custom-properties/fonts.css';
import '../../editor/src/styles/custom-properties/colors.css';
import PopupLayer from '../../editor/src/views/popuplayer';
import Viewer from './src/views/viewer';
Viewer.instance = new Viewer();
Viewer.instance.render();
$('body').append(Viewer.instance.el);
//add popup and dialog layers for the right click inspect menu to work
PopupLayer.instance = new PopupLayer();
document.body.appendChild(PopupLayer.instance.render().get(0));
const dialogLayer = document.createElement('div');
dialogLayer.classList.add('dialog-layer');
$('body').append(dialogLayer);

View File

@@ -0,0 +1,14 @@
<div class="container">
<div class="sidebar-panel-header">
<div class="title weburl" data-click="onTitleClicked">Viewer</div>
<div style="flex-grow: 1"></div>
<div class="icon-container" data-click="onTitleClicked">
<div class="titlebar-icon titlebar-icon-external"></div>
</div>
<div class="icon-container" data-click="onAttachIconClicked">
<div class="titlebar-icon titlebar-icon-close"></div>
</div>
</div>
<div class="webview-container">
</div>
</div>

View File

@@ -0,0 +1,179 @@
const View = require('../../../../shared/view');
const Config = require('../../../../shared/config/config');
const ViewerTemplate = require('../templates/viewer.html');
const { ipcRenderer } = require('electron');
const remote = require('@electron/remote');
require('@noodl/platform-electron');
require('../../../../editor/src/styles/custom-properties/colors.css');
const { platform, PlatformOS } = require('@noodl/platform');
const { CanvasView } = require('../../../../editor/src/views/VisualCanvas/CanvasView');
const { showContextMenuInPopup } = require('../../../../editor/src/views/ShowContextMenuInPopup');
const MenuDialogWidth = require('@noodl-core-ui/components/popups/MenuDialog');
class Viewer extends View {
constructor() {
super();
// remote.getCurrentWindow().webContents.openDevTools();
this.isWindows = platform.os === PlatformOS.Windows;
this.canvasView = new CanvasView({
onNavigationStateChanged: (state) => {
ipcRenderer.send('viewer-navigation-state', state);
}
});
ipcRenderer.on('viewer-refresh', () => {
this.canvasView.refresh();
ipcRenderer.send('viewer-refreshed');
});
ipcRenderer.on('viewer-focus', () => {
const window = remote.getCurrentWindow();
if (window && window.focusable) {
window.focus();
}
});
ipcRenderer.on('viewer-open-devtools', () => {
this.canvasView.openDevTools();
});
ipcRenderer.on('viewer-select-node', (sender, nodeId) => {
this.canvasView.setNodeSelected(nodeId);
});
ipcRenderer.on('viewer-set-zoom-factor', (sender, zf) => {
this.canvasView.setZoomFactor(zf);
});
ipcRenderer.on('viewer-set-route', (sender, route) => {
this.canvasView.setCurrentRoute(route);
});
ipcRenderer.on('viewer-set-inspect-mode', (sender, inspectMode) => {
this.canvasView.setInspectMode(inspectMode);
});
ipcRenderer.on('viewer-set-viewport-size', (sender, viewportSize) => {
this.canvasView.setViewportSize(viewportSize);
});
ipcRenderer.on('viewer-navigate-forward', (sender) => {
this.canvasView.navigateForward();
});
ipcRenderer.on('viewer-navigate-back', (sender) => {
this.canvasView.navigateBack();
});
ipcRenderer.on('viewer-capture-thumb', async ({ sender }) => {
// Capture a snapshot of the viewer
const image = await this.canvasView.captureThumbnail();
if (image) {
sender.send('viewer-capture-thumb-reply', image.toDataURL());
}
});
ipcRenderer.on('viewer-show-inspect-menu', ({ sender }, listItems) => {
const items = listItems.map((item) => ({
label: item.label,
onClick: () => {
sender.send('viewer-inspect-node', item.nodeId);
}
}));
showContextMenuInPopup({ title: 'Nodes behind cursor', items, width: MenuDialogWidth.Large });
});
}
render() {
const el = this.bindView($(ViewerTemplate), this);
if (this.el) this.el.append(el);
else this.el = el;
this.$('.webview-container').append(this.canvasView.render());
//make sure webview is never blurred so keyboard shortcuts always work (the webview is sending key input to the editor)
setTimeout(() => {
//give react a chance to render before focusing the first time
this.$('.webview-container webview')?.focus();
}, 100);
this.$('.webview-container webview').on('blur', (e) => {
e.target.focus();
});
getLocalIPs((result) => {
const ipAddress = result && result.length > 0 ? result[result.length - 1] : 'localhost';
const protocol = process.env.ssl ? 'https://' : 'http://';
const webUrl = `${protocol}${ipAddress}:${Config.PreviewServer.port}`;
this.$('.weburl').text(webUrl).attr('href', webUrl);
});
this._blockClicksAfterMovingWindow();
return this.el;
}
_blockClicksAfterMovingWindow() {
remote.getCurrentWindow().on('moved', () => {
this.blockNextClick = true;
});
document.addEventListener(
'click',
(e) => {
if (this.blockNextClick) {
e.stopPropagation();
this.blockNextClick = false;
}
},
true
); //capture phase
}
onAttachIconClicked() {
ipcRenderer.send('viewer-attach');
}
onTitleClicked() {
platform.openExternal(this.$('.title').text());
}
}
function getLocalIPs(callback) {
let ips = [];
const RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
const pc = new RTCPeerConnection({
// Don't specify any stun/turn servers, otherwise you will
// also find your public IP addresses.
iceServers: []
});
// Add a media line, this is needed to activate candidate gathering.
pc.createDataChannel('');
// onicecandidate is triggered whenever a candidate has been found.
pc.onicecandidate = function (e) {
if (!e.candidate) {
// Candidate gathering completed.
pc.close();
callback(ips);
return;
}
var ip = /^candidate:.+ (\S+) \d+ typ/.exec(e.candidate.candidate)[1];
if (ips.indexOf(ip) === -1)
// avoid duplicate entries (tcp/udp)
ips.push(ip);
};
pc.createOffer(
function (sdp) {
pc.setLocalDescription(sdp);
},
function onerror() {}
);
}
module.exports = Viewer;