aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Digitigrade/Model/Note.php13
-rw-r--r--Digitigrade/Model/NoteAttachment.php6
-rw-r--r--locale/en_GB.json1
-rw-r--r--static/form.css14
-rw-r--r--static/icons.css3
-rw-r--r--static/note.css63
-rw-r--r--templates/note.php17
-rw-r--r--templates/write_note_form.php11
8 files changed, 119 insertions, 9 deletions
diff --git a/Digitigrade/Model/Note.php b/Digitigrade/Model/Note.php
index 0164e7d..a4df99d 100644
--- a/Digitigrade/Model/Note.php
+++ b/Digitigrade/Model/Note.php
@@ -82,10 +82,14 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
$this->mentions = $this->findMentions();
$this->attachments = NoteAttachment::findAllWhere('note_id = ?', [$this->id]);
$this->extensions = $this->findExtensions();
+
+ // put attachments back in the right order
+ usort($this->attachments, fn($a, $b) => $a->index <=> $b->index);
}
protected function dehydrate() {
$this->saveMentions();
+ $this->saveAttachments();
$this->saveExtensions();
}
@@ -130,6 +134,15 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
}
}
+ private function saveAttachments() {
+ $index = 0;
+ foreach ($this->attachments as $att) {
+ $att->index = $index++;
+ $att->setOwnerId($this->id);
+ $att->save();
+ }
+ }
+
private function saveExtensions() {
$pdo = Db::getInstance()->getPdo();
foreach ($this->extensions as $uri => $obj) {
diff --git a/Digitigrade/Model/NoteAttachment.php b/Digitigrade/Model/NoteAttachment.php
index c47ec64..9e6a3d3 100644
--- a/Digitigrade/Model/NoteAttachment.php
+++ b/Digitigrade/Model/NoteAttachment.php
@@ -10,13 +10,13 @@ class NoteAttachment extends Model {
public string $href;
public ?string $description;
- protected function setOwnerId(int $id) {
+ public function setOwnerId(int $id) {
$this->noteId = $id;
}
protected function getUpdateWhereClause($db): ?string {
- if (self::findWhere('note_id = ?', [$this->noteId]) != null) {
- return "note_id = $this->noteId";
+ if (self::findWhere('note_id = ? AND index = ?', [$this->noteId, $this->index]) != null) {
+ return "note_id = $this->noteId AND index = $this->index";
}
return null;
}
diff --git a/locale/en_GB.json b/locale/en_GB.json
index e3e2a4c..9d2a2b7 100644
--- a/locale/en_GB.json
+++ b/locale/en_GB.json
@@ -72,6 +72,7 @@
"login.action": "Log in",
"login.failed": "Invalid email address or password",
"writeNote.label": "Write a note",
+ "writeNote.placeholder": "What's on your mind?",
"writeNote.summary.label": "Content warning (optional)",
"writeNote.scope.label": "Visibility",
"writeNote.action": "Post",
diff --git a/static/form.css b/static/form.css
index c14b0b7..b309f33 100644
--- a/static/form.css
+++ b/static/form.css
@@ -63,6 +63,20 @@ form:not(.nopanel):not([hidden]) {
&#writeNoteForm {
max-width: 100%;
+ .summaryAndContent {
+ input:has(+ textarea) {
+ margin-bottom: 0;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom: none;
+ + textarea {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+ }
+ }
+
.miniProfile {
display: grid;
grid-template-columns: max-content 1fr;
diff --git a/static/icons.css b/static/icons.css
index efbf8ca..8d6b7b5 100644
--- a/static/icons.css
+++ b/static/icons.css
@@ -99,4 +99,7 @@
&.delete-outline {
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z'/%3E%3C/svg%3E");
}
+ &.attach-file {
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M18 15.75q0 2.6-1.825 4.425T11.75 22t-4.425-1.825T5.5 15.75V6.5q0-1.875 1.313-3.187T10 2t3.188 1.313T14.5 6.5v8.75q0 1.15-.8 1.95t-1.95.8t-1.95-.8t-.8-1.95V6h2v9.25q0 .325.213.538t.537.212t.538-.213t.212-.537V6.5q-.025-1.05-.737-1.775T10 4t-1.775.725T7.5 6.5v9.25q-.025 1.775 1.225 3.013T11.75 20q1.75 0 2.975-1.237T16 15.75V6h2z'/%3E%3C/svg%3E");
+ }
}
diff --git a/static/note.css b/static/note.css
index 9b9eb65..0400b21 100644
--- a/static/note.css
+++ b/static/note.css
@@ -128,6 +128,69 @@ article.note {
}
}
+ .attachments {
+ padding: var(--spacing-single) 0;
+ display: grid;
+ grid-template-columns: auto;
+ grid-template-rows: auto;
+ grid-auto-flow: row;
+ width: 100%;
+ box-sizing: border-box;
+ gap: var(--spacing-single);
+
+ &:has(:nth-child(2)) {
+ grid-template-columns: auto auto;
+ }
+ &:has(:nth-child(3)) {
+ grid-template-columns: auto auto auto;
+ }
+ &:has(:nth-child(4)) {
+ grid-template-columns: auto auto;
+ grid-template-rows: auto auto;
+ }
+ &:has(:nth-child(5)) {
+ grid-template-columns: unset;
+ grid-template-rows: auto;
+ grid-auto-flow: column;
+ }
+
+ > * {
+ border-radius: var(--border-radius);
+ overflow: hidden;
+ display: flex;
+ &:has(img) {
+ background: black;
+ }
+ }
+
+ img {
+ width: 100%;
+ max-height: 16lh;
+ object-fit: contain;
+ object-position: center;
+ }
+
+ a.file {
+ border: var(--border);
+ border-radius: var(--border-radius);
+ background: var(--clr-panel-background);
+ color: var(--clr-foreground);
+ text-decoration: none;
+ padding: var(--spacing-single);
+ display: grid;
+ width: 100%;
+ box-sizing: border-box;
+ grid-auto-flow: column;
+ align-items: center;
+ justify-content: start;
+ gap: var(--spacing-half);
+ span {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
+ }
+ }
+
.buttons {
margin-top: var(--spacing-single);
padding: 0;
diff --git a/templates/note.php b/templates/note.php
index 4d05554..c69531b 100644
--- a/templates/note.php
+++ b/templates/note.php
@@ -77,6 +77,23 @@ if ($user != null) {
<?php endif; ?>
</div>
+ <?php if (count($note->attachments) > 0): ?>
+ <div class="attachments">
+ <?php foreach ($note->attachments as $attachment): ?>
+ <div>
+ <?php if (str_starts_with($attachment->type, 'image/')): ?>
+ <img src="<?= $attachment->href ?>">
+ <?php else: ?>
+ <a class="file" href="<?= $attachment->href ?>" target="_blank">
+ <span class="material-symbols attach-file"></span>
+ <span><?= $attachment->description ?? basename($attachment->href) ?></span>
+ </a>
+ <?php endif; ?>
+ </div>
+ <?php endforeach; ?>
+ </div>
+ <?php endif; ?>
+
<div class="buttons">
<?php foreach (['like', 'dislike', 'reshare'] as $action) {
$kind = InteractionKind::from($action);
diff --git a/templates/write_note_form.php b/templates/write_note_form.php
index d2dae61..b86e825 100644
--- a/templates/write_note_form.php
+++ b/templates/write_note_form.php
@@ -9,13 +9,12 @@
<div class="handle">@<?= $actor->handle ?></div>
</div>
</div>
- <div class="row">
+ <div class="row summaryAndContent">
<label for="noteContent"><?= __('writeNote.label') ?></label>
- <textarea name="content" id="noteContent" required autocomplete="off"></textarea>
- </div>
- <div class="row">
- <label for="noteSummary"><?= __('writeNote.summary.label') ?></label>
- <input type="text" id="noteSummary" name="summary" autocomplete="off">
+ <input type="text" id="noteSummary" name="summary" autocomplete="off"
+ placeholder="<?= __('writeNote.summary.label') ?>">
+ <textarea name="content" id="noteContent" required autocomplete="off"
+ placeholder="<?= __('writeNote.placeholder') ?>"></textarea>
</div>
<div class="row">
<label class="standalone"><?= __('writeNote.mentions.label') ?></label>