diff --git a/src/components/editor.js b/src/components/editor.js
index e260ee3..0d5a620 100644
--- a/src/components/editor.js
+++ b/src/components/editor.js
@@ -123,9 +123,12 @@ class AppEditor extends Tonic {
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 = 'block'
// Display a preview for this type.
return
}
diff --git a/src/components/project.js b/src/components/project.js
index a56af33..34caa59 100644
--- a/src/components/project.js
+++ b/src/components/project.js
@@ -569,6 +569,8 @@ class AppProject extends Tonic {
const fullPath = path.join(dirPath, entry.name)
const oldChild = this.getNodeByProperty('id', fullPath, oldState)
+ if (entry.name === '.git') continue
+
const child = {
id: fullPath,
parent,
diff --git a/src/components/share.js b/src/components/share.js
new file mode 100644
index 0000000..ad78085
--- /dev/null
+++ b/src/components/share.js
@@ -0,0 +1,32 @@
+import Tonic from '@socketsupply/tonic'
+import { TonicDialog } from '@socketsupply/components/dialog'
+
+export class DialogShare extends TonicDialog {
+ async click (e) {
+ super.click(e)
+
+ const el = Tonic.match(e.target, '[data-event]')
+ if (!el) return
+
+ const { event } = el.dataset
+
+ if (event === 'share') {
+ const app = this.props.parent
+ }
+ }
+
+ render () {
+ return this.html`
+
+
+ asdfsdf
+
+
+ `
+ }
+}
diff --git a/src/components/sprite.js b/src/components/sprite.js
index 53417c7..632bba4 100644
--- a/src/components/sprite.js
+++ b/src/components/sprite.js
@@ -44,6 +44,26 @@ class AppSprite extends Tonic {
l37.2-22.3v44.6L51.1,94.7z"/>
+
+
+
+
header [platform="darwin"] {
padding-left: 35%;
padding-right: 35%;
}
diff --git a/src/css/share.css b/src/css/share.css
new file mode 100644
index 0000000..281d353
--- /dev/null
+++ b/src/css/share.css
@@ -0,0 +1,47 @@
+dialog-share {
+ display: grid;
+ grid-template-rows: auto 1fr;
+ max-width: 500px;
+ min-height: 280px;
+ display: grid;
+ font-family: var(--tonic-monospace);
+}
+
+body.mobile dialog-share {
+ width: 90vw !important;
+ height: 50vh !important;
+}
+
+dialog-share header {
+ height: 46px;
+ text-align: center;
+ padding: 14px;
+ font-size: 12px;
+ color: var(--tonic-secondary);
+}
+
+dialog-share footer {
+ height: 50px;
+ display: grid;
+ grid-template-columns: 1fr auto;
+ gap: 10px;
+ padding: 0 16px;
+}
+
+dialog-share .centered {
+ position: absolute;
+ top: 0; left: 0; right: 0; bottom: 0;
+ display: grid;
+ justtify-content: center;
+ align-content: center;
+}
+
+dialog-share .centered .message {
+ display: inline-block;
+ width: 80%;
+ margin: auto;
+}
+
+dialog-share main {
+ padding: 16px;
+}
diff --git a/src/index.html b/src/index.html
index 9cb04da..2a1e6e3 100644
--- a/src/index.html
+++ b/src/index.html
@@ -15,9 +15,10 @@
object-src 'none';
"
>
+
+
-
diff --git a/src/index.js b/src/index.js
index c3d8328..0f44ccd 100644
--- a/src/index.js
+++ b/src/index.js
@@ -17,6 +17,7 @@ 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 { DialogShare } from './components/share.js'
components(Tonic)
@@ -255,7 +256,64 @@ class AppView extends Tonic {
}
async initNetwork () {
+ const { data: dataPeer } = await this.db.state.get('peer')
+ const { data: dataUser } = await this.db.state.get('user')
+ //
+ // once awaited, we know that we have discovered our nat type and advertised
+ // to the network that we can accept inbound connections from other peers
+ // the socket is now ready to be read from and written to.
+ //
+ const pk = Buffer.from(dataUser.publicKey).toString('base64')
+
+ const signingKeys = {
+ publicKey: dataUser.publicKey,
+ privateKey: dataUser.privateKey
+ }
+
+ let socket = this.socket
+
+ if (!this.state.isInitialized) {
+ socket = this.socket = await network({ ...dataPeer, signingKeys })
+ const info = await socket.getInfo()
+ console.log(info)
+ }
+
+ const { data: dataSubscriptions } = await this.db.subscriptions.readAll()
+
+ for (const [subscriptionId, subscription] of dataSubscriptions.entries()) {
+ if (!subscription.sharedKey) continue
+ if (socket.subclusters.get(subscriptionId)) continue
+
+ const subcluster = await socket.subcluster({ sharedKey: subscription.sharedKey })
+
+ const onMessage = async (value, packet) => {
+ const pid = Buffer.from(packet.packetId).toString('hex')
+ const scid = Buffer.from(packet.subclusterId).toString('base64')
+ const key = [channelId, pid].join('\xFF')
+
+ const { data: hasPacket } = await this.db.messages.has(key)
+ if (hasPacket) return
+
+
+ }
+
+ subcluster.on('message', (value, packet) => {
+ if (!packet.verified) return // gtfoa
+ if (packet.index !== -1) return // not interested
+
+ // messages must be parsable
+ try { value = JSON.parse(value) } catch { return }
+
+ // messages must have content
+ if (!value || !value.content) return
+
+ // messages must have a type
+ if (typeof value.type !== 'string') return
+
+ onMessage(value, packet)
+ })
+ }
}
async initData () {
@@ -265,7 +323,7 @@ class AppView extends Tonic {
}
this.db = {
- channels: await Database.open('shares'),
+ subscriptions: await Database.open('subscriptions'),
state: await Database.open('state')
}
@@ -288,7 +346,6 @@ class AppView extends Tonic {
const { data: dataPeer } = await this.db.state.has('peer')
if (!dataPeer) {
- const signingKeys = await Encryption.createKeyPair()
await this.db.state.put('peer', {
config: {
peerId: await Encryption.createId(),
@@ -296,6 +353,17 @@ class AppView extends Tonic {
}
})
}
+
+ const { data: dataUser } = await this.db.state.has('user')
+
+ if (!dataUser) {
+ const signingKeys = await Encryption.createKeyPair()
+
+ await this.db.state.put('user', {
+ ...signingKeys
+ })
+ }
+
}
async initApplication () {
@@ -563,6 +631,11 @@ class AppView extends Tonic {
if (event === 'run') {
this.exportProject()
}
+
+ if (event === 'open-dialog-share') {
+ const coDialogShare = document.querySelector('dialog-share')
+ if (coDialogShare) coDialogShare.show()
+ }
}
async connected () {
@@ -604,12 +677,13 @@ class AppView extends Tonic {
data-event="get-share"
>
+
@@ -638,6 +712,15 @@ class AppView extends Tonic {
+
+
+
+
`
}
@@ -652,4 +735,5 @@ window.onload = () => {
Tonic.add(AppSprite)
Tonic.add(AppTerminal)
Tonic.add(AppView)
+ Tonic.add(DialogShare)
}
diff --git a/src/template/demo-project/socket.ini b/src/template/demo-project/socket.ini
index 9f8f27f..98e2208 100644
--- a/src/template/demo-project/socket.ini
+++ b/src/template/demo-project/socket.ini
@@ -30,7 +30,7 @@ flags = "-O3"
headless = false
; The name of the program and executable to be output. Can't contain spaces or special characters. Required field.
-name = "templates"
+name = "demo-project"
; The binary output path. It's recommended to add this path to .gitignore.
; default value: "build"
@@ -142,11 +142,11 @@ flags = "-g"
; A unique ID that identifies the bundle (used by all app stores).
; It's required when `[meta] type` is not `"extension"`.
; It should be in a reverse DNS notation https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier#discussion
-bundle_identifier = "com.templates"
+bundle_identifier = "com.demo-project"
; A unique application protocol scheme to support deep linking
; If this value is not defined, then it is derived from the `[meta] bundle_identifier` value
-application_protocol = "templates"
+application_protocol = "demo-project"
; A string that gets used in the about dialog and package meta info.
; copyright = "(c) Beep Boop Corp. 1985"
@@ -164,7 +164,7 @@ lang = "en-us"
; maintainer = "Beep Boop Corp."
; The title of the app used in metadata files. This is NOT a window title. Can contain spaces and special characters. Defaults to name in a [build] section.
-title = "templates"
+title = "demo-project"
; Builds an extension when set to "extension".
; default value: ""