mirror of
https://github.com/hoytech/strfry.git
synced 2025-06-18 01:08:51 +00:00
240 lines
6.8 KiB
JavaScript
240 lines
6.8 KiB
JavaScript
const bech32Ctx = genBech32('bech32');
|
|
|
|
function encodeBech32(prefix, inp) {
|
|
return bech32Ctx.encode(prefix, bech32Ctx.toWords(base16.decode(inp.toUpperCase())));
|
|
}
|
|
|
|
function decodeBech32(inp) {
|
|
return base16.encode(bech32Ctx.fromWords(bech32Ctx.decode(inp).words)).toLowerCase();
|
|
}
|
|
|
|
document.addEventListener('alpine:init', () => {
|
|
Alpine.data('obLogin', () => ({
|
|
loggedIn: false,
|
|
pubkey: '',
|
|
username: '',
|
|
|
|
init() {
|
|
let storage = JSON.parse(window.localStorage.getItem('auth') || '{}');
|
|
if (storage.pubkey) {
|
|
this.loggedIn = true;
|
|
this.pubkey = storage.pubkey;
|
|
this.username = storage.username;
|
|
}
|
|
},
|
|
|
|
async login() {
|
|
if (!window.nostr) {
|
|
window.location = "/login";
|
|
return;
|
|
}
|
|
|
|
let pubkey = await nostr.getPublicKey();
|
|
|
|
let response = await fetch(`/u/${pubkey}/metadata.json`);
|
|
let json = await response.json();
|
|
console.log(json);
|
|
|
|
let username = json.name;
|
|
if (username === undefined) username = pubkey.substr(0, 8) + '...';
|
|
if (username.length > 25) username = username.substr(0, 25) + '...';
|
|
|
|
this.pubkey = pubkey;
|
|
this.username = username;
|
|
window.localStorage.setItem('auth', JSON.stringify({ pubkey, username, }));
|
|
|
|
this.loggedIn = true;
|
|
},
|
|
|
|
myProfile() {
|
|
return `/u/${encodeBech32('npub', this.pubkey)}`;
|
|
},
|
|
|
|
logout() {
|
|
window.localStorage.setItem('auth', '{}');
|
|
|
|
this.loggedIn = false;
|
|
},
|
|
}));
|
|
|
|
Alpine.data('newPost', () => ({
|
|
init() {
|
|
},
|
|
|
|
async submit() {
|
|
this.$refs.msg.innerText = '';
|
|
|
|
let ev = {
|
|
created_at: Math.floor(((new Date()) - 0) / 1000),
|
|
kind: 1,
|
|
tags: [['t', 'oddbean']],
|
|
content: this.$refs.post.value,
|
|
};
|
|
|
|
ev = await window.nostr.signEvent(ev);
|
|
|
|
let resp = await fetch("/submit-post", {
|
|
method: "post",
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(ev),
|
|
});
|
|
|
|
let json = await resp.json();
|
|
|
|
if (json.message === 'ok' && json.written === true) {
|
|
window.location = `/e/${json.event}`
|
|
} else {
|
|
this.$refs.msg.innerText = `Sending note failed: ${json.message}`;
|
|
console.error(json);
|
|
}
|
|
},
|
|
}));
|
|
|
|
Alpine.data('newReply', (note) => ({
|
|
async init() {
|
|
let resp = await fetch(`/e/${note}/raw.json`);
|
|
this.repliedTo = await resp.json();
|
|
},
|
|
|
|
async submit() {
|
|
this.$refs.msg.innerText = '';
|
|
|
|
let ev = {
|
|
created_at: Math.floor(((new Date()) - 0) / 1000),
|
|
kind: 1,
|
|
tags: [],
|
|
content: this.$refs.post.value,
|
|
};
|
|
|
|
{
|
|
// e tags
|
|
|
|
let rootId;
|
|
for (let t of this.repliedTo.tags) {
|
|
if (t[0] === 'e' && t[3] === 'root') {
|
|
rootId = t[1];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!rootId) {
|
|
for (let t of this.repliedTo.tags) {
|
|
if (t[0] === 'e') {
|
|
rootId = t[1];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rootId) {
|
|
ev.tags.push(['e', rootId, '', 'root']);
|
|
ev.tags.push(['e', this.repliedTo.id, '', 'reply']);
|
|
} else {
|
|
ev.tags.push(['e', this.repliedTo.id, '', 'root']);
|
|
}
|
|
|
|
// p tags
|
|
|
|
let seenPTags = {};
|
|
|
|
for (let t of this.repliedTo.tags) {
|
|
if (t[0] === 'p' && !seenPTags[t[1]]) {
|
|
ev.tags.push(['p', t[1]]);
|
|
seenPTags[t[1]] = true;
|
|
}
|
|
}
|
|
|
|
if (!seenPTags[this.repliedTo.pubkey]) {
|
|
ev.tags.push(['p', this.repliedTo.pubkey]);
|
|
}
|
|
}
|
|
|
|
ev = await window.nostr.signEvent(ev);
|
|
|
|
let resp = await fetch("/submit-post", {
|
|
method: "post",
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(ev),
|
|
});
|
|
|
|
let json = await resp.json();
|
|
|
|
if (json.message === 'ok' && json.written === true) {
|
|
window.location = `/e/${json.event}`
|
|
} else {
|
|
this.$refs.msg.innerText = `Sending note failed: ${json.message}`;
|
|
console.error(json);
|
|
}
|
|
},
|
|
}))
|
|
});
|
|
|
|
|
|
document.addEventListener("click", async (e) => {
|
|
let parent = e.target.closest(".vote-context");
|
|
if (!parent) return;
|
|
|
|
let which = e.target.className;
|
|
if (which.length !== 1) return;
|
|
|
|
let note = parent.getAttribute('data-note');
|
|
|
|
e.target.className = 'loading';
|
|
e.target.innerText = '↻';
|
|
|
|
if (which === 'f') return; // not impl
|
|
|
|
|
|
try {
|
|
let ev = {
|
|
created_at: Math.floor(((new Date()) - 0) / 1000),
|
|
kind: 7,
|
|
tags: [],
|
|
content: which === 'u' ? '+' : '-',
|
|
};
|
|
|
|
{
|
|
let response = await fetch(`/e/${note}/raw.json`);
|
|
let liked = await response.json();
|
|
|
|
//for (let tag of liked.tags) {
|
|
// if (tag.length >= 2 && (tag[0] === 'e' || tag[0] === 'p')) ev.tags.push(tag);
|
|
//}
|
|
|
|
ev.tags.push(['e', liked.id]);
|
|
//ev.tags.push(['p', liked.pubkey]);
|
|
}
|
|
|
|
ev = await window.nostr.signEvent(ev);
|
|
|
|
let response = await fetch("/submit-post", {
|
|
method: "post",
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(ev),
|
|
});
|
|
|
|
let json = await response.json();
|
|
|
|
if (json.message === 'ok' && json.written === true) {
|
|
e.target.className = 'success';
|
|
e.target.innerText = '✔';
|
|
} else {
|
|
throw(Error(`Sending reaction note failed: ${json.message}`));
|
|
console.error(json);
|
|
}
|
|
} catch(err) {
|
|
console.error(err);
|
|
e.target.className = 'error';
|
|
e.target.innerText = '✘';
|
|
}
|
|
});
|