diff --git a/server/message_cache.go b/server/message_cache.go index 140271fe..8a613ff1 100644 --- a/server/message_cache.go +++ b/server/message_cache.go @@ -45,6 +45,7 @@ const ( attachment_deleted INT NOT NULL, sender TEXT NOT NULL, user TEXT NOT NULL, + content_type TEXT NOT NULL, encoding TEXT NOT NULL, published INT NOT NULL ); @@ -63,43 +64,43 @@ const ( COMMIT; ` insertMessageQuery = ` - INSERT INTO messages (mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, attachment_deleted, sender, user, encoding, published) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + INSERT INTO messages (mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, attachment_deleted, sender, user, content_type, encoding, published) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ` deleteMessageQuery = `DELETE FROM messages WHERE mid = ?` updateMessagesForTopicExpiryQuery = `UPDATE messages SET expires = ? WHERE topic = ?` selectRowIDFromMessageID = `SELECT id FROM messages WHERE mid = ?` // Do not include topic, see #336 and TestServer_PollSinceID_MultipleTopics selectMessagesByIDQuery = ` - SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, encoding + SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, content_type, encoding FROM messages WHERE mid = ? ` selectMessagesSinceTimeQuery = ` - SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, encoding + SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, content_type, encoding FROM messages WHERE topic = ? AND time >= ? AND published = 1 ORDER BY time, id ` selectMessagesSinceTimeIncludeScheduledQuery = ` - SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, encoding + SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, content_type, encoding FROM messages WHERE topic = ? AND time >= ? ORDER BY time, id ` selectMessagesSinceIDQuery = ` - SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, encoding + SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, content_type, encoding FROM messages WHERE topic = ? AND id > ? AND published = 1 ORDER BY time, id ` selectMessagesSinceIDIncludeScheduledQuery = ` - SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, encoding + SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, content_type, encoding FROM messages WHERE topic = ? AND (id > ? OR published = 0) ORDER BY time, id ` selectMessagesDueQuery = ` - SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, encoding + SELECT mid, time, expires, topic, message, title, priority, tags, click, icon, actions, attachment_name, attachment_type, attachment_size, attachment_expires, attachment_url, sender, user, content_type, encoding FROM messages WHERE time <= ? AND published = 0 ORDER BY time, id @@ -121,7 +122,7 @@ const ( // Schema management queries const ( - currentSchemaVersion = 11 + currentSchemaVersion = 12 createSchemaVersionTableQuery = ` CREATE TABLE IF NOT EXISTS schemaVersion ( id INT PRIMARY KEY, @@ -240,6 +241,11 @@ const ( ); INSERT INTO stats (key, value) VALUES ('messages', 0); ` + + // 11 -> 12 + migrate11To12AlterMessagesTableQuery = ` + ALTER TABLE messages ADD COLUMN content_type TEXT NOT NULL DEFAULT(''); + ` ) var ( @@ -255,6 +261,7 @@ var ( 8: migrateFrom8, 9: migrateFrom9, 10: migrateFrom10, + 11: migrateFrom11, } ) @@ -384,6 +391,7 @@ func (c *messageCache) addMessages(ms []*message) error { attachmentDeleted, // Always zero sender, m.User, + m.ContentType, m.Encoding, published, ) @@ -656,7 +664,7 @@ func readMessages(rows *sql.Rows) ([]*message, error) { func readMessage(rows *sql.Rows) (*message, error) { var timestamp, expires, attachmentSize, attachmentExpires int64 var priority int - var id, topic, msg, title, tagsStr, click, icon, actionsStr, attachmentName, attachmentType, attachmentURL, sender, user, encoding string + var id, topic, msg, title, tagsStr, click, icon, actionsStr, attachmentName, attachmentType, attachmentURL, sender, user, contentType, encoding string err := rows.Scan( &id, ×tamp, @@ -676,6 +684,7 @@ func readMessage(rows *sql.Rows) (*message, error) { &attachmentURL, &sender, &user, + &contentType, &encoding, ) if err != nil { @@ -706,22 +715,23 @@ func readMessage(rows *sql.Rows) (*message, error) { } } return &message{ - ID: id, - Time: timestamp, - Expires: expires, - Event: messageEvent, - Topic: topic, - Message: msg, - Title: title, - Priority: priority, - Tags: tags, - Click: click, - Icon: icon, - Actions: actions, - Attachment: att, - Sender: senderIP, // Must parse assuming database must be correct - User: user, - Encoding: encoding, + ID: id, + Time: timestamp, + Expires: expires, + Event: messageEvent, + Topic: topic, + Message: msg, + Title: title, + Priority: priority, + Tags: tags, + Click: click, + Icon: icon, + Actions: actions, + Attachment: att, + Sender: senderIP, // Must parse assuming database must be correct + User: user, + ContentType: contentType, + Encoding: encoding, }, nil } @@ -929,7 +939,7 @@ func migrateFrom9(db *sql.DB, cacheDuration time.Duration) error { return tx.Commit() } -func migrateFrom10(db *sql.DB, cacheDuration time.Duration) error { +func migrateFrom10(db *sql.DB, _ time.Duration) error { log.Tag(tagMessageCache).Info("Migrating cache database schema: from 10 to 11") tx, err := db.Begin() if err != nil { @@ -944,3 +954,19 @@ func migrateFrom10(db *sql.DB, cacheDuration time.Duration) error { } return tx.Commit() } + +func migrateFrom11(db *sql.DB, _ time.Duration) error { + log.Tag(tagMessageCache).Info("Migrating cache database schema: from 11 to 12") + tx, err := db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + if _, err := tx.Exec(migrate11To12AlterMessagesTableQuery); err != nil { + return err + } + if _, err := tx.Exec(updateSchemaVersion, 12); err != nil { + return err + } + return tx.Commit() +} diff --git a/server/server_firebase_test.go b/server/server_firebase_test.go index f18abe13..fb27ea05 100644 --- a/server/server_firebase_test.go +++ b/server/server_firebase_test.go @@ -182,6 +182,7 @@ func TestToFirebaseMessage_Message_Normal_Allowed(t *testing.T) { "title": "some title", "message": "this is a message", "actions": `[{"id":"123","action":"view","label":"Open page","clear":true,"url":"https://ntfy.sh"},{"id":"456","action":"http","label":"Close door","clear":false,"url":"https://door.com/close","method":"PUT","headers":{"really":"yes"}}]`, + "content_type": "", "encoding": "", "attachment_name": "some file.jpg", "attachment_type": "image/jpeg", @@ -203,6 +204,7 @@ func TestToFirebaseMessage_Message_Normal_Allowed(t *testing.T) { "title": "some title", "message": "this is a message", "actions": `[{"id":"123","action":"view","label":"Open page","clear":true,"url":"https://ntfy.sh"},{"id":"456","action":"http","label":"Close door","clear":false,"url":"https://door.com/close","method":"PUT","headers":{"really":"yes"}}]`, + "content_type": "", "encoding": "", "attachment_name": "some file.jpg", "attachment_type": "image/jpeg", diff --git a/web/public/static/langs/en.json b/web/public/static/langs/en.json index 3d85b757..3f2947e4 100644 --- a/web/public/static/langs/en.json +++ b/web/public/static/langs/en.json @@ -359,9 +359,6 @@ "prefs_appearance_theme_system": "System (default)", "prefs_appearance_theme_dark": "Dark mode", "prefs_appearance_theme_light": "Light mode", - "prefs_appearance_markdown_always_enabled_title": "Format all messages as Markdown", - "prefs_appearance_markdown_always_enabled_on": "Enabled", - "prefs_appearance_markdown_always_enabled_off": "Disabled", "prefs_reservations_title": "Reserved topics", "prefs_reservations_description": "You can reserve topic names for personal use here. Reserving a topic gives you ownership over the topic, and allows you to define access permissions for other users over the topic.", "prefs_reservations_limit_reached": "You reached your reserved topics limit.", diff --git a/web/src/app/Prefs.js b/web/src/app/Prefs.js index 9d9ed0d5..4f28f87e 100644 --- a/web/src/app/Prefs.js +++ b/web/src/app/Prefs.js @@ -55,15 +55,6 @@ class Prefs { async setTheme(mode) { await this.db.prefs.put({ key: "theme", value: mode }); } - - async markdownAlwaysEnabled() { - const record = await this.db.prefs.get("markdownAlwaysEnabled"); - return record?.value ?? false; - } - - async setMarkdownAlwaysEnabled(enabled) { - await this.db.prefs.put({ key: "markdownAlwaysEnabled", value: enabled }); - } } const prefs = new Prefs(db()); diff --git a/web/src/components/Notifications.jsx b/web/src/components/Notifications.jsx index 610d5256..ccd2deb9 100644 --- a/web/src/components/Notifications.jsx +++ b/web/src/components/Notifications.jsx @@ -192,6 +192,10 @@ const MarkdownContainer = styled("div")` ol { padding-inline: 1rem; } + + img { + max-width: 100%; + } `; const MarkdownContent = ({ content }) => { @@ -205,17 +209,11 @@ const MarkdownContent = ({ content }) => { }; const NotificationBody = ({ notification }) => { - const markdownAlwaysEnabled = useLiveQuery(async () => prefs.markdownAlwaysEnabled()); - - // TODO: check notification content-type when implemented on the server - const displayAsMarkdown = markdownAlwaysEnabled; - + const displayAsMarkdown = notification.content_type === "text/markdown"; const formatted = formatMessage(notification); - if (displayAsMarkdown) { return ; } - return autolink(formatted); }; diff --git a/web/src/components/Preferences.jsx b/web/src/components/Preferences.jsx index f28c3da3..a93032ce 100644 --- a/web/src/components/Preferences.jsx +++ b/web/src/components/Preferences.jsx @@ -259,26 +259,6 @@ const Theme = () => { ); }; -const MarkdownAlwaysEnabled = () => { - const { t } = useTranslation(); - const labelId = "prefMarkdown"; - const enabled = useLiveQuery(async () => prefs.markdownAlwaysEnabled()); - const handleChange = async (ev) => { - await prefs.setMarkdownAlwaysEnabled(ev.target.value); - }; - - return ( - - - - - - ); -}; - const WebPushEnabled = () => { const { t } = useTranslation(); const labelId = "prefWebPushEnabled"; @@ -533,7 +513,6 @@ const Appearance = () => { - );