diff options
-rw-r--r-- | graffiti.js | 8 | ||||
-rw-r--r-- | plugins/vue/index.html | 34 | ||||
-rw-r--r-- | plugins/vue/plugin.js | 58 | ||||
-rw-r--r-- | test.html | 4 | ||||
-rw-r--r-- | utils/logoot.js (renamed from logoot.js) | 0 |
5 files changed, 99 insertions, 5 deletions
diff --git a/graffiti.js b/graffiti.js index 57a7911..d28b64d 100644 --- a/graffiti.js +++ b/graffiti.js @@ -12,10 +12,11 @@ export default class { this.open = false this.eventTarget = new EventTarget() this.tagMap = {} + + this.#initialize() } - // CALL THIS BEFORE DOING ANYTHING ELSE - async initialize() { + async #initialize() { // Perform authorization this.authParams = await Auth.connect(this.graffitiURL) @@ -33,8 +34,9 @@ export default class { // Commence connection this.#connect() + } - // Wait until open + async waitTilOpen() { await new Promise(resolve => { this.eventTarget.addEventListener("graffitiOpen", () => resolve() ) }) diff --git a/plugins/vue/index.html b/plugins/vue/index.html new file mode 100644 index 0000000..ceea8c7 --- /dev/null +++ b/plugins/vue/index.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> +<head> + <script async src="https://ga.jspm.io/npm:es-module-shims@1.6.2/dist/es-module-shims.js"></script> + <script type="importmap">{ "imports": { + "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.45/vue.esm-browser.min.js" + }}</script> + <script type="module"> + import { createApp } from 'vue' + import GraffitiVue from './plugin.js' + + createApp() + .use(GraffitiVue, {url: "http://localhost:5001"}) + .mount('#app') + </script> +</head> +<body id="app"> + {{ $graffitiID }} + + <button @click="$graffitiToggleLogIn"> + Log In + </button> + + <graffiti-objects :tags="['asdf']" v-slot="{objects}"> + <li v-for="object in objects"> + {{object._tags}} + <button @click="object._remove()"> + ❌ + </button> + </li> + </graffiti-objects> + +</body> +</html> diff --git a/plugins/vue/plugin.js b/plugins/vue/plugin.js new file mode 100644 index 0000000..e5483c6 --- /dev/null +++ b/plugins/vue/plugin.js @@ -0,0 +1,58 @@ +import { ref, reactive } from 'vue' +import Graffiti from '../../graffiti.js' + +export default { + install(app, options) { + + const graffitiURL = options && 'url' in options? + options.url : 'https://graffiti.garden' + + // Initialize graffiti + const graffiti = new Graffiti(graffitiURL, ()=>reactive({})) + + // These ID need to change after opening + app.config.globalProperties.$graffitiID = ref(null) + graffiti.waitTilOpen().then(()=> { + app.config.globalProperties.$graffitiID.value = graffiti.myID + }) + + // Add logging in and out + app.config.globalProperties.$graffitiToggleLogIn = + graffiti.toggleLogIn.bind(graffiti) + + // A composable for subscribing and + // unsubscribing to tags that returns + // a reactive array of the results + app.component('GraffitiObjects', { + + props: ['tags'], + + watch: { + tags: { + async handler(newTags, oldTags=[]) { + // Subscribe to the new tags + await graffiti.subscribe(...newTags) + // Unsubscribe to the existing tags + await graffiti.unsubscribe(...oldTags) + }, + immediate: true, + deep: true + } + }, + + // Handle unmounting too + unmount() { + graffiti.unsubscribe(this.tags) + }, + + computed: { + objects() { + return graffiti.objectsByTags(...this.tags) + } + }, + + template: '<slot :objects="objects"></slot>' + }) + + } +} @@ -32,8 +32,8 @@ // Connect to a local Graffiti instance // (see the server README for how to n locally) - const graffiti = new Graffiti("http://localhost:5001") - await graffiti.initialize() + window.graffiti = new Graffiti("http://localhost:5001") + await graffiti.waitTilOpen() // Log in automatically if not already // and supply a log out button diff --git a/logoot.js b/utils/logoot.js index c8c7c02..c8c7c02 100644 --- a/logoot.js +++ b/utils/logoot.js |