aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--locale/en_GB.json6
-rw-r--r--routes/note_fragment.php14
-rw-r--r--static/style.css33
-rw-r--r--templates/note.php15
-rw-r--r--templates/reply_button.php2
-rw-r--r--templates/reply_form.php11
-rw-r--r--templates/skeleton.php1
-rw-r--r--templates/write_note_form.php2
8 files changed, 79 insertions, 5 deletions
diff --git a/locale/en_GB.json b/locale/en_GB.json
index deda419..da09f77 100644
--- a/locale/en_GB.json
+++ b/locale/en_GB.json
@@ -8,6 +8,8 @@
"note.action.like": "Like",
"note.action.dislike": "Dislike",
"note.action.reshare": "Reshare",
+ "note.action.reply": "Reply",
+ "note.info.replyTo": "In reply to %s",
"timeline.local": "Local timeline",
"timeline.local.description": "This timeline shows all public indexable notes posted by users on this server.",
"placeholder": "There's nothing here.",
@@ -23,5 +25,7 @@
"login.action": "Log in",
"login.failed": "Invalid email address or password",
"writeNote.label": "Write a note",
- "writeNote.action": "Post"
+ "writeNote.action": "Post",
+ "writeReply.label": "Write a reply",
+ "writeReply.action": "Reply"
}
diff --git a/routes/note_fragment.php b/routes/note_fragment.php
index 9170e2b..83e7655 100644
--- a/routes/note_fragment.php
+++ b/routes/note_fragment.php
@@ -32,6 +32,20 @@ Router::getInstance()->mount('/fragment/note/:id/:action', function (array $args
render_template('interaction_button', ['action' => $args['action'], 'active' => $active, 'note' => $note]);
});
+Router::getInstance()->mount('/fragment/note/:id/reply', function (array $args) {
+ // replying to a note
+ $author = UserAccount::requireByCurrentSession();
+ $note = Note::find($args['id']);
+ if (isset($_POST['content'])) {
+ $reply = Note::create($author->actor, $_POST['content'], 'unk');
+ $reply->inReplyTo = $note;
+ $reply->threadApex = $note->threadApex ?? $note;
+ $reply->save();
+ $reply->publish();
+ }
+ render_template('reply_form');
+});
+
Router::getInstance()->mount('/fragment/note', function (array $args) {
// posting a new note
$author = UserAccount::requireByCurrentSession();
diff --git a/static/style.css b/static/style.css
index 01281d8..f963802 100644
--- a/static/style.css
+++ b/static/style.css
@@ -176,6 +176,15 @@ article.note {
}
}
+ .replyInfo a {
+ font-size: 10pt;
+ color: #555;
+ text-decoration: none;
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
.buttons {
margin-top: 8px;
padding: 0;
@@ -203,6 +212,9 @@ article.note {
&.reshare.active {
color: #21a821;
}
+ &.reply.active {
+ color: #0761b6;
+ }
}
}
}
@@ -247,7 +259,7 @@ form {
padding: 16px;
display: grid;
grid-auto-flow: row;
- gap: 16px;
+ gap: 8px;
max-width: max-content;
label:has(+ input, + textarea) {
@@ -294,6 +306,21 @@ form {
padding: 16px;
margin: 0;
}
+
+ &.noteReplyForm {
+ background: none;
+ border: none;
+ padding: 0;
+ margin: 0;
+ margin-top: 8px;
+ max-width: 100%;
+ input:not([type="checkbox"]),
+ textarea,
+ button {
+ width: 100%;
+ box-sizing: border-box;
+ }
+ }
}
.fullProfile {
@@ -322,3 +349,7 @@ form {
}
}
}
+
+[hidden] {
+ display: none;
+}
diff --git a/templates/note.php b/templates/note.php
index fdc0dc8..3fc86ba 100644
--- a/templates/note.php
+++ b/templates/note.php
@@ -27,17 +27,28 @@ if ($user != null) {
?>
</a>
</div>
+ <?php if (isset($note->inReplyTo)): ?>
+ <div class="replyInfo">
+ <a href="/@/<?= $note->inReplyTo->author->getFullHandle() ?>/note/<?= $note->inReplyTo->id ?>">
+ <?= sprintf(__('note.info.replyTo'),
+ '<b>' . $note->inReplyTo->author->displayName) . '</b>' ?>
+ </a>
+ </div>
+ <?php endif; ?>
<div class="content">
<?= $note->getFormattedContent('text/html') ?? htmlspecialchars($note->plainContent) ?>
</div>
<div class="buttons">
<?php foreach (['like', 'dislike', 'reshare'] as $action) {
- render_template('interaction_button', [
+ call_template('interaction_button', [
'action' => $action,
'note' => $note,
'active' => in_array(InteractionKind::from($action), $interKinds)
]);
- } ?>
+ }
+ call_template('reply_button', ['note' => $note]);
+ ?>
</div>
+ <?php call_template('reply_form', ['note' => $note]); ?>
</div>
</article> \ No newline at end of file
diff --git a/templates/reply_button.php b/templates/reply_button.php
new file mode 100644
index 0000000..6b755df
--- /dev/null
+++ b/templates/reply_button.php
@@ -0,0 +1,2 @@
+<button title="<?= __('note.action.reply') ?>" class="icon material-symbols-outlined reply"
+ _="on click send toggle to [me, next .noteReplyForm] on toggle toggle .active">reply</button> \ No newline at end of file
diff --git a/templates/reply_form.php b/templates/reply_form.php
new file mode 100644
index 0000000..84d8121
--- /dev/null
+++ b/templates/reply_form.php
@@ -0,0 +1,11 @@
+<form class="noteReplyForm" id="replyForm-<?= $note->id ?>"
+ _="on submit send toggle to previous <button.reply/> on toggle or submit toggle @hidden" hidden
+ hx-post="/fragment/note/<?= $note->id ?>/reply" hx-disabled-elt="find button" hx-swap="outerHTML">
+ <div class="row">
+ <label for="replyContent-<?= $note->id ?>"><?= __('writeReply.label') ?></label>
+ <textarea id="replyContent-<?= $note->id ?>" name="content" required></textarea>
+ </div>
+ <div class="row">
+ <button><?= __('writeReply.action') ?></button>
+ </div>
+</form> \ No newline at end of file
diff --git a/templates/skeleton.php b/templates/skeleton.php
index 072f812..e678957 100644
--- a/templates/skeleton.php
+++ b/templates/skeleton.php
@@ -11,6 +11,7 @@ $user = Digitigrade\Model\UserAccount::findByCurrentSession();
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:FILL@0..1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
+ <script src="https://unpkg.com/hyperscript.org@0.9.13"></script>
<script src="/static/language-switch.js" defer></script>
</head>
diff --git a/templates/write_note_form.php b/templates/write_note_form.php
index 49fcafc..38a9993 100644
--- a/templates/write_note_form.php
+++ b/templates/write_note_form.php
@@ -1,7 +1,7 @@
<form action="/todo" method="post" hx-post="/fragment/note" hx-swap="outerHTML" hx-disabled-elt="find button">
<div class="row">
<label for="noteContent"><?= __('writeNote.label') ?></label>
- <textarea name="content" id="noteContent"></textarea>
+ <textarea name="content" id="noteContent" required></textarea>
</div>
<div class="row">
<button><?= __('writeNote.action') ?></button>