diff --git a/android/app/src/main/java/com/mattermost/helpers/database_extension/Post.kt b/android/app/src/main/java/com/mattermost/helpers/database_extension/Post.kt index 9cd6f2bec..61e463247 100644 --- a/android/app/src/main/java/com/mattermost/helpers/database_extension/Post.kt +++ b/android/app/src/main/java/com/mattermost/helpers/database_extension/Post.kt @@ -86,6 +86,7 @@ internal fun insertPost(db: Database, post: JSONObject) { val editAt = try { post.getDouble("edit_at") } catch (e: JSONException) { 0 } val isPinned = try { post.getBoolean("is_pinned") } catch (e: JSONException) { false } val message = try { post.getString("message") } catch (e: JSONException) { "" } + val messageSource = try { post.getString("message_source") } catch (e: JSONException) { "" } val metadata = try { post.getJSONObject("metadata") } catch (e: JSONException) { JSONObject() } val originalId = try { post.getString("original_id") } catch (e: JSONException) { "" } val pendingId = try { post.getString("pending_post_id") } catch (e: JSONException) { "" } @@ -100,13 +101,13 @@ internal fun insertPost(db: Database, post: JSONObject) { db.execute( """ INSERT INTO Post - (id, channel_id, create_at, delete_at, update_at, edit_at, is_pinned, message, metadata, original_id, pending_post_id, + (id, channel_id, create_at, delete_at, update_at, edit_at, is_pinned, message, message_source, metadata, original_id, pending_post_id, previous_post_id, root_id, type, user_id, props, _changed, _status) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '', 'created') + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '', 'created') """.trimIndent(), arrayOf( id, channelId, createAt, deleteAt, updateAt, editAt, - isPinned, message, metadata.toString(), + isPinned, message, messageSource, metadata.toString(), originalId, pendingId, prevId, rootId, type, userId, props ) @@ -139,6 +140,7 @@ internal fun updatePost(db: Database, post: JSONObject) { val editAt = try { post.getDouble("edit_at") } catch (e: JSONException) { 0 } val isPinned = try { post.getBoolean("is_pinned") } catch (e: JSONException) { false } val message = try { post.getString("message") } catch (e: JSONException) { "" } + val messageSource = try { post.getString("message_source") } catch (e: JSONException) { "" } val metadata = try { post.getJSONObject("metadata") } catch (e: JSONException) { JSONObject() } val originalId = try { post.getString("original_id") } catch (e: JSONException) { "" } val pendingId = try { post.getString("pending_post_id") } catch (e: JSONException) { "" } @@ -154,13 +156,13 @@ internal fun updatePost(db: Database, post: JSONObject) { db.execute( """ UPDATE Post SET channel_id = ?, create_at = ?, delete_at = ?, update_at =?, edit_at =?, - is_pinned = ?, message = ?, metadata = ?, original_id = ?, pending_post_id = ?, previous_post_id = ?, + is_pinned = ?, message = ?, message_source = ?, metadata = ?, original_id = ?, pending_post_id = ?, previous_post_id = ?, root_id = ?, type = ?, user_id = ?, props = ?, _status = 'updated' WHERE id = ? """.trimIndent(), arrayOf( channelId, createAt, deleteAt, updateAt, editAt, - isPinned, message, metadata.toString(), + isPinned, message, messageSource, metadata.toString(), originalId, pendingId, prevId, rootId, type, userId, props, id, diff --git a/app/actions/local/post.ts b/app/actions/local/post.ts index 7adbc6771..8dffef599 100644 --- a/app/actions/local/post.ts +++ b/app/actions/local/post.ts @@ -158,6 +158,7 @@ export async function markPostAsDeleted(serverUrl: string, post: Post, prepareRe const model = dbPost.prepareUpdate((p) => { p.deleteAt = Date.now(); p.message = ''; + p.messageSource = ''; p.metadata = null; p.props = undefined; }); diff --git a/app/actions/remote/post.ts b/app/actions/remote/post.ts index 514024942..7a5add8e6 100644 --- a/app/actions/remote/post.ts +++ b/app/actions/remote/post.ts @@ -858,12 +858,13 @@ export const editPost = async (serverUrl: string, postId: string, postMessage: s const post = await getPostById(database, postId); if (post) { - const {update_at, edit_at, message: updatedMessage} = await client.patchPost({message: postMessage, id: postId}); + const {update_at, edit_at, message: updatedMessage, message_source} = await client.patchPost({message: postMessage, id: postId}); await database.write(async () => { await post.update((p) => { p.updateAt = update_at; p.editAt = edit_at; p.message = updatedMessage; + p.messageSource = message_source || ''; }); }); } diff --git a/app/database/migration/server/index.ts b/app/database/migration/server/index.ts index 5916eb497..6fc926695 100644 --- a/app/database/migration/server/index.ts +++ b/app/database/migration/server/index.ts @@ -8,9 +8,20 @@ import {addColumns, schemaMigrations} from '@nozbe/watermelondb/Schema/migration import {MM_TABLES} from '@constants/database'; -const {CHANNEL_INFO, DRAFT} = MM_TABLES.SERVER; +const {CHANNEL_INFO, DRAFT, POST} = MM_TABLES.SERVER; export default schemaMigrations({migrations: [ + { + toVersion: 3, + steps: [ + addColumns({ + table: POST, + columns: [ + {name: 'message_source', type: 'string'}, + ], + }), + ], + }, { toVersion: 2, steps: [ diff --git a/app/database/models/server/post.ts b/app/database/models/server/post.ts index 8ef57ae3c..d278d2c49 100644 --- a/app/database/models/server/post.ts +++ b/app/database/models/server/post.ts @@ -72,6 +72,11 @@ export default class PostModel extends Model implements PostModelInterface { /** message : Message in the post */ @field('message') message!: string; + /** messageSource : will contain the message as submitted by the user if Message has been modified + by Mattermost for presentation (e.g if an image proxy is being used). It should be used to + populate edit boxes if present. */ + @field('message_source') messageSource!: string; + /** metadata: All the extra data associated with this Post */ @json('metadata', safeParseJSON) metadata!: PostMetadata | null; @@ -168,6 +173,7 @@ export default class PostModel extends Model implements PostModelInterface { root_id: this.rootId, original_id: this.originalId, message: this.message, + message_source: this.messageSource, type: this.type, props: this.props, pending_post_id: this.pendingPostId, diff --git a/app/database/operator/server_data_operator/transformers/post.ts b/app/database/operator/server_data_operator/transformers/post.ts index 0e43b4535..0b42b8b6a 100644 --- a/app/database/operator/server_data_operator/transformers/post.ts +++ b/app/database/operator/server_data_operator/transformers/post.ts @@ -41,6 +41,7 @@ export const transformPostRecord = ({action, database, value}: TransformerArgs): post.updateAt = raw.update_at; post.isPinned = Boolean(raw.is_pinned); post.message = raw.message; + post.messageSource = raw.message_source || ''; // When we extract the posts from the threads, we don't get the metadata // So, it might not be present in the raw post, so we use the one from the record diff --git a/app/database/schema/server/index.ts b/app/database/schema/server/index.ts index 332daf924..8220f092e 100644 --- a/app/database/schema/server/index.ts +++ b/app/database/schema/server/index.ts @@ -39,7 +39,7 @@ import { } from './table_schemas'; export const serverSchema: AppSchema = appSchema({ - version: 2, + version: 3, tables: [ CategorySchema, CategoryChannelSchema, diff --git a/app/database/schema/server/table_schemas/post.ts b/app/database/schema/server/table_schemas/post.ts index 1deb281b1..7c6f2ff83 100644 --- a/app/database/schema/server/table_schemas/post.ts +++ b/app/database/schema/server/table_schemas/post.ts @@ -16,6 +16,7 @@ export default tableSchema({ {name: 'edit_at', type: 'number'}, {name: 'is_pinned', type: 'boolean'}, {name: 'message', type: 'string'}, + {name: 'message_source', type: 'string'}, {name: 'metadata', type: 'string', isOptional: true}, {name: 'original_id', type: 'string'}, {name: 'pending_post_id', type: 'string', isIndexed: true}, diff --git a/app/database/schema/server/test.ts b/app/database/schema/server/test.ts index d660b2073..e64685048 100644 --- a/app/database/schema/server/test.ts +++ b/app/database/schema/server/test.ts @@ -45,7 +45,7 @@ const { describe('*** Test schema for SERVER database ***', () => { it('=> The SERVER SCHEMA should strictly match', () => { expect(serverSchema).toEqual({ - version: 2, + version: 3, unsafeSql: undefined, tables: { [CATEGORY]: { @@ -366,6 +366,7 @@ describe('*** Test schema for SERVER database ***', () => { edit_at: {name: 'edit_at', type: 'number'}, is_pinned: {name: 'is_pinned', type: 'boolean'}, message: {name: 'message', type: 'string'}, + message_source: {name: 'message_source', type: 'string'}, metadata: {name: 'metadata', type: 'string', isOptional: true}, original_id: {name: 'original_id', type: 'string'}, pending_post_id: {name: 'pending_post_id', type: 'string', isIndexed: true}, @@ -383,6 +384,7 @@ describe('*** Test schema for SERVER database ***', () => { {name: 'edit_at', type: 'number'}, {name: 'is_pinned', type: 'boolean'}, {name: 'message', type: 'string'}, + {name: 'message_source', type: 'string'}, {name: 'metadata', type: 'string', isOptional: true}, {name: 'original_id', type: 'string'}, {name: 'pending_post_id', type: 'string', isIndexed: true}, diff --git a/app/screens/edit_post/edit_post.tsx b/app/screens/edit_post/edit_post.tsx index 01a5255aa..e369d11eb 100644 --- a/app/screens/edit_post/edit_post.tsx +++ b/app/screens/edit_post/edit_post.tsx @@ -56,8 +56,9 @@ type EditPostProps = { canDelete: boolean; } const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttached, canDelete}: EditPostProps) => { - const [postMessage, setPostMessage] = useState(post.message); - const [cursorPosition, setCursorPosition] = useState(post.message.length); + const editingMessage = post.messageSource || post.message; + const [postMessage, setPostMessage] = useState(editingMessage); + const [cursorPosition, setCursorPosition] = useState(editingMessage.length); const [errorLine, setErrorLine] = useState(); const [errorExtra, setErrorExtra] = useState(); const [isUpdating, setIsUpdating] = useState(false); @@ -133,8 +134,8 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach setErrorLine(line); setErrorExtra(extra); } - toggleSaveButton(post.message !== message); - }, [intl, maxPostSize, post.message, toggleSaveButton]); + toggleSaveButton(editingMessage !== message); + }, [intl, maxPostSize, editingMessage, toggleSaveButton]); const onAutocompleteChangeText = useCallback((message: string) => { setPostMessage(message); @@ -175,7 +176,7 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach onPress: () => { setIsUpdating(false); toggleSaveButton(); - setPostMessage(post.message); + setPostMessage(editingMessage); }, }, { text: intl.formatMessage({id: 'post_info.del', defaultMessage: 'Delete'}), @@ -186,7 +187,7 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach }, }], ); - }, [serverUrl, post.message]); + }, [serverUrl, editingMessage]); const onSavePostMessage = useCallback(async () => { setIsUpdating(true); diff --git a/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift b/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift index 6b8f7d815..cce0a2f73 100644 --- a/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift +++ b/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift @@ -244,6 +244,7 @@ extension Database { let rootId = Expression("root_id") let originalId = Expression("original_id") let message = Expression("message") + let messageSource = Expression("message_source") let metadata = Expression("metadata") let type = Expression("type") let pendingPostId = Expression("pending_post_id") @@ -267,6 +268,7 @@ extension Database { setter.append(rootId <- post.rootId) setter.append(originalId <- post.originalId) setter.append(message <- post.message) + setter.append(messageSource <- post.messageSource) setter.append(metadata <- metadataSetters.metadata) setter.append(type <- post.type) setter.append(pendingPostId <- post.pendingPostId) diff --git a/types/api/posts.d.ts b/types/api/posts.d.ts index 8bea3d7c7..f8a4ac7c5 100644 --- a/types/api/posts.d.ts +++ b/types/api/posts.d.ts @@ -68,6 +68,7 @@ type Post = { root_id: string; original_id: string; message: string; + message_source?: string; type: PostType; participants?: null | UserProfile[]|string[]; props: Record; diff --git a/types/database/models/servers/post.ts b/types/database/models/servers/post.ts index a9af5704a..e81b543bd 100644 --- a/types/database/models/servers/post.ts +++ b/types/database/models/servers/post.ts @@ -42,6 +42,11 @@ declare class PostModel extends Model { /** message : Message in the post */ message: string; + /** messageSource : will contain the message as submitted by the user if Message has been modified + by Mattermost for presentation (e.g if an image proxy is being used). It should be used to + populate edit boxes if present. */ + messageSource: string; + /** metadata: All the extra data associated with this Post */ metadata: PostMetadata | null;