Use message source on post edit (#7325)

* Use message source on post edit

* Fix tests and bugs
This commit is contained in:
Daniel Espino García 2023-05-11 14:18:07 +02:00 committed by GitHub
parent 66a37b7032
commit c99861d728
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 49 additions and 15 deletions

View file

@ -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,

View file

@ -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;
});

View file

@ -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 || '';
});
});
}

View file

@ -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: [

View file

@ -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,

View file

@ -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

View file

@ -39,7 +39,7 @@ import {
} from './table_schemas';
export const serverSchema: AppSchema = appSchema({
version: 2,
version: 3,
tables: [
CategorySchema,
CategoryChannelSchema,

View file

@ -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},

View file

@ -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},

View file

@ -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<string | undefined>();
const [errorExtra, setErrorExtra] = useState<string | undefined>();
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);

View file

@ -244,6 +244,7 @@ extension Database {
let rootId = Expression<String>("root_id")
let originalId = Expression<String>("original_id")
let message = Expression<String>("message")
let messageSource = Expression<String>("message_source")
let metadata = Expression<String>("metadata")
let type = Expression<String>("type")
let pendingPostId = Expression<String?>("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)

View file

@ -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<string, any>;

View file

@ -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;