mirror of
https://github.com/hoytech/strfry.git
synced 2025-06-19 09:36:43 +00:00
wip
This commit is contained in:
@ -357,6 +357,23 @@ inline std::string stripUrls(std::string &content) {
|
||||
}
|
||||
|
||||
|
||||
struct ReplyCtx {
|
||||
uint64_t timestamp;
|
||||
TemplarResult rendered;
|
||||
};
|
||||
|
||||
struct RenderedEventCtx {
|
||||
std::string content;
|
||||
std::string timestamp;
|
||||
const Event *ev = nullptr;
|
||||
const User *user = nullptr;
|
||||
bool isFullThreadLoaded = false;
|
||||
bool eventPresent = true;
|
||||
bool abbrev = false;
|
||||
bool highlight = false;
|
||||
bool showActions = true;
|
||||
std::vector<ReplyCtx> replies;
|
||||
};
|
||||
|
||||
|
||||
struct EventThread {
|
||||
@ -444,25 +461,9 @@ struct EventThread {
|
||||
auto now = hoytech::curr_time_s();
|
||||
flat_hash_set<uint64_t> processedLevIds;
|
||||
|
||||
struct Reply {
|
||||
uint64_t timestamp;
|
||||
TemplarResult rendered;
|
||||
};
|
||||
|
||||
struct RenderedEvent {
|
||||
std::string content;
|
||||
std::string timestamp;
|
||||
const Event *ev = nullptr;
|
||||
const User *user = nullptr;
|
||||
bool isFullThreadLoaded = false;
|
||||
bool eventPresent = true;
|
||||
bool abbrev = false;
|
||||
bool highlight = false;
|
||||
std::vector<Reply> replies;
|
||||
};
|
||||
|
||||
std::function<TemplarResult(const std::string &)> process = [&](const std::string &id){
|
||||
RenderedEvent ctx;
|
||||
RenderedEventCtx ctx;
|
||||
|
||||
auto p = eventCache.find(id);
|
||||
if (p != eventCache.end()) {
|
||||
@ -508,7 +509,7 @@ struct EventThread {
|
||||
|
||||
struct {
|
||||
TemplarResult foundEvents;
|
||||
std::vector<Reply> orphanNodes;
|
||||
std::vector<ReplyCtx> orphanNodes;
|
||||
} ctx;
|
||||
|
||||
ctx.foundEvents = process(rootEventId);
|
||||
|
@ -2,6 +2,9 @@
|
||||
#include "WebData.h"
|
||||
|
||||
|
||||
#include "WebStaticFiles.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -93,7 +96,7 @@ void doSearch(lmdb::txn &txn, Decompressor &decomp, std::string_view search, std
|
||||
|
||||
TemplarResult renderCommunityEvents(lmdb::txn &txn, Decompressor &decomp, UserCache &userCache, const CommunitySpec &communitySpec) {
|
||||
AlgoScanner a(txn, communitySpec.algo);
|
||||
auto events = a.getEvents(txn, decomp, 300);
|
||||
auto events = a.getEvents(txn, decomp, 60);
|
||||
|
||||
std::vector<TemplarResult> rendered;
|
||||
auto now = hoytech::curr_time_s();
|
||||
@ -176,7 +179,20 @@ HTTPResponse WebServer::generateReadResponse(lmdb::txn &txn, Decompressor &decom
|
||||
EventThread et(txn, decomp, decodeBech32Simple(u.path[1]));
|
||||
body = et.render(txn, decomp, userCache);
|
||||
} else if (u.path.size() == 3) {
|
||||
if (u.path[2] == "raw.json") {
|
||||
if (u.path[2] == "reply") {
|
||||
auto ev = Event::fromIdExternal(txn, u.path[1]);
|
||||
ev.populateJson(txn, decomp);
|
||||
|
||||
RenderedEventCtx ctx;
|
||||
|
||||
ctx.timestamp = renderTimestamp(startTime / 1'000'000, ev.getCreatedAt());
|
||||
ctx.content = templarInternal::htmlEscape(ev.json.at("content").get_string(), false);
|
||||
ctx.ev = &ev;
|
||||
ctx.user = userCache.getUser(txn, decomp, ev.getPubkey());
|
||||
ctx.showActions = false;
|
||||
|
||||
body = tmpl::event::reply(ctx);
|
||||
} else if (u.path[2] == "raw.json") {
|
||||
auto ev = Event::fromIdExternal(txn, u.path[1]);
|
||||
ev.populateJson(txn, decomp);
|
||||
rawBody = tao::json::to_string(ev.json, 4);
|
||||
|
@ -79,6 +79,91 @@ document.addEventListener('alpine:init', () => {
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
// t tags
|
||||
|
||||
ev.tags.push(['t', 'oddbean']);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -17,10 +17,11 @@
|
||||
|
||||
<> | <a href="/e/$(ctx.ev->getParentNoteId())">parent</a> </> ?(ctx.ev->parent.size())
|
||||
|
||||
<br/>
|
||||
|
||||
<a href="">reply</a>
|
||||
<>
|
||||
| <a href="/e/$(ctx.ev->getNoteId())/reply">reply</a>
|
||||
| <a href="" class="f">flag</a>
|
||||
</> ?(ctx.showActions)
|
||||
|
||||
<>+$(ctx.ev->upVotes)</> ?(ctx.ev->upVotes)
|
||||
<>-$(ctx.ev->downVotes)</> ?(ctx.ev->downVotes)
|
||||
</div>
|
||||
|
12
src/apps/web/tmpls/event/reply.tmpl
Normal file
12
src/apps/web/tmpls/event/reply.tmpl
Normal file
@ -0,0 +1,12 @@
|
||||
<div x-data="newReply('$(ctx.ev->getNoteId())')" class="new-post">
|
||||
$(event::event(ctx))
|
||||
|
||||
<textarea id="post-text" name="post-text" x-ref="post" rows="8" cols="80" wrap="virtual"></textarea>
|
||||
|
||||
<div @click="submit" class="submit-button">
|
||||
<button>Reply</button>
|
||||
</div>
|
||||
|
||||
<div class="result-message" x-ref="msg">
|
||||
</div>
|
||||
</div>
|
Reference in New Issue
Block a user