update
BIN
src/base/assets/penpot-logo/App Icon Rounded.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
src/base/assets/penpot-logo/App Icon.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
src/base/assets/penpot-logo/Linux/icon.png
Normal file
After Width: | Height: | Size: 16 KiB |
0
src/base/assets/penpot-logo/Windows/icon.ico
Normal file
BIN
src/base/assets/penpot-logo/logo-black.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
src/base/assets/penpot-logo/logo-full-black.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/base/assets/penpot-logo/logo-full-white.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
src/base/assets/penpot-logo/logo-white.png
Normal file
After Width: | Height: | Size: 9 KiB |
BIN
src/base/assets/penpot-logo/macOS App Icon.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
src/base/assets/penpot-logo/macOS/icon.icns
Normal file
BIN
src/base/assets/penpot-logo/macOS/macOS App Icon.icns
Normal file
|
@ -1,5 +1,5 @@
|
||||||
<sl-alert id="noinstance" variant="warning">
|
<sl-alert id="noinstance" variant="warning">
|
||||||
<sl-icon slot="icon" name="exclamation-triangle"></sl-icon>
|
<sl-icon slot="icon" name="exclamation-triangle"></sl-icon>
|
||||||
<strong>No Instance Detected</strong><br />
|
<strong>No Instance Detected</strong><br />
|
||||||
Your instance setting is not set, please set one. <a href="#" onclick="localStorage.setItem('Instance', 'https://design.penpot.app/'); window.api.send('ReloadApp')">Reset Setting</a>
|
Your instance setting is not set, please set one. <a href="#" onclick="localStorage.setItem('Instance', 'https://design.penpot.app/'); window.api.send('ReloadApp')">Reset Instance</a>
|
||||||
</sl-alert>
|
</sl-alert>
|
|
@ -7,7 +7,25 @@
|
||||||
<input style="width: -webkit-fill-available;" id="InstanceField" type="url" pattern="https?://.*" placeholder="https://design.penpot.app/" value=""/>
|
<input style="width: -webkit-fill-available;" id="InstanceField" type="url" pattern="https?://.*" placeholder="https://design.penpot.app/" value=""/>
|
||||||
<input id="InstanceSaveButton" type="button" value="Save" onclick="InstanceSave()" />
|
<input id="InstanceSaveButton" type="button" value="Save" onclick="InstanceSave()" />
|
||||||
</div>
|
</div>
|
||||||
<sl-details style="max-width: 320px;" summary="What is an instance?">A server running Penpot, is called an instance. There can be many and you don't really need to choose one, commonly you only need to choose the offiical one that is ran by Penpot or to self-host your own.</sl-details>
|
</div>
|
||||||
|
<!-- <div class="settings-section">
|
||||||
|
<div class="settings-section-header">
|
||||||
|
<h2>Theme</h2>
|
||||||
|
</div>
|
||||||
|
<div id="theme" class="settings-section-content">
|
||||||
|
<div onclick="localStorage.setItem('theme', 'light'); document.body.classList.add('theme-is-light'); document.body.classList.remove('theme-is-dark')" id="theme-select-light" class="theme-selection"><p>Light</p></div>
|
||||||
|
<div onclick="localStorage.setItem('theme', 'dark'); document.body.classList.add('theme-is-dark'); document.body.classList.remove('theme-is-light')" id="theme-select-dark" class="theme-selection"><p>Dark</p></div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="settings-section">
|
||||||
|
<div class="settings-section-header">
|
||||||
|
<h2>Help</h2>
|
||||||
|
</div>
|
||||||
|
<div class="settings-section-content">
|
||||||
|
<div style="display: flex; gap: 12px; justify-content: space-evenly; flex: auto;">
|
||||||
|
<a href="#" onclick="window.api.send('OpenHelp')">Help</a>
|
||||||
|
<a href="#" onclick="window.api.send('OpenOffline')">Selfhost</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,23 @@
|
||||||
<script src="../../node_modules/electron-tabs/dist/electron-tabs.js"></script>
|
<script src="../../node_modules/electron-tabs/dist/electron-tabs.js"></script>
|
||||||
<script src="./scripts/electron-tabs.js"></script>
|
<script src="./scripts/electron-tabs.js"></script>
|
||||||
<script src="./scripts/instance.js"></script>
|
<script src="./scripts/instance.js"></script>
|
||||||
|
<script src="./scripts/theme.js"></script>
|
||||||
<script src="./scripts/toggles.js"></script>
|
<script src="./scripts/toggles.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body onload="InstanceGet()">
|
<body onload="ThemeCheck(); InstanceGet()">
|
||||||
<drag></drag>
|
<drag></drag>
|
||||||
<sl-include src="./components/titlebar.html"></sl-include>
|
<sl-include src="./components/titlebar.html"></sl-include>
|
||||||
<sl-include src="./components/splash.html"></sl-include>
|
<sl-include src="./components/splash.html"></sl-include>
|
||||||
<sl-include src="./components/tabs.html"></sl-include>
|
<sl-include src="./components/tabs.html"></sl-include>
|
||||||
<sl-include src="./components/settings.html"></sl-include>
|
<sl-include src="./components/settings.html"></sl-include>
|
||||||
|
|
||||||
|
<div class="no-tabs-exist" style="display: none;">
|
||||||
|
<img src="./assets/penpot-logo/logo-white.png"/>
|
||||||
|
<h2>No tabs are opened</h2>
|
||||||
|
<p>Add a new tab to start making awesome things.</p>
|
||||||
|
<button onclick='document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav > div.buttons > button").click(); ATWC()'>Create a tab</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Alerts-->
|
<!-- Alerts-->
|
||||||
<sl-include class="alert-modal" src="./components/alerts/no-instance.html"></sl-include>
|
<sl-include class="alert-modal" src="./components/alerts/no-instance.html"></sl-include>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -29,12 +29,14 @@ if (!localStorage.getItem("firstTime")) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.querySelector("#InstanceField").value = localStorage.getItem('Instance')
|
document.querySelector("#InstanceField").value = localStorage.getItem('Instance')
|
||||||
}, 0o500);
|
}, 0o500);
|
||||||
// setTimeout(() => {
|
setTimeout(() => {
|
||||||
// if (document.querySelector("body > tab-group").shadowRoot.querySelector("div > div > webview").src === '') {
|
if (document.querySelector("tab-group").shadowRoot.querySelector("div > div > webview").src === '') {
|
||||||
// console.log('You need to set an instance.')
|
document.querySelector("tab-group").shadowRoot.querySelector("div > div > webview").style.opacity = '0'
|
||||||
// document.querySelector("body > titlebar > div.actions > div > button:nth-child(2)").click()
|
document.querySelector("tab-group").shadowRoot.querySelector("div > nav").style.opacity = '0'
|
||||||
// document.querySelector(".tdm-warnings").style.display = 'inherit'
|
console.log('You need to set an instance.')
|
||||||
// } else {
|
document.querySelector("body > titlebar > div.actions > div > button:nth-child(2)").click()
|
||||||
// console.log('An instance is set.')
|
document.querySelector(".tdm-warnings").style.display = 'inherit'
|
||||||
// }
|
} else {
|
||||||
// }, 1500);
|
console.log('An instance is set.')
|
||||||
|
}
|
||||||
|
}, 1500);
|
7
src/base/scripts/theme.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
function ThemeCheck() {
|
||||||
|
if (localStorage.getItem('theme') === 'light') {
|
||||||
|
document.body.classList.add('theme-is-light')
|
||||||
|
} else {
|
||||||
|
document.body.classList.add('theme-is-dark')
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,25 @@ function ToggleSettings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect if there are no tabs
|
||||||
|
setTimeout(() => {
|
||||||
|
document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav > div.tabs > div > span.tab-close").addEventListener('click', function(){ATWC()})
|
||||||
|
document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav > div.buttons > button").addEventListener('click', function(){ATWC()})
|
||||||
|
}, 2000)
|
||||||
|
function ATWC() {
|
||||||
|
var element = document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav > div.tabs > *")
|
||||||
|
if (typeof(element) != 'undefined' && element != null)
|
||||||
|
{
|
||||||
|
document.querySelector('.no-tabs-exist').style.display = 'none'
|
||||||
|
document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav > div.tabs > div > span.tab-close").addEventListener('click', function(){ATWC()})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.querySelector('.no-tabs-exist').style.display = 'inherit'
|
||||||
|
document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav > div.tabs > div > span.tab-close").addEventListener('click', function(){ATWC()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Alerts
|
// Alerts
|
||||||
/// Docs: https://shoelace.style/getting-started/usage#methods
|
/// Docs: https://shoelace.style/getting-started/usage#methods
|
||||||
/// No Instance
|
/// No Instance
|
||||||
|
@ -18,4 +37,4 @@ setTimeout(() => {
|
||||||
if (document.querySelector("#InstanceField").value === "") {
|
if (document.querySelector("#InstanceField").value === "") {
|
||||||
ShowNoInstance()
|
ShowNoInstance()
|
||||||
}
|
}
|
||||||
}, 0o500);
|
}, 1000);
|
|
@ -1 +1 @@
|
||||||
body{background:#18181a;font-family:arial}.titlebar{position:fixed;top:0px;right:0px;width:max-content;text-align:right;margin:4px 4px 0px 0px;cursor:default;z-index:5;app-region:no-drag;display:flex}.titlebar .linux-titlebar{display:none}.titlebar button{width:32px;height:32px;font-size:0px;border:none;border-radius:6px;background:rgba(0,0,0,0)}.titlebar button:hover{background:#303236}.titlebar button svg{width:16px;height:16px;filter:invert(1)}sl-include.alert-modal{position:fixed;z-index:50;bottom:24px;left:50%;transform:translate(-50%);width:max-content}drag{position:fixed;top:0px;left:0px;width:100%;height:50px;app-region:drag;z-index:1}.dropdown-modal{position:fixed;top:40px;right:0px;z-index:50;display:none;flex-direction:column;background:#242428;border-radius:6px;border:1px #36363b solid;margin:6px;min-width:250px;width:300px;transition:1s all}.dropdown-modal div:nth-child(1)>div.settings-section-header{border-radius:4px 4px 0px 0px}.dropdown-modal .settings-section-header{background:#303236;padding:6px 0px 6px 16px;font-size:12px}.dropdown-modal .settings-section-header h2{margin:0px}.dropdown-modal .settings-section-content{display:flex;margin:12px}.dropdown-modal .settings-section-content input{padding:6px 12px;border-radius:4px;border:1px #656565 solid;margin-right:6px}.dropdown-modal .settings-section-content input#InstanceSaveButton{background:#575151;color:#fff;border:none;border-radius:4px;padding:0px 12px}
|
.theme-is-light{background:#fff}.theme-is-light .titlebar{filter:invert(1)}.theme-is-light #theme-select-light{border-color:#00ff89;color:#00ff89}.theme-is-dark{background:#18181a}.theme-is-dark #theme-select-dark{border-color:#00ff89;color:#00ff89}body{font-family:arial}.titlebar{position:fixed;top:0px;right:0px;width:max-content;text-align:right;margin:4px 4px 0px 0px;cursor:default;z-index:5;app-region:no-drag;display:flex}.titlebar .linux-titlebar{display:none}.titlebar button{width:32px;height:32px;font-size:0px;border:none;border-radius:6px;background:rgba(0,0,0,0)}.titlebar button:hover{background:#303236}.titlebar button svg{width:16px;height:16px;filter:invert(1)}sl-include.alert-modal{position:fixed;z-index:50;bottom:24px;left:50%;transform:translate(-50%);width:max-content}drag{position:fixed;top:0px;left:0px;width:100%;height:50px;app-region:drag;z-index:1}.dropdown-modal{position:fixed;top:40px;right:0px;z-index:50;display:none;flex-direction:column;background:#242428;border-radius:6px;border:1px #36363b solid;margin:6px;min-width:250px;width:300px;transition:1s all}.dropdown-modal div:nth-child(1)>div.settings-section-header{border-radius:4px 4px 0px 0px}.dropdown-modal .settings-section-header{background:#303236;padding:6px 0px 6px 16px;font-size:12px}.dropdown-modal .settings-section-header h2{margin:0px}.dropdown-modal .settings-section-content{display:flex;margin:12px}.dropdown-modal .settings-section-content input{padding:6px 12px;border-radius:4px;border:1px #656565 solid;margin-right:6px}.dropdown-modal .settings-section-content input#InstanceSaveButton{background:#575151;color:#fff;border:none;border-radius:4px;padding:0px 12px}div#theme{display:flex;justify-content:space-evenly;gap:12px}.theme-selection{border:2px #7d7d7d solid;border-radius:10px;padding:12px 32px;width:100%;text-align:center}.theme-selection p{margin:0px}div#theme-select-light{color:#000;background:#fff}div#theme-select-dark{color:#fff;background:#232222}.settings-section-content a{background:#3c413e;color:#fff;text-decoration:none;padding:12px 24px;border-radius:10px;width:100%;text-align:center;cursor:default}.no-tabs-exist{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%);text-align:center}.no-tabs-exist img{width:54px}.no-tabs-exist button{color:#000;background:#00ff89;border:none;border-radius:3rem;padding:12px 24px;transition:.3s background,.3s color}.no-tabs-exist button:hover{color:#000;background:#e6e6e6;transition:.3s background,.3s color}
|
||||||
|
|
|
@ -1,5 +1,22 @@
|
||||||
body {
|
.theme-is-light {
|
||||||
|
background: #ffffff;
|
||||||
|
.titlebar {
|
||||||
|
filter: invert(1)
|
||||||
|
}
|
||||||
|
#theme-select-light {
|
||||||
|
border-color: #00ff89;
|
||||||
|
color: #00ff89;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.theme-is-dark {
|
||||||
background: #18181a;
|
background: #18181a;
|
||||||
|
#theme-select-dark {
|
||||||
|
border-color: #00ff89;
|
||||||
|
color: #00ff89;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
font-family: arial;
|
font-family: arial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,3 +114,61 @@ drag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#theme {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.theme-selection {
|
||||||
|
border: 2px #7d7d7d solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 12px 32px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.theme-selection p {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
div#theme-select-light {
|
||||||
|
color: black;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
div#theme-select-dark {
|
||||||
|
color: white;
|
||||||
|
background: #232222;
|
||||||
|
}
|
||||||
|
.settings-section-content a {
|
||||||
|
background: #3c413e;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-tabs-exist {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
img {
|
||||||
|
width: 54px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
color: black;
|
||||||
|
background: #00ff89;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3rem;
|
||||||
|
padding: 12px 24px;
|
||||||
|
transition: 0.3s background, 0.3s color;
|
||||||
|
&:hover {
|
||||||
|
color: black;
|
||||||
|
background: #e6e6e6;
|
||||||
|
transition: 0.3s background, 0.3s color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,7 +79,6 @@ module.exports = {
|
||||||
accelerator: 'CmdOrCtrl+R',
|
accelerator: 'CmdOrCtrl+R',
|
||||||
click: async () => {
|
click: async () => {
|
||||||
mainWindow.webContents.executeJavaScript(`document.querySelector("tab-group").shadowRoot.querySelector("webview.visible").reload()`)
|
mainWindow.webContents.executeJavaScript(`document.querySelector("tab-group").shadowRoot.querySelector("webview.visible").reload()`)
|
||||||
setTimeout(() => {Platform.CSS()}, 1000)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -87,7 +86,7 @@ module.exports = {
|
||||||
accelerator: 'CmdOrCtrl+Shift+R',
|
accelerator: 'CmdOrCtrl+Shift+R',
|
||||||
click: async () => {
|
click: async () => {
|
||||||
mainWindow.reload()
|
mainWindow.reload()
|
||||||
setTimeout(() => {Platform.CSS()}, 2000)
|
setTimeout(() => {Platform.CSS()}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ role: 'toggleDevTools' },
|
{ role: 'toggleDevTools' },
|
||||||
|
|
|
@ -6,7 +6,9 @@ contextBridge.exposeInMainWorld( "api", { send: (channel, data) => {let validCha
|
||||||
"ReloadApp",
|
"ReloadApp",
|
||||||
"MaximizeWindow",
|
"MaximizeWindow",
|
||||||
"UnmaximizeWindow",
|
"UnmaximizeWindow",
|
||||||
"MinimizeWindow"
|
"MinimizeWindow",
|
||||||
|
"OpenHelp",
|
||||||
|
"OpenOffline"
|
||||||
]
|
]
|
||||||
if (validChannels.includes(channel)) {ipcRenderer.send(channel, data)}}})
|
if (validChannels.includes(channel)) {ipcRenderer.send(channel, data)}}})
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const {app, BrowserWindow, ipcMain, ipcRenderer} = require('electron')
|
const {app, BrowserWindow, ipcMain, ipcRenderer, shell} = require('electron')
|
||||||
const windowStateKeeper = require('electron-window-state')
|
const windowStateKeeper = require('electron-window-state')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
|
@ -7,7 +7,10 @@ const Platform = require('./platform')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
create: function () {
|
create: function () {
|
||||||
let mainWindowState = windowStateKeeper({defaultWidth: 1400,defaultHeight: 900})
|
let mainWindowState = windowStateKeeper({ // Remember the positiona and size of the window
|
||||||
|
defaultWidth: 1400,
|
||||||
|
defaultHeight: 900
|
||||||
|
})
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
// Size
|
// Size
|
||||||
x: mainWindowState.x,
|
x: mainWindowState.x,
|
||||||
|
@ -19,7 +22,7 @@ module.exports = {
|
||||||
// Theme
|
// Theme
|
||||||
darkTheme: true,
|
darkTheme: true,
|
||||||
transparent: global.transparent,
|
transparent: global.transparent,
|
||||||
vibrancy: "header",
|
vibrancy: "sidebar",
|
||||||
// Titlebar
|
// Titlebar
|
||||||
titleBarStyle: 'hidden',
|
titleBarStyle: 'hidden',
|
||||||
trafficLightPosition: { x: 16, y: 12 }, // for macOS
|
trafficLightPosition: { x: 16, y: 12 }, // for macOS
|
||||||
|
@ -45,6 +48,8 @@ module.exports = {
|
||||||
ipcMain.on('MaximizeWindow', () => {mainWindow.maximize()})
|
ipcMain.on('MaximizeWindow', () => {mainWindow.maximize()})
|
||||||
ipcMain.on('UnmaximizeWindow', () => {mainWindow.restore()})
|
ipcMain.on('UnmaximizeWindow', () => {mainWindow.restore()})
|
||||||
ipcMain.on('MinimizeWindow', () => {mainWindow.minimize()})
|
ipcMain.on('MinimizeWindow', () => {mainWindow.minimize()})
|
||||||
|
ipcMain.on('OpenHelp', () => {shell.openExternal('https://sudovanilla.com/docs/penpot-desktop/')})
|
||||||
|
ipcMain.on('OpenOffline', () => {shell.openExternal('https://sudovanilla.com/docs/penpot-desktop/features/offline-use/')})
|
||||||
|
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
// Move Tabs when entering or existing fullscreen on macOS
|
// Move Tabs when entering or existing fullscreen on macOS
|
||||||
|
@ -55,7 +60,6 @@ module.exports = {
|
||||||
mainWindow.on('focus', (e, cmd) => {mainWindow.webContents.executeJavaScript(`document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav").style.opacity = '1'`)})
|
mainWindow.on('focus', (e, cmd) => {mainWindow.webContents.executeJavaScript(`document.querySelector("body > sl-include:nth-child(4) > tab-group").shadowRoot.querySelector("div > nav").style.opacity = '1'`)})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Other Functions
|
// Other Functions
|
||||||
mainWindowState.manage(mainWindow)
|
mainWindowState.manage(mainWindow)
|
||||||
Menu.MainMenu()
|
Menu.MainMenu()
|
||||||
|
|