adding pinned messages (wip)

This commit is contained in:
or-else
2023-03-22 17:50:33 -07:00
parent 9640c604b9
commit 11fe81fdf1
27 changed files with 365 additions and 53 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "Pin",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": false,
"obsolete": false
},
"unpin_message": {
"translation": "Unpin",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": false,
"obsolete": false
}
}
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+8
View File
@@ -756,6 +756,10 @@
"defaultMessage": "phone",
"description": "Dative case of 'phone', i.e. 'phone' in 'by phone'"
},
"pin_message": {
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top."
},
"private_editing_placeholder": {
"defaultMessage": "Visible to you only",
"description": "Placeholder for editing 'private'"
@@ -912,6 +916,10 @@
"defaultMessage": "Unnamed",
"description": "Title shown when the topic has no name"
},
"unpin_message": {
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message."
},
"unrecognized_video_format": {
"defaultMessage": "Format of this video is not recognized",
"description": "Error message when uploaded video is invalid"
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+14
View File
@@ -1647,5 +1647,19 @@
"description": "Label for busy call line",
"missing": false,
"obsolete": false
},
"pin_message": {
"translation": "",
"defaultMessage": "Pin",
"description": "Menu item [Pin] for pinning message to the top.",
"missing": true,
"obsolete": false
},
"unpin_message": {
"translation": "",
"defaultMessage": "Unpin",
"description": "Menu item [Unpin] for un-pinning the message.",
"missing": true,
"obsolete": false
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
// This is a generated file. Don't edit.
export const PACKAGE_VERSION = "0.22.2";
export const PACKAGE_VERSION = "0.23.0-rc1";
+19 -3
View File
@@ -123,6 +123,7 @@ class MessagesView extends React.Component {
this.handleDescChange = this.handleDescChange.bind(this);
this.handleSubsUpdated = this.handleSubsUpdated.bind(this);
this.handleMessageUpdate = this.handleMessageUpdate.bind(this);
this.handleAuxUpdate = this.handleAuxUpdate.bind(this);
this.handleAllMessagesReceived = this.handleAllMessagesReceived.bind(this);
this.handleInfoReceipt = this.handleInfoReceipt.bind(this);
this.handleExpandMedia = this.handleExpandMedia.bind(this);
@@ -234,6 +235,7 @@ class MessagesView extends React.Component {
topic.onMetaDesc = this.handleDescChange;
topic.onSubsUpdated = this.handleSubsUpdated;
topic.onPres = this.handleSubsUpdated;
topic.onAux = this.handleAuxUpdate;
}
}
@@ -359,7 +361,8 @@ class MessagesView extends React.Component {
minSeqId: topic.minMsgSeq(),
maxSeqId: topic.maxMsgSeq(),
latestClearId: topic.maxClearId(),
channel: topic.isChannelType()
channel: topic.isChannelType(),
pins: topic.aux('pins')
});
if (nextProps.callTopic == topic.name && shouldPresentCallPanel(nextProps.callState)) {
@@ -393,6 +396,9 @@ class MessagesView extends React.Component {
if (nextProps.acs.isReader() != prevState.isReader) {
nextState.isReader = !prevState.isReader;
}
if (nextProps.acs.isAdmin() != prevState.isAdmin) {
nextState.isAdmin = !prevState.isAdmin;
}
if (!nextProps.acs.isReader('given') != prevState.readingBlocked) {
nextState.readingBlocked = !prevState.readingBlocked;
}
@@ -406,6 +412,9 @@ class MessagesView extends React.Component {
if (prevState.isReader) {
nextState.isReader = false;
}
if (prevState.isAdmin) {
nextState.isAdmin = false;
}
if (!prevState.readingBlocked) {
prevState.readingBlocked = true;
}
@@ -582,6 +591,7 @@ class MessagesView extends React.Component {
this.setState({
isWriter: desc.acs.isWriter(),
isReader: desc.acs.isReader(),
isAdmin: desc.acs.isAdmin(),
readingBlocked: !desc.acs.isReader('given'),
unconfirmed: isUnconfirmed(desc.acs),
});
@@ -722,6 +732,10 @@ class MessagesView extends React.Component {
}
}
handleAuxUpdate(aux) {
this.setState({pins: aux['pins']});
}
handleInfoReceipt(info) {
switch (info.what) {
case 'kp': {
@@ -748,9 +762,9 @@ class MessagesView extends React.Component {
}
if (content.video) {
this.setState({ videoPostview: content });
this.setState({videoPostview: content});
} else {
this.setState({ imagePostview: content });
this.setState({imagePostview: content});
}
}
@@ -1479,6 +1493,7 @@ class MessagesView extends React.Component {
received={deliveryStatus}
uploader={msg._uploader}
userIsWriter={this.state.isWriter}
userIsAdmin={this.state.isAdmin}
viewportWidth={this.props.viewportWidth} // Used by `formatter`.
showContextMenu={this.handleShowMessageContextMenu}
onExpandMedia={this.handleExpandMedia}
@@ -1594,6 +1609,7 @@ class MessagesView extends React.Component {
}<ContactBadges badges={icon_badges} /></div>
<div id="topic-last-seen">{lastSeen}</div>
</div>
<div>{this.state.pins}</div>
{groupTopic ?
<GroupSubs
tinode={this.props.tinode}
+19 -14
View File
@@ -93,23 +93,28 @@ class BaseChatMessage extends React.PureComponent {
if (this.props.received == Tinode.MESSAGE_STATUS_FAILED) {
menuItems.push('menu_item_send_retry');
}
if (this.props.userIsWriter && this.props.received > Tinode.MESSAGE_STATUS_FATAL) {
menuItems.push('menu_item_reply');
if (!this.props.response) {
let immutable = false;
Drafty.entities(this.props.content, (_0, _1, tp) => {
immutable = ['AU', 'EX', 'FM', 'IM', 'VC', 'VD'].includes(tp);
return immutable;
});
if (!immutable) {
Drafty.styles(this.props.content, tp => {
immutable = ['QQ'].includes(tp);
if (this.props.received > Tinode.MESSAGE_STATUS_FATAL) {
if (this.props.userIsWriter) {
menuItems.push('menu_item_reply');
if (!this.props.response) {
let immutable = false;
Drafty.entities(this.props.content, (_0, _1, tp) => {
immutable = ['AU', 'EX', 'FM', 'IM', 'VC', 'VD'].includes(tp);
return immutable;
});
if (!immutable) {
Drafty.styles(this.props.content, tp => {
immutable = ['QQ'].includes(tp);
return immutable;
});
}
if (!immutable) {
menuItems.push('menu_item_edit');
}
}
if (!immutable) {
menuItems.push('menu_item_edit');
}
}
if (this.props.userIsAdmin) {
menuItems.push('menu_item_pin');
}
}
menuItems.push('menu_item_forward');
+55
View File
@@ -116,6 +116,16 @@ const messages = defineMessages({
defaultMessage: 'Are you sure you want to clear all messages? It cannot be undone.',
description: 'Alert dialog warning when deleting all messages.'
},
pin_message: {
id: 'pin_message',
defaultMessage: 'Pin',
description: 'Menu item [Pin] for pinning message to the top.'
},
unpin_message: {
id: 'unpin_message',
defaultMessage: 'Unpin',
description: 'Menu item [Unpin] for un-pinning the message.'
},
});
class ContextMenu extends React.Component {
@@ -205,6 +215,20 @@ class ContextMenu extends React.Component {
return this.editMessage(params, errorHandler);
}
},
'menu_item_pin': {
id: 'menu_item_pin',
title: formatMessage(messages.pin_message),
handler: (params, errorHandler) => {
return this.pinMessage(true, params, errorHandler);
}
},
'menu_item_unpin': {
id: 'menu_item_unpin',
title: formatMessage(messages.unpin_message),
handler: (params, errorHandler) => {
return this.pinMessage(false, params, errorHandler);
}
},
'topic_unmute': {
id: 'topic_unmute',
title: formatMessage(messages.unmute),
@@ -428,6 +452,37 @@ class ContextMenu extends React.Component {
});
}
// Pin or unpin the message.
pinMessage(pin, params, errorHandler) {
const topic = this.props.tinode.getTopic(params.topicName);
if (!topic) {
return;
}
let pinned = topic.aux('pins');
console.log("topic.aux[pins]=", pinned);
if (!Array.isArray(pinned)) {
pinned = [];
}
let changed = false;
if (pin) {
if (!pinned.includes(params.seq)) {
changed = true;
pinned.push(params.seq);
}
} else {
if (pinned.includes(params.seq)) {
changed = true;
pinned = pinned.filter(seq => seq != params.seq)
}
}
if (changed) {
console.log("sending pins=", pinned);
topic.setMeta({aux: {pins: pinned}})
.catch(err => errorHandler ? errorHandler(err.message, 'err') : null);
}
}
// Function is used by context menu to set permissions.
topicPermissionSetter(mode, params, errorHandler) {
const topic = this.props.tinode.getTopic(params.topicName);