Posting of all media types supported by the server.

Content warnings supported.
Minor fix on post counter.
This commit is contained in:
elpamplina 2025-02-12 20:11:18 +01:00
parent 4277edb05d
commit 8e41e9f1ed
8 changed files with 39 additions and 16 deletions

View file

@ -15,7 +15,7 @@ Making threads can be tedious, manually pasting text and images. This plugin all
This plugin can:
- Insert thread separators manually or automatically.
- Visualize the order of fragments and their size as they are typed.
- Add descriptions to images to facilitate accessibility for people with visual impairments.
- Add descriptions to images and other media to facilitate accessibility for people with visual impairments.
- Submit individual posts or entire threads directly to the Mastodon server, checking the size limitations and different types of visibility supported by the server.
## Installation
@ -112,14 +112,18 @@ In Obsidian's view mode, separators appear as simple horizontal lines with no co
When the plugin is disabled, or when copying text somewhere outside the vault, separators are displayed with the typographical paragraph symbol (§).
### Quotes and image descriptions
### Quotes and media descriptions
The plugin uses quote blocks (starting with the Markdown symbol ">") to add descriptions to images. Just add a quote after an image, and it will be sent as description.
The plugin uses quote blocks (starting with the Markdown symbol ">") to add descriptions to images and other media. Just add a quote after a media, and it will be sent as description.
![Screen capture with an image with description](img/images.png)
Quote blocks that are not directly behind an image will be ignored and will not be sent as part of the thread. Feel free to use them as a place to keep comments or notes.
### Content warning
Starting a line with "!!" symbols will make it a content warning (aka spoiler text). Mastodon will show the rest of the post collapsed behind this warning.
## Questions, suggestions or bugs
You are greatly welcome to ask questions, post any suggestions, or report any bugs! You can do it directly here in Github, or by email at <elpamplinadecai@gmail.com>, or in Mastodon at @ElPamplina@masto.es

View file

@ -55,6 +55,7 @@
"alt_exceeded": "NOT SENT: More than {{max}} characters in description.",
"attachment_exceeded": "NOT SENT: More than {{max}} images in one post.",
"void_fragment": "NOT SENT: Can't send empty fragments!",
"file_not_found": "ERROR: Attachment file not found."
"file_not_found": "ERROR: Attachment file not found.",
"filetype_not_allowed": "ERROR: Attachment type not supported."
}
}

View file

@ -57,6 +57,7 @@
"alt_exceeded": "NO ENVIADO: Se superan los {{max}} caracteres en la descripción.",
"attachment_exceeded": "NO ENVIADO: Se superan las {{max}} imágenes en un post.",
"void_fragment": "NO ENVIADO: Hay fragmentos vacíos.",
"file_not_found": "ERROR: Archivo adjunto no encontrado."
"file_not_found": "ERROR: Archivo adjunto no encontrado.",
"filetype_not_allowed": "ERROR: Tipo de adjunto no soportado."
}
}

22
main.ts
View file

@ -19,7 +19,7 @@ import {
pattern_image,
pattern_quote,
pattern_server,
pattern_url,
pattern_url, pattern_warning,
SEPARATOR,
separatorField,
separatorPostProcessor
@ -226,6 +226,7 @@ export default class MastodonThreading extends Plugin {
if (editor.getValue()) {
type postMetadata = {
text: string,
warning: string | null,
images: {
file: TFile,
alt: string
@ -242,6 +243,7 @@ export default class MastodonThreading extends Plugin {
}
let post: postMetadata = {
text: c,
warning: null,
images: []
}
// Get images metadata
@ -278,21 +280,33 @@ export default class MastodonThreading extends Plugin {
alt: desc
});
}
else {
new Notice(t('error.filetype_not_allowed'));
return;
}
}
if (post.images.length > this.settings.serverMaxAttachments) {
new Notice(t('error.attachment_exceeded', {max: this.settings.serverMaxAttachments}));
return;
}
// Find content warning
let found_warning = post.text.match(pattern_warning);
console.log(found_warning)
if (found_warning) {
post.warning = found_warning[1];
}
// Remove images from main text
post.text = post.text.replace(pattern_image, ' ')
// Simplify links
.replace(pattern_url, '$1')
// Remove warning blocks
.replace(pattern_warning, '')
// Remove quote blocks
.replace(pattern_quote, '')
// Finally, strip spaces
.trim();
// Add counter
if (this.settings.postCounter) {
if (this.settings.postCounter && chunks.length > 1) {
post.text += `\n[${++count}/${chunks.length}]`;
}
if (post.text.length > this.settings.maxPost) {
@ -317,6 +331,7 @@ export default class MastodonThreading extends Plugin {
}
let status: mastodon.v1.Status = await this.getClient().v1.statuses.create({
status: p.text,
spoilerText: p.warning,
visibility: (first ? visibility_first : visibility_rest),
inReplyToId: id_link,
mediaIds: media,
@ -549,8 +564,7 @@ class MastodonThreadingSettingTab extends PluginSettingTab {
this.plugin.settings.serverMaxDescription = data.configuration.media_attachments.description_limit;
this.plugin.settings.serverMaxImage = data.configuration.media_attachments.image_size_limit;
this.plugin.settings.serverMaxAttachments = data.configuration.statuses.max_media_attachments;
this.plugin.settings.serverMimeTypes =
data.configuration.media_attachments.supported_mime_types.filter((m: string) => m.startsWith('image/'));
this.plugin.settings.serverMimeTypes = data.configuration.media_attachments.supported_mime_types;
await this.plugin.saveSettings();
this.display();
})

View file

@ -1,11 +1,11 @@
{
"id": "mastodon-threading",
"name": "Mastodon Threading",
"version": "1.0.6",
"version": "1.0.7",
"minAppVersion": "1.7.7",
"description": "Compose and post threads to Mastodon.",
"author": "El Pamplina de Cai",
"authorUrl": "https://masto.es/@ElPamplina",
"fundingUrl": "",
"isDesktopOnly": false
}
}

View file

@ -1,6 +1,6 @@
{
"name": "mastodon-threading",
"version": "1.0.6",
"version": "1.0.7",
"description": "Obsidian plugin to compose and post threads to Mastodon",
"main": "main.js",
"scripts": {

View file

@ -4,9 +4,11 @@ import MastodonThreading from "./main";
import {MarkdownPostProcessor} from "obsidian";
const SEPARATOR: string = '§'
const CW: string = '!!'
const pattern_image = /!\[\[(.*\.(.*?))(\|.*)*]]\s*?((\n>.*)*)/g;
const pattern_url = /\[.*]\((https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*))\)/g;
const pattern_separator = new RegExp('^' + SEPARATOR, 'm');
const pattern_warning = new RegExp('^' + CW + ' (.*)$', 'm');
const pattern_quote = /^>.*\n/gm;
const pattern_server = /(https?:\/\/)?([-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6})\b.*$/gm;
@ -81,8 +83,8 @@ function separatorField(plugin: MastodonThreading) {
last_start_pos = 0;
last_end_pos = 0;
}
// Quote blocks ignored
if (!lin.startsWith('>')) {
// Quote and warning blocks ignored
if (!lin.startsWith('>') && !lin.startsWith(CW)) {
text += lin;
}
}
@ -123,4 +125,4 @@ function replaceSeparators(element: HTMLElement) {
const separatorPostProcessor: MarkdownPostProcessor =
(element, context) => replaceSeparators(element);
export {SEPARATOR, separatorField, separatorPostProcessor, pattern_url, pattern_image, pattern_quote, pattern_server}
export {SEPARATOR, separatorField, separatorPostProcessor, pattern_url, pattern_image, pattern_quote, pattern_server, pattern_warning}

View file

@ -2,5 +2,6 @@
"1.0.3": "1.7.7",
"1.0.4": "1.7.7",
"1.0.5": "1.7.7",
"1.0.6": "1.7.7"
"1.0.6": "1.7.7",
"1.0.7": "1.7.7"
}