diff --git a/src/components/editor.js b/src/components/editor.js
index 4f27a39..a6f3eed 100644
--- a/src/components/editor.js
+++ b/src/components/editor.js
@@ -263,6 +263,7 @@ class AppEditor extends Tonic {
const coTerminal = document.querySelector('app-terminal')
const coProperties = document.querySelector('app-properties')
const coTabs = document.querySelector('editor-tabs')
+ const coEditor = document.querySelector('app-editor')
if (!coTabs.tab) return
@@ -278,13 +279,11 @@ class AppEditor extends Tonic {
}
coTerminal.info('Settings file updated.')
+ coEditor.refreshColors()
app.activatePreviewWindows()
}
- clearTimeout(this.debouncePropertiesRerender)
- this.debouncePropertiesRerender = setTimeout(() => {
- coProperties.reRender()
- }, 512)
+ coProperties.reRender()
try {
await fs.promises.writeFile(coTabs.tab.path, value)
@@ -364,7 +363,7 @@ class AppEditor extends Tonic {
{ token: 'variable.predefined', foreground: '4864AA' },
{ token: 'variable.parameter', foreground: '9CDCFE' },
{ token: 'constant', foreground: '569CD6' },
- { token: 'comment', foreground: '338c32' },
+ { token: 'comment', foreground: colors.secondary },
{ token: 'number', foreground: colors.accent },
{ token: 'number.hex', foreground: '5BB498' },
{ token: 'regexp', foreground: 'B46695' },
diff --git a/src/components/git-status.js b/src/components/git-status.js
new file mode 100644
index 0000000..ee91d26
--- /dev/null
+++ b/src/components/git-status.js
@@ -0,0 +1,49 @@
+import Tonic from '@socketsupply/tonic'
+import { exec } from 'socket:child_process'
+
+// TODO(@heapwolf): this should be a component
+class GitStatus extends Tonic {
+ async render () {
+ const app = this.props.app
+ const currentProject = app.state.currentProject
+
+ const { data: dataProject } = await app.db.projects.get(currentProject.projectId)
+
+ let gitStatus = { stdout: '', stderr: '' }
+
+ //
+ // Try to get the status of the project to tell the user what
+ // has changed and help them decide if they should publish.
+ //
+ try {
+ gitStatus = await exec('git status --porcelain', { cwd: dataProject.path })
+ } catch (err) {
+ gitStatus.stderr = err.message
+ }
+
+ if (gitStatus?.stderr.includes('command not found')) {
+ return this.html`
+ Git is not installed and is required to use this program.
+
+ `
+ }
+
+ return this.html`
+
Git Integration
+ ${gitStatus.stderr || gitStatus.stdout}
+ `
+ }
+}
+
+export default GitStatus
+export { GitStatus }
diff --git a/src/components/patch-requests.js b/src/components/patch-requests.js
new file mode 100644
index 0000000..7d41eec
--- /dev/null
+++ b/src/components/patch-requests.js
@@ -0,0 +1,46 @@
+import Tonic from '@socketsupply/tonic'
+import { exec } from 'socket:child_process'
+
+class PatchRequests extends Tonic {
+ async render () {
+ const app = this.props.app
+
+ const { data: dataPatches } = await app.db.patches.readAll()
+
+ let patches = []
+
+ for (const [patchId, patch] of dataPatches.entries()) {
+ patches.push(this.html`
+
+
+
+
+ |
+ ${patch.author} |
+ ${patch.date} |
+ ${patch.parent} |
+ ${patch.message} |
+
+ `)
+ }
+
+ return this.html`
+ Patch Requests
+
+
+ Actions |
+ Author |
+ Date |
+ Parent |
+ Commit Message |
+
+
+ ${patches}
+
+
+ `
+ }
+}
+
+export default PatchRequests
+export { PatchRequests }
diff --git a/src/components/project.js b/src/components/project.js
index bdc54d1..19e5013 100644
--- a/src/components/project.js
+++ b/src/components/project.js
@@ -334,7 +334,7 @@ class AppProject extends Tonic {
if (!node) this.getNodeFromElement(el.parentElement)
if (!node) return
- if (node.nonMovable && !node.type === 'project') return
+ if (node.nonMovable && node.type !== 'project') return
const container = el.querySelector('.label')
@@ -726,6 +726,7 @@ class AppProject extends Tonic {
selected: oldChild?.selected ?? 0,
state: oldChild?.state ?? 0,
id: project.path,
+ bundleId: project.bundleId,
projectId,
label: project.label,
isDirectory: false,
@@ -735,6 +736,11 @@ class AppProject extends Tonic {
children: []
}
+ if (!this.props.parent.state.currentProject) {
+ this.props.parent.state.currentProject = node
+ this.props.parent.reloadPreviewWindows()
+ }
+
tree.children.push(node)
if (project.path) {
diff --git a/src/components/properties.js b/src/components/properties.js
index f5f7a7c..1fd671a 100644
--- a/src/components/properties.js
+++ b/src/components/properties.js
@@ -6,38 +6,6 @@ import process from 'socket:process'
import Config from '../lib/config.js'
class AppProperties extends Tonic {
- async saveSettingsFile () {
- const app = this.props.parent
- const currentProject = app.state.currentProject
- const pathToSettingsFile = path.join(path.DATA, 'projects', 'settings.json')
- const coTabs = document.querySelector('editor-tabs')
- const coEditor = document.querySelector('app-editor')
-
- // if the user currently has the config file open in the editor...
- if (coTabs.tab?.isRootSettingsFile) {
- try {
- coEditor.value = JSON.stringify(app.state.settings, null, 2)
- } catch (err) {
- return notifications.create({
- type: 'error',
- title: 'Unable to save config file',
- message: err.message
- })
- }
- }
-
- try {
- const str = JSON.stringify(app.state.settings)
- await fs.promises.writeFile(pathToSettingsFile, str)
- } catch (err) {
- return notifications?.create({
- type: 'error',
- title: 'Error',
- message: 'Unable to update settings'
- })
- }
- }
-
async change (e) {
const el = Tonic.match(e.target, '[data-event]')
if (!el) return
@@ -60,7 +28,7 @@ class AppProperties extends Tonic {
previewWindow.active = !previewWindow.active
}
- await this.saveSettingsFile()
+ await app.saveSettingsFile()
app.activatePreviewWindows()
}
diff --git a/src/components/publish.js b/src/components/publish.js
index 42228ad..5fc9341 100644
--- a/src/components/publish.js
+++ b/src/components/publish.js
@@ -19,26 +19,10 @@ export class DialogPublish extends TonicDialog {
}
}
- async getProject () {
- const app = this.props.parent
- const currentProject = app.state.currentProject
- if (!currentProject) return
-
- let config = new Config(currentProject.id)
- let bundleId = await config.get('meta', 'bundle_identifier')
- bundleId = bundleId.replace(/"/g, '')
-
- const { data: hasProject } = await app.db.projects.has(bundleId)
-
- if (hasProject) {
- const { data: dataProject } = await app.db.projects.get(bundleId)
- return dataProject
- }
- }
-
async publish (type, value) {
const app = this.props.parent
- const dataProject = await this.getProject()
+ const currentProject = app.state.currentProject
+ const { data: dataProject } = await app.db.projects.get(currentProject.bundleId)
const opts = {
// TODO(@heapwolf): probably chain with previousId
@@ -197,8 +181,8 @@ export class DialogPublish extends TonicDialog {
this.publish('patch', Buffer.from(output.stdout)) // into the background
}
- const coProperties = document.querySelector('app-properties')
- coProperties.reRender()
+ const coProjectSummary = document.querySelector('view-project-summary')
+ coProjectSummary.reRender()
}
return this.html`
diff --git a/src/css/component-patch-requests.css b/src/css/component-patch-requests.css
new file mode 100644
index 0000000..6307c06
--- /dev/null
+++ b/src/css/component-patch-requests.css
@@ -0,0 +1,31 @@
+patch-requests table {
+ font-family: var(--tonic-monospace);
+ width: 100%;
+}
+
+patch-requests table thead {
+ text-align: left;
+}
+
+patch-requests table tr th {
+ height: 40px;
+ border-bottom: 1px solid var(--tonic-border);
+ color: var(--tonic-medium, #999);
+ font-weight: 500;
+ font: 12px/14px var(--tonic-subheader, 'Arial', sans-serif);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+}
+
+patch-requests table td {
+ padding: 8px 0px;
+ border-bottom: 1px solid var(--tonic-border);
+}
+
+patch-requests table td {
+ min-width: 120px;
+}
+
+patch-requests table tr:last-of-type td {
+ border-bottom: none;
+}
diff --git a/src/css/theme.css b/src/css/theme.css
index d1593fd..f3e12f5 100644
--- a/src/css/theme.css
+++ b/src/css/theme.css
@@ -17,7 +17,7 @@ body {
--tonic-window: rgba(255, 255, 255, 1);
--tonic-accent: rgba(56, 185, 255, 1);
--tonic-primary: rgba(54, 57, 61, 1);
- --tonic-secondary: rgba(232, 232, 228, 1);
+ --tonic-secondary: rgba(190, 190, 190, 1);
--tonic-light: rgba(153, 157, 160, 1);
--tonic-medium: rgba(153, 157, 160, 1);
--tonic-shadow: rgba(150, 150, 150, 0.25);
@@ -47,7 +47,7 @@ body {
--tonic-window: rgba(46, 46, 46, 1);
--tonic-accent: rgba(56, 185, 255, 1);
--tonic-primary: rgba(255, 255, 255, 1);
- --tonic-secondary: rgba(120, 120, 120, 1);
+ --tonic-secondary: rgba(93, 93, 93, 1);
--tonic-medium: rgba(153, 157, 160, 1);
--tonic-dark: rgba(28, 28, 28, 1);
--tonic-shadow: rgba(0, 0, 0, 0.3);
diff --git a/src/css/view-project-summary.css b/src/css/view-project-summary.css
index 6d03537..e2b6f3a 100644
--- a/src/css/view-project-summary.css
+++ b/src/css/view-project-summary.css
@@ -12,6 +12,13 @@ view-project-summary.show {
z-index: 30;
}
+view-project-summary h2 {
+ font-size: 20px;
+ text-transform: uppercase;
+ color: var(--tonic-info);
+ font-weight: 100;
+}
+
view-project-summary header span {
width: 100%;
text-align: center;
@@ -42,7 +49,7 @@ view-project-summary .sharing {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 20px;
- grid-template-rows: auto auto 1fr;
+ grid-template-rows: auto auto auto 1fr;
align-items: end;
}
@@ -62,7 +69,12 @@ view-project-summary #publish {
grid-area: 2 / 4;
}
-view-project-summary view-git-status {
+view-project-summary git-status {
grid-area: 3 / span 4;
align-self: start;
}
+
+view-project-summary patch-requests {
+ grid-area: 4 / span 4;
+ align-self: start;
+}
diff --git a/src/index.html b/src/index.html
index 0595cc7..d1cbffd 100644
--- a/src/index.html
+++ b/src/index.html
@@ -23,6 +23,7 @@
+
diff --git a/src/index.js b/src/index.js
index 8c91dc6..1a26393 100644
--- a/src/index.js
+++ b/src/index.js
@@ -16,11 +16,13 @@ import { ViewHome } from './views/home.js'
import { ViewImagePreview } from './views/image-preview.js'
import { ViewProjectSummary } from './views/project-summary.js'
+import { AppEditor } from './components/editor.js'
+import { GitStatus } from './components/git-status.js'
+import { PatchRequests } from './components/patch-requests.js'
import { AppTerminal } from './components/terminal.js'
import { AppProject } from './components/project.js'
import { AppProperties } from './components/properties.js'
import { AppSprite } from './components/sprite.js'
-import { AppEditor } from './components/editor.js'
import { DialogConfirm } from './components/confirm.js'
import { DialogPublish } from './components/publish.js'
import { DialogSubscribe } from './components/subscribe.js'
@@ -163,7 +165,7 @@ class AppView extends Tonic {
zoom: this.state.zoom[index] || '1'
}).toString()
- let currentProjectPath = this.getCurrentProjectPath()
+ let currentProjectPath = this.getCurrentProjectPath()
if (!currentProjectPath) return
const opts = {
@@ -432,7 +434,38 @@ class AppView extends Tonic {
const coProperties = document.querySelector('app-properties')
this.state.settings.previewMode = !this.state.settings.previewMode
- coProperties.saveSettingsFile()
+ this.saveSettingsFile()
+ }
+
+ async saveSettingsFile () {
+ const currentProject = this.state.currentProject
+ const pathToSettingsFile = path.join(path.DATA, 'settings.json')
+ const coTabs = document.querySelector('editor-tabs')
+ const coEditor = document.querySelector('app-editor')
+
+ // if the user currently has the config file open in the editor...
+ if (coTabs.tab?.isRootSettingsFile) {
+ try {
+ coEditor.value = JSON.stringify(this.state.settings, null, 2)
+ } catch (err) {
+ return notifications.create({
+ type: 'error',
+ title: 'Unable to save config file',
+ message: err.message
+ })
+ }
+ }
+
+ try {
+ const str = JSON.stringify(this.state.settings)
+ await fs.promises.writeFile(pathToSettingsFile, str)
+ } catch (err) {
+ return notifications?.create({
+ type: 'error',
+ title: 'Error',
+ message: 'Unable to update settings'
+ })
+ }
}
//
@@ -783,6 +816,8 @@ window.onload = () => {
Tonic.add(AppSprite)
Tonic.add(AppTerminal)
Tonic.add(AppView)
+ Tonic.add(GitStatus)
+ Tonic.add(PatchRequests)
Tonic.add(DialogConfirm)
Tonic.add(DialogPublish)
Tonic.add(DialogSubscribe)
diff --git a/src/views/project-summary.js b/src/views/project-summary.js
index 09532f2..9d8eac9 100644
--- a/src/views/project-summary.js
+++ b/src/views/project-summary.js
@@ -1,51 +1,6 @@
import Tonic from '@socketsupply/tonic'
-import { exec } from 'socket:child_process'
import { Encryption, sha256 } from 'socket:network'
-class ViewGitStatus extends Tonic {
- async render () {
- const app = this.props.app
- const currentProject = app.state.currentProject
-
- const { data: dataProject } = await app.db.projects.get(currentProject.projectId)
-
- let gitStatus = { stdout: '', stderr: '' }
-
- //
- // Try to get the status of the project to tell the user what
- // has changed and help them decide if they should publish.
- //
- try {
- gitStatus = await exec('git status --porcelain', { cwd: dataProject.path })
- } catch (err) {
- gitStatus.stderr = err.message
- }
-
- if (gitStatus?.stderr.includes('command not found')) {
- return this.html`
- Git is not installed and is required to use this program.
-
- `
- }
-
- return this.html`
- ${gitStatus.stderr || gitStatus.stdout}
- `
- }
-}
-
-Tonic.add(ViewGitStatus)
-
class ViewProjectSummary extends Tonic {
show () {
this.classList.add('show')
@@ -163,10 +118,13 @@ class ViewProjectSummary extends Tonic {
data-event="publish"
width="100%"
class="pull-right"
- >Publish
+ >Commit & Publish
+
+
+
-
-
+
+
`
}