aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorwinter2025-01-28 22:00:20 +0000
committerwinter2025-01-28 22:00:20 +0000
commit093b34db9498d9ce1155c1fd8a59646aa483f85d (patch)
treeca596c39d6e001f118b8381cf77d746300add468
parent1af3a4e00ec63755a90109d8a63a1b6f6d95def6 (diff)
add upload/attach file feature for writing notes
-rw-r--r--Digitigrade/Model/NoteAttachment.php9
-rw-r--r--locale/en_GB.json2
-rw-r--r--routes/note_fragment.php19
-rw-r--r--static/misc.css2
-rw-r--r--templates/attachment_pill.php22
-rw-r--r--templates/write_note_form.php9
6 files changed, 62 insertions, 1 deletions
diff --git a/Digitigrade/Model/NoteAttachment.php b/Digitigrade/Model/NoteAttachment.php
index 9e6a3d3..1ca0064 100644
--- a/Digitigrade/Model/NoteAttachment.php
+++ b/Digitigrade/Model/NoteAttachment.php
@@ -10,6 +10,15 @@ class NoteAttachment extends Model {
public string $href;
public ?string $description;
+ public static function fromStorageObject(StorageObject $obj, int $index, ?string $description = null) {
+ $a = new self();
+ $a->index = $index;
+ $a->type = $obj->mimetype;
+ $a->href = $obj->getUrl();
+ $a->description = $description;
+ return $a;
+ }
+
public function setOwnerId(int $id) {
$this->noteId = $id;
}
diff --git a/locale/en_GB.json b/locale/en_GB.json
index 9d2a2b7..c7bccdf 100644
--- a/locale/en_GB.json
+++ b/locale/en_GB.json
@@ -79,6 +79,8 @@
"writeNote.mentions.label": "Mentioned users",
"writeNote.mentions.add.action": "Add a mention",
"writeNote.mentions.placeholder": "someone@social.example",
+ "writeNote.attachments.label": "Attached files",
+ "writeNote.attachments.add.action": "Add a file",
"writeReply.label": "Write a reply",
"writeReply.action": "Reply",
"followRequests.pageTitle": "Pending follow requests",
diff --git a/routes/note_fragment.php b/routes/note_fragment.php
index 9d3b9bb..02655ec 100644
--- a/routes/note_fragment.php
+++ b/routes/note_fragment.php
@@ -6,9 +6,13 @@ use Digitigrade\Model\Actor;
use Digitigrade\Model\Interaction;
use Digitigrade\Model\InteractionKind;
use Digitigrade\Model\Note;
+use Digitigrade\Model\NoteAttachment;
use Digitigrade\Model\NotePrivacyScope;
+use Digitigrade\Model\StorageObject;
use Digitigrade\Model\UserAccount;
use Digitigrade\Router;
+use Digitigrade\StorageProvider;
+use Digitigrade\StorageProvider\FilesystemStorage;
Router::getInstance()->mount('/fragment/note/:id', function (array $args) {
if ($_SERVER['REQUEST_METHOD'] != 'DELETE') {
@@ -104,6 +108,11 @@ Router::getInstance()->mount('/fragment/note', function (array $args) {
foreach (($_POST['mentions'] ?? []) as $uid) {
$note->mentions[] = Actor::find($uid);
}
+ $index = 0;
+ foreach (($_POST['attachments'] ?? []) as $oid) {
+ $obj = StorageObject::findByOid($oid);
+ $note->attachments[] = NoteAttachment::fromStorageObject($obj, $index++, $obj->filename);
+ }
$note->save();
$note->publish();
$note->processTimelineAdditions();
@@ -128,4 +137,14 @@ Router::getInstance()->mount('/fragment/note/mentionPill', function (array $args
// start editing
render_template('user_mention_pill', ['type' => 'edit']);
}
+});
+
+Router::getInstance()->mount('/fragment/note/attachmentPill', function (array $args) {
+ // adding an attachment to a new post
+ if (isset($_FILES['file'])) {
+ // store the file and return a pill for it
+ // TODO: allow other providers
+ $obj = StorageObject::createFromUpload(FilesystemStorage::class, $_FILES['file']);
+ render_template('attachment_pill', ['type' => 'file', 'oid' => $obj->oid, 'name' => $obj->filename]);
+ }
}); \ No newline at end of file
diff --git a/static/misc.css b/static/misc.css
index 0c18970..8013403 100644
--- a/static/misc.css
+++ b/static/misc.css
@@ -140,5 +140,5 @@ pre {
}
[hidden] {
- display: none;
+ display: none !important;
}
diff --git a/templates/attachment_pill.php b/templates/attachment_pill.php
new file mode 100644
index 0000000..76fc590
--- /dev/null
+++ b/templates/attachment_pill.php
@@ -0,0 +1,22 @@
+<?php
+$type ??= 'add';
+?>
+
+<?php if ($type == 'add'): ?>
+
+ <button id="writeNoteAttachmentPillAdder" type="button" class="inlinePill" type="button"
+ _="on click set f to #noteAttachmentFile then f.click()">
+ <span class="pillIcon material-symbols add"></span>
+ <span class="pillText"><?= __('writeNote.attachments.add.action') ?></span>
+ </button>
+
+<?php elseif ($type == 'file'): ?>
+
+ <button class="inlinePill" type="button" _="on click remove me">
+ <span class="pillIcon material-symbols attach-file"></span>
+ <span class="pillText"><?= $name ?></span>
+ <input type="hidden" name="attachments[]" value="<?= $oid ?>">
+ <span class="pillIcon material-symbols close-small"></span>
+ </button>
+
+<?php endif; ?> \ No newline at end of file
diff --git a/templates/write_note_form.php b/templates/write_note_form.php
index b86e825..82964c5 100644
--- a/templates/write_note_form.php
+++ b/templates/write_note_form.php
@@ -1,3 +1,8 @@
+<form hidden id="writeNoteAttachmentForm" action="/todo" hx-post="/fragment/note/attachmentPill" hx-swap="beforebegin"
+ hx-target="#writeNoteAttachmentPillAdder" enctype="multipart/form-data">
+ <input hidden type="file" name="file" id="noteAttachmentFile" _="on change send submit to closest <form/>">
+</form>
+
<form id="writeNoteForm" action="/todo" method="post" hx-post="/fragment/note" hx-swap="outerHTML"
hx-disabled-elt="find button" _="on submit wait 1s then trigger update on #liveTimelineUpdater">
<div class="row miniProfile">
@@ -21,6 +26,10 @@
<?php call_template('user_mention_pill'); ?>
</div>
<div class="row">
+ <label class="standalone"><?= __('writeNote.attachments.label') ?></label>
+ <?php call_template('attachment_pill'); ?>
+ </div>
+ <div class="row">
<label for="noteScope"><?= __('writeNote.scope.label') ?></label>
<select name="scope" id="noteScope" required autocomplete="off">
<option value="none"><?= __('note.privacy.scope.none') ?></option>