-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
252 additions
and
222 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,15 +7,6 @@ import Tonic from '@socketsupply/tonic' | |
|
||
import { resizePNG } from '../lib/icon.js' | ||
|
||
function escapeCommitMessage (commitMessage) { | ||
return commitMessage | ||
.replace(/&/g, "&") | ||
.replace(/</g, "<") | ||
.replace(/>/g, ">") | ||
.replace(/"/g, """) | ||
.replace(/'/g, "'"); | ||
} | ||
|
||
function rgbaToHex (rgbaString) { | ||
const rgbaValues = rgbaString.match(/\d+/g) | ||
|
||
|
@@ -64,122 +55,31 @@ class AppEditor extends Tonic { | |
this.editor.setValue(s) | ||
} | ||
|
||
async click (e) { | ||
const el = Tonic.match(e.target, '[data-event]') | ||
if (!el) return | ||
|
||
const { event, value } = el.dataset | ||
|
||
const pickerOpts = { | ||
types: [ | ||
{ | ||
description: 'Images', | ||
accept: { | ||
'image/*': ['.png'] | ||
} | ||
} | ||
], | ||
excludeAcceptAllOption: true, | ||
multiple: false | ||
} | ||
|
||
if (event === 'size') { | ||
const [fileHandle] = await window.showOpenFilePicker(pickerOpts) | ||
|
||
/* const kFileSystemHandleFullName = Object | ||
.getOwnPropertySymbols(data) | ||
.find(s => s.description === 'kFileSystemHandleFullName') | ||
const pathToFile = fileHandle[kFileSystemHandleFullName] | ||
*/ | ||
|
||
const file = fileHandle.getFile() | ||
const buf = await file.arrayBuffer() | ||
|
||
if (value === 'all') { | ||
const imagePreview = this.querySelector('.image-preview') | ||
const blob = new Blob([buf], { type: 'image/png' }) | ||
const url = URL.createObjectURL(blob) | ||
;[...imagePreview.querySelectorAll('img')].forEach(img => (img.src = url)) | ||
return | ||
} | ||
|
||
const blob = await resizePNG(buf, parseInt(value)) | ||
|
||
el.src = URL.createObjectURL(blob) | ||
} | ||
} | ||
|
||
get selection () { | ||
this.editor.getModel().getValueInRange(this.editor.getSelection()) | ||
} | ||
|
||
async writeToDisk (projectNode, data) { | ||
const app = document.querySelector('app-view') | ||
const preview = document.querySelector('app-preview') | ||
const app = this.props.parent | ||
|
||
try { | ||
await fs.promises.writeFile(projectNode.id, data) | ||
} catch (err) { | ||
console.error(`Unable to write to ${dest}`, err) | ||
} | ||
|
||
this.props.parent.reloadPreviewWindows() | ||
app.reloadPreviewWindows() | ||
} | ||
|
||
async loadProjectNode (projectNode) { | ||
if (!projectNode) return | ||
|
||
const parent = this.props.parent | ||
const ext = path.extname(projectNode.id) | ||
const type = await lookup(ext.slice(1)) | ||
const elImagePreview = document.querySelector('.image-preview') | ||
elImagePreview.style.display = 'none' | ||
|
||
if (type.length) { | ||
if (/image/.test(type[0].mime)) { | ||
elImagePreview.style.display = 'grid' | ||
// Display a preview for this type. | ||
return | ||
} | ||
} | ||
|
||
this.projectNode = projectNode | ||
|
||
const fileName = projectNode.label | ||
const imagePreview = this.querySelector('.image-preview') | ||
|
||
if (projectNode.isDirectory && projectNode.parent.id === 'root') { | ||
// in this case we can read all the patch files in the database | ||
// and present them to the user in the form of "patch requests". | ||
|
||
/* | ||
* Each patch file has a header like this, so we can parse it, present | ||
* it, and the user can decide if they want to apply the patch or not. | ||
* | ||
* From 97d72567aeb446e2b58262e88623f77ad0f7044f Mon Sep 17 00:00:00 2001 | ||
* From: heapwolf <[email protected]> | ||
* Date: Thu, 14 Mar 2024 10:48:03 +0100 | ||
* Subject: [PATCH] fix write method and preview script | ||
* | ||
*/ | ||
} | ||
|
||
if (projectNode.isDirectory && fileName === 'icons') { | ||
const iconPath = path.join(projectNode.id, 'icon.png') | ||
const data = await fs.promises.readFile(iconPath) | ||
const blob = new Blob([data], { type: 'image/png' }) | ||
const url = URL.createObjectURL(blob) | ||
;[...imagePreview.querySelectorAll('img')].forEach(img => (img.src = url)) | ||
imagePreview.classList.add('show') | ||
return | ||
} | ||
|
||
imagePreview.classList.remove('show') | ||
const app = this.props.parent | ||
|
||
if (!projectNode.isDirectory && this.editor) { | ||
const ext = path.extname(projectNode.id) | ||
|
||
const mappings = parent.state.settings.extensionLanguageMappings | ||
const mappings = app.state.settings.extensionLanguageMappings | ||
const lang = mappings[ext] || ext.slice(1) | ||
monaco.editor.setModelLanguage(this.editor.getModel(), lang) | ||
let data = await fs.promises.readFile(projectNode.id, 'utf8') | ||
|
@@ -274,13 +174,13 @@ class AppEditor extends Tonic { | |
} | ||
|
||
async refreshSettings () { | ||
const parent = this.props.parent | ||
this.editor.updateOptions(parent.state.settings?.editorOptions || {}) | ||
const app = this.props.parent | ||
this.editor.updateOptions(app.state.settings?.editorOptions || {}) | ||
} | ||
|
||
connected () { | ||
let theme | ||
const parent = this.props.parent | ||
const app = this.props.parent | ||
|
||
this.editor = monaco.editor.create(this.querySelector('.editor'), { | ||
value: '', | ||
|
@@ -298,21 +198,23 @@ class AppEditor extends Tonic { | |
const model = this.editor.getModel() | ||
|
||
model.onDidChangeContent(async () => { | ||
if (!this.projectNode) return | ||
const currentProject = app.state.currentProject | ||
if (!currentProject) return | ||
|
||
const value = this.editor.getValue() | ||
const coTerminal = document.querySelector('app-terminal') | ||
|
||
if (this.projectNode.label === 'settings.json' && this.projectNode.parent.id === 'root') { | ||
if (currentProject.label === 'settings.json' && currentProject.parent.id === 'root') { | ||
|
||
try { | ||
this.props.parent.state.settings = JSON.parse(value) | ||
app.state.settings = JSON.parse(value) | ||
} catch (err) { | ||
coTerminal.error(`Unable to parse settings file (${err.message})`) | ||
return | ||
} | ||
|
||
coTerminal.info(`Settings file updated.`) | ||
parent.activatePreviewWindows() | ||
app.activatePreviewWindows() | ||
} | ||
|
||
clearTimeout(this.debouncePropertiesRerender) | ||
|
@@ -321,7 +223,7 @@ class AppEditor extends Tonic { | |
coProperties.reRender() | ||
}, 1024) | ||
|
||
this.writeToDisk(this.projectNode, value) | ||
this.writeToDisk(currentProject, value) | ||
}) | ||
|
||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { | ||
|
@@ -335,30 +237,6 @@ class AppEditor extends Tonic { | |
|
||
render () { | ||
return this.html` | ||
<div class="image-preview"> | ||
<div class="top"> | ||
<h1>Icon Preview</h1> | ||
<tonic-button data-event="size" data-value="all">Update</tonic-button> | ||
</div> | ||
<div class="bottom"> | ||
<div class="size size-128"> | ||
<img data-event="size" data-value="128"> | ||
<label>128x128</label> | ||
</div> | ||
<div class="size size-64"> | ||
<img data-event="size" data-value="64"> | ||
<label>64x64</label> | ||
</div> | ||
<div class="size size-32"> | ||
<img data-event="size" data-value="32"> | ||
<label>32x32</label> | ||
</div> | ||
<div class="size size-16"> | ||
<img data-event="size" data-value="16"> | ||
<label>16x16</label> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="editor"></div> | ||
` | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import fs from 'socket:fs' | ||
import path from 'socket:path' | ||
|
||
import Tonic from '@socketsupply/tonic' | ||
|
||
import * as ini from '../lib/ini.js' | ||
|
||
class AppImagePreview extends Tonic { | ||
async click (e) { | ||
const el = Tonic.match(e.target, '[data-event]') | ||
if (!el) return | ||
|
||
const { event, value } = el.dataset | ||
|
||
const pickerOpts = { | ||
types: [ | ||
{ | ||
description: 'Images', | ||
accept: { | ||
'image/*': ['.png'] | ||
} | ||
} | ||
], | ||
excludeAcceptAllOption: true, | ||
multiple: false | ||
} | ||
|
||
if (event === 'size') { | ||
const [fileHandle] = await window.showOpenFilePicker(pickerOpts) | ||
|
||
/* const kFileSystemHandleFullName = Object | ||
.getOwnPropertySymbols(data) | ||
.find(s => s.description === 'kFileSystemHandleFullName') | ||
const pathToFile = fileHandle[kFileSystemHandleFullName] | ||
*/ | ||
|
||
const file = fileHandle.getFile() | ||
const buf = await file.arrayBuffer() | ||
|
||
if (value === 'all') { | ||
const imagePreview = this.querySelector('.image-preview') | ||
const blob = new Blob([buf], { type: 'image/png' }) | ||
const url = URL.createObjectURL(blob) | ||
;[...imagePreview.querySelectorAll('img')].forEach(img => (img.src = url)) | ||
return | ||
} | ||
|
||
const blob = await resizePNG(buf, parseInt(value)) | ||
|
||
el.src = URL.createObjectURL(blob) | ||
} | ||
} | ||
|
||
show () { | ||
this.classList.add('show') | ||
} | ||
|
||
hide () { | ||
this.classList.remove('show') | ||
} | ||
|
||
async load (projectNode) { | ||
this.state.pathToFile = projectNode.id | ||
this.reRender() | ||
} | ||
|
||
async render () { | ||
const app = this.props.parent | ||
const settings = app.state.settings | ||
const currentProject = app.state.currentProject | ||
|
||
let src = '' | ||
|
||
if (!currentProject) return this.html`` | ||
|
||
const cwd = currentProject?.id | ||
|
||
try { | ||
const pathToConfigFile = path.join(cwd, 'socket.ini') | ||
src = await fs.promises.readFile(pathToConfigFile, 'utf8') | ||
} catch (err) { | ||
const notifications = document.querySelector('#notifications') | ||
notifications?.create({ | ||
type: 'error', | ||
title: 'Error', | ||
message: err.message | ||
}) | ||
} | ||
|
||
const getSizes = platform => ini | ||
.get(src, platform, 'icon_sizes') | ||
.replace(/"/g, '') | ||
.split(' ') | ||
.map(pair => { | ||
let { 0: size, 1: scale } = pair.split('@') | ||
scale = parseInt(scale) | ||
|
||
const src = this.state.pathToFile.replace(path.HOME, '/user/home') | ||
const scaled = size * scale | ||
|
||
return this.html` | ||
<div class="size"> | ||
<img data-event="size" width="${scaled}px" height="${scaled}px" src="${src}"> | ||
<label>${pair}</label> | ||
</div> | ||
` | ||
}) | ||
|
||
return this.html` | ||
<div class="top"> | ||
<h1>Icon Preview</h1> | ||
<tonic-button data-event="size" data-value="all">Update</tonic-button> | ||
</div> | ||
<div class="bottom"> | ||
<h2>MacOS</h2> | ||
<div class="icon-grid">${getSizes('mac')}</div> | ||
<h2>iOS</h2> | ||
<div class="icon-grid">${getSizes('ios')}</div> | ||
<h2>Linux</h2> | ||
<div class="icon-grid">${getSizes('linux')}</div> | ||
<h2>Windows</h2> | ||
<div class="icon-grid">${getSizes('win')}</div> | ||
</div> | ||
` | ||
} | ||
} | ||
|
||
export { AppImagePreview } | ||
export default AppImagePreview |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.