works as expected on desktop, mobile needs work

This commit is contained in:
or-else
2023-03-24 13:56:24 -07:00
parent cca97d410e
commit e68ebc8336
12 changed files with 164 additions and 37 deletions
+19 -4
View File
@@ -310,9 +310,8 @@ ul.menu > li.separator:hover {
} }
/* The down arrow head - trigger for context menu */ /* The down arrow head - trigger for context menu */
li .menuTrigger { .menuTrigger {
position: absolute; position: absolute;
top: 0.25rem;
right: 0.25rem; right: 0.25rem;
width: 1.4rem; width: 1.4rem;
height: 1.4rem; height: 1.4rem;
@@ -322,6 +321,10 @@ li .menuTrigger {
opacity: 0; opacity: 0;
background-color: inherit; background-color: inherit;
} }
li .menuTrigger {
top: 0.25rem;
}
li:hover .menuTrigger { li:hover .menuTrigger {
opacity: 0.9; opacity: 0.9;
} }
@@ -3060,7 +3063,6 @@ ul.tabbar li.active > a {
transition: background 0s; transition: background 0s;
} }
.pinned-scroll { .pinned-scroll {
position: relative; position: relative;
display: flex; display: flex;
@@ -3088,6 +3090,19 @@ ul.tabbar li.active > a {
background-color: #039be5; background-color: #039be5;
} }
#pinned-wrapper .menuTrigger.upper {
top: 0.25rem;
}
#pinned-wrapper .menuTrigger.lower {
bottom: 0.25rem;
}
#pinned-wrapper:hover .menuTrigger {
opacity: 0.9;
}
#pinned-wrapper:hover .menuTrigger a {
color: #757575;
}
/* /*
Drag-and-drop area. Drag-and-drop area.
*/ */
@@ -3200,7 +3215,7 @@ ul.phone-country-selector span.country {
} }
/* Must make it a bit visible on mobile because there is no :hover */ /* Must make it a bit visible on mobile because there is no :hover */
li .menuTrigger { .menuTrigger {
opacity: 0.3; opacity: 0.3;
} }
+1 -1
View File
File diff suppressed because one or more lines are too long
+22 -8
View File
@@ -289,7 +289,9 @@ class MessagesView extends React.Component {
reply: null, reply: null,
contentToEdit: null, contentToEdit: null,
showGoToLastButton: false, showGoToLastButton: false,
dragging: false dragging: false,
pins: [],
selectedPin: 0
}; };
} else if (nextProps.topic != prevState.topic) { } else if (nextProps.topic != prevState.topic) {
const topic = nextProps.tinode.getTopic(nextProps.topic); const topic = nextProps.tinode.getTopic(nextProps.topic);
@@ -308,7 +310,8 @@ class MessagesView extends React.Component {
fetchingMessages: false, fetchingMessages: false,
showGoToLastButton: false, showGoToLastButton: false,
contentToEdit: null, contentToEdit: null,
dragging: false dragging: false,
selectedPin: 0
}; };
if (nextProps.forwardMessage) { if (nextProps.forwardMessage) {
@@ -359,12 +362,13 @@ class MessagesView extends React.Component {
peerMessagingDisabled: false peerMessagingDisabled: false
}); });
} }
console.log("getDerivedStateFromProps", nextProps.topic, prevState.topic);
Object.assign(nextState, { Object.assign(nextState, {
minSeqId: topic.minMsgSeq(), minSeqId: topic.minMsgSeq(),
maxSeqId: topic.maxMsgSeq(), maxSeqId: topic.maxMsgSeq(),
latestClearId: topic.maxClearId(), latestClearId: topic.maxClearId(),
channel: topic.isChannelType(), channel: topic.isChannelType(),
pins: topic.aux('pins') pins: (topic.aux('pins') || []).slice()
}); });
if (nextProps.callTopic == topic.name && shouldPresentCallPanel(nextProps.callState)) { if (nextProps.callTopic == topic.name && shouldPresentCallPanel(nextProps.callState)) {
@@ -380,7 +384,8 @@ class MessagesView extends React.Component {
title: '', title: '',
avatar: null, avatar: null,
peerMessagingDisabled: false, peerMessagingDisabled: false,
channel: false channel: false,
pins: []
}); });
} }
} else { } else {
@@ -736,7 +741,15 @@ class MessagesView extends React.Component {
} }
handleAuxUpdate(aux) { handleAuxUpdate(aux) {
this.setState({pins: aux['pins']}); const pins = (aux['pins'] || []).slice();
let selectedPin = this.state.selectedPin;
if (pins.length > this.state.pins.length) {
// New pins added, show the latest.
selectedPin = 0;
} else if (selectedPin >= pins.length) {
selectedPin = Math.max(0, pins.length - 1);
}
this.setState({pins: pins, selectedPin: selectedPin});
} }
handleInfoReceipt(info) { handleInfoReceipt(info) {
@@ -1426,7 +1439,7 @@ class MessagesView extends React.Component {
} }
const pinnedMessages = []; const pinnedMessages = [];
(this.state.pins || []).forEach(seq => pinnedMessages.push(topic.findMessage(seq))); this.state.pins.forEach(seq => pinnedMessages.push(topic.findMessage(seq)));
const messageNodes = []; const messageNodes = [];
let previousFrom = null; let previousFrom = null;
@@ -1505,7 +1518,7 @@ class MessagesView extends React.Component {
uploader={msg._uploader} uploader={msg._uploader}
userIsWriter={this.state.isWriter} userIsWriter={this.state.isWriter}
userIsAdmin={this.state.isAdmin} userIsAdmin={this.state.isAdmin}
pinned={(this.state.pins || []).includes(msg.seq)} pinned={this.state.pins.includes(msg.seq)}
viewportWidth={this.props.viewportWidth} // Used by `formatter`. viewportWidth={this.props.viewportWidth} // Used by `formatter`.
showContextMenu={this.handleShowMessageContextMenu} showContextMenu={this.handleShowMessageContextMenu}
onExpandMedia={this.handleExpandMedia} onExpandMedia={this.handleExpandMedia}
@@ -1624,7 +1637,8 @@ class MessagesView extends React.Component {
<PinnedMessages <PinnedMessages
tinode={this.props.tinode} tinode={this.props.tinode}
messages={pinnedMessages} messages={pinnedMessages}
selected={0} selected={this.state.selectedPin}
setSelected={index => this.setState({selectedPin: index})}
onSelected={this.handleQuoteClick} onSelected={this.handleQuoteClick}
onCancel={this.handleUnpinMessage} /> onCancel={this.handleUnpinMessage} />
{groupTopic ? {groupTopic ?
+47 -4
View File
@@ -9,22 +9,51 @@ class PinnedMessages extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.getSelectedIndex = this.getSelectedIndex.bind(this);
this.handleCancel = this.handleCancel.bind(this); this.handleCancel = this.handleCancel.bind(this);
this.handleSelected = this.handleSelected.bind(this); this.handleSelected = this.handleSelected.bind(this);
this.handleMoveNext = this.handleMoveNext.bind(this);
this.handleMovePrev = this.handleMovePrev.bind(this);
}
getSelectedIndex() {
const list = (this.props.messages || []);
return list.length - this.props.selected - 1;
} }
handleCancel(e) { handleCancel(e) {
e.preventDefault(); e.preventDefault();
this.props.onCancel(this.props.messages[this.props.selected].seq); this.props.onCancel(this.props.messages[this.getSelectedIndex()].seq);
} }
handleSelected(e) { handleSelected(e) {
e.preventDefault(); e.preventDefault();
this.props.onSelected(this.props.messages[this.props.selected].seq); this.props.onSelected(this.props.messages[this.getSelectedIndex()].seq);
}
handleMoveNext(e) {
e.preventDefault();
e.stopPropagation();
const idx = Math.max(this.props.selected - 1, 0);
if (idx != this.props.selected) {
console.log("Move selection to ", idx);
this.props.setSelected(idx);
}
}
handleMovePrev(e) {
e.preventDefault();
e.stopPropagation();
const idx = Math.min(this.props.selected + 1, (this.props.messages || []).length - 1);
if (idx != this.props.selected) {
console.log("Move selection to ", idx);
this.props.setSelected(idx);
}
} }
render() { render() {
let shown = (this.props.messages || [])[this.props.selected]; const selected = this.getSelectedIndex();
let shown = (this.props.messages || [])[selected];
shown = shown ? Drafty.format(shown.content, previewFormatter, { shown = shown ? Drafty.format(shown.content, previewFormatter, {
formatMessage: this.props.intl.formatMessage.bind(this.props.intl), formatMessage: this.props.intl.formatMessage.bind(this.props.intl),
authorizeURL: this.props.tinode.authorizeURL.bind(this.props.tinode) authorizeURL: this.props.tinode.authorizeURL.bind(this.props.tinode)
@@ -32,7 +61,7 @@ class PinnedMessages extends React.PureComponent {
const dots = []; const dots = [];
this.props.messages.forEach(_ => { this.props.messages.forEach(_ => {
const cn = dots.length == this.props.selected ? 'adot' : 'dot'; const cn = dots.length == selected ? 'adot' : 'dot';
dots.push(<div key={dots.length} className={cn} />); dots.push(<div key={dots.length} className={cn} />);
}); });
@@ -43,6 +72,20 @@ class PinnedMessages extends React.PureComponent {
</div> </div>
<div className="pinned-scroll">{dots}</div> <div className="pinned-scroll">{dots}</div>
<div className="pinned" onClick={this.handleSelected}>{shown}</div> <div className="pinned" onClick={this.handleSelected}>{shown}</div>
{selected > 0 ?
<span className="menuTrigger upper">
<a href="#" onClick={this.handleMovePrev}>
<i className="material-icons">expand_less</i>
</a>
</span>
: null}
{this.props.selected > 0 ?
<span className="menuTrigger lower">
<a href="#" onClick={this.handleMoveNext}>
<i className="material-icons">expand_more</i>
</a>
</span>
: null}
</div>) : null; </div>) : null;
} }
} }
+69 -13
View File
@@ -5326,7 +5326,9 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
reply: null, reply: null,
contentToEdit: null, contentToEdit: null,
showGoToLastButton: false, showGoToLastButton: false,
dragging: false dragging: false,
pins: [],
selectedPin: 0
}; };
} else if (nextProps.topic != prevState.topic) { } else if (nextProps.topic != prevState.topic) {
const topic = nextProps.tinode.getTopic(nextProps.topic); const topic = nextProps.tinode.getTopic(nextProps.topic);
@@ -5344,7 +5346,8 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
fetchingMessages: false, fetchingMessages: false,
showGoToLastButton: false, showGoToLastButton: false,
contentToEdit: null, contentToEdit: null,
dragging: false dragging: false,
selectedPin: 0
}; };
if (nextProps.forwardMessage) { if (nextProps.forwardMessage) {
nextState.reply = { nextState.reply = {
@@ -5387,12 +5390,13 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
peerMessagingDisabled: false peerMessagingDisabled: false
}); });
} }
console.log("getDerivedStateFromProps", nextProps.topic, prevState.topic);
Object.assign(nextState, { Object.assign(nextState, {
minSeqId: topic.minMsgSeq(), minSeqId: topic.minMsgSeq(),
maxSeqId: topic.maxMsgSeq(), maxSeqId: topic.maxMsgSeq(),
latestClearId: topic.maxClearId(), latestClearId: topic.maxClearId(),
channel: topic.isChannelType(), channel: topic.isChannelType(),
pins: topic.aux('pins') pins: (topic.aux('pins') || []).slice()
}); });
if (nextProps.callTopic == topic.name && shouldPresentCallPanel(nextProps.callState)) { if (nextProps.callTopic == topic.name && shouldPresentCallPanel(nextProps.callState)) {
nextState.rtcPanel = nextProps.callTopic; nextState.rtcPanel = nextProps.callTopic;
@@ -5406,7 +5410,8 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
title: '', title: '',
avatar: null, avatar: null,
peerMessagingDisabled: false, peerMessagingDisabled: false,
channel: false channel: false,
pins: []
}); });
} }
} else { } else {
@@ -5713,8 +5718,16 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
} }
} }
handleAuxUpdate(aux) { handleAuxUpdate(aux) {
const pins = (aux['pins'] || []).slice();
let selectedPin = this.state.selectedPin;
if (pins.length > this.state.pins.length) {
selectedPin = 0;
} else if (selectedPin >= pins.length) {
selectedPin = Math.max(0, pins.length - 1);
}
this.setState({ this.setState({
pins: aux['pins'] pins: pins,
selectedPin: selectedPin
}); });
} }
handleInfoReceipt(info) { handleInfoReceipt(info) {
@@ -6325,7 +6338,7 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
} }
} }
const pinnedMessages = []; const pinnedMessages = [];
(this.state.pins || []).forEach(seq => pinnedMessages.push(topic.findMessage(seq))); this.state.pins.forEach(seq => pinnedMessages.push(topic.findMessage(seq)));
const messageNodes = []; const messageNodes = [];
let previousFrom = null; let previousFrom = null;
let prevDate = null; let prevDate = null;
@@ -6394,7 +6407,7 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
uploader: msg._uploader, uploader: msg._uploader,
userIsWriter: this.state.isWriter, userIsWriter: this.state.isWriter,
userIsAdmin: this.state.isAdmin, userIsAdmin: this.state.isAdmin,
pinned: (this.state.pins || []).includes(msg.seq), pinned: this.state.pins.includes(msg.seq),
viewportWidth: this.props.viewportWidth, viewportWidth: this.props.viewportWidth,
showContextMenu: this.handleShowMessageContextMenu, showContextMenu: this.handleShowMessageContextMenu,
onExpandMedia: this.handleExpandMedia, onExpandMedia: this.handleExpandMedia,
@@ -6526,7 +6539,10 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
}, lastSeen)), react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_pinned_messages_jsx__WEBPACK_IMPORTED_MODULE_15__["default"], { }, lastSeen)), react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_pinned_messages_jsx__WEBPACK_IMPORTED_MODULE_15__["default"], {
tinode: this.props.tinode, tinode: this.props.tinode,
messages: pinnedMessages, messages: pinnedMessages,
selected: 0, selected: this.state.selectedPin,
setSelected: index => this.setState({
selectedPin: index
}),
onSelected: this.handleQuoteClick, onSelected: this.handleQuoteClick,
onCancel: this.handleUnpinMessage onCancel: this.handleUnpinMessage
}), groupTopic ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_group_subs_jsx__WEBPACK_IMPORTED_MODULE_8__["default"], { }), groupTopic ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_group_subs_jsx__WEBPACK_IMPORTED_MODULE_8__["default"], {
@@ -14789,26 +14805,52 @@ __webpack_require__.r(__webpack_exports__);
class PinnedMessages extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { class PinnedMessages extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
constructor(props) { constructor(props) {
super(props); super(props);
this.getSelectedIndex = this.getSelectedIndex.bind(this);
this.handleCancel = this.handleCancel.bind(this); this.handleCancel = this.handleCancel.bind(this);
this.handleSelected = this.handleSelected.bind(this); this.handleSelected = this.handleSelected.bind(this);
this.handleMoveNext = this.handleMoveNext.bind(this);
this.handleMovePrev = this.handleMovePrev.bind(this);
}
getSelectedIndex() {
const list = this.props.messages || [];
return list.length - this.props.selected - 1;
} }
handleCancel(e) { handleCancel(e) {
e.preventDefault(); e.preventDefault();
this.props.onCancel(this.props.messages[this.props.selected].seq); this.props.onCancel(this.props.messages[this.getSelectedIndex()].seq);
} }
handleSelected(e) { handleSelected(e) {
e.preventDefault(); e.preventDefault();
this.props.onSelected(this.props.messages[this.props.selected].seq); this.props.onSelected(this.props.messages[this.getSelectedIndex()].seq);
}
handleMoveNext(e) {
e.preventDefault();
e.stopPropagation();
const idx = Math.max(this.props.selected - 1, 0);
if (idx != this.props.selected) {
console.log("Move selection to ", idx);
this.props.setSelected(idx);
}
}
handleMovePrev(e) {
e.preventDefault();
e.stopPropagation();
const idx = Math.min(this.props.selected + 1, (this.props.messages || []).length - 1);
if (idx != this.props.selected) {
console.log("Move selection to ", idx);
this.props.setSelected(idx);
}
} }
render() { render() {
let shown = (this.props.messages || [])[this.props.selected]; const selected = this.getSelectedIndex();
let shown = (this.props.messages || [])[selected];
shown = shown ? tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.format(shown.content, _lib_formatters_js__WEBPACK_IMPORTED_MODULE_3__.previewFormatter, { shown = shown ? tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.format(shown.content, _lib_formatters_js__WEBPACK_IMPORTED_MODULE_3__.previewFormatter, {
formatMessage: this.props.intl.formatMessage.bind(this.props.intl), formatMessage: this.props.intl.formatMessage.bind(this.props.intl),
authorizeURL: this.props.tinode.authorizeURL.bind(this.props.tinode) authorizeURL: this.props.tinode.authorizeURL.bind(this.props.tinode)
}) : null; }) : null;
const dots = []; const dots = [];
this.props.messages.forEach(_ => { this.props.messages.forEach(_ => {
const cn = dots.length == this.props.selected ? 'adot' : 'dot'; const cn = dots.length == selected ? 'adot' : 'dot';
dots.push(react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { dots.push(react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
key: dots.length, key: dots.length,
className: cn className: cn
@@ -14828,7 +14870,21 @@ class PinnedMessages extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
}, dots), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }, dots), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "pinned", className: "pinned",
onClick: this.handleSelected onClick: this.handleSelected
}, shown)) : null; }, shown), selected > 0 ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
className: "menuTrigger upper"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#",
onClick: this.handleMovePrev
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons"
}, "expand_less"))) : null, this.props.selected > 0 ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
className: "menuTrigger lower"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#",
onClick: this.handleMoveNext
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons"
}, "expand_more"))) : null) : null;
} }
} }
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(PinnedMessages)); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(PinnedMessages));
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -5837,7 +5837,6 @@ class Tinode {
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'set', topic); const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'set', topic);
const what = []; const what = [];
if (params) { if (params) {
console.log("setMeta, params=", params);
['desc', 'sub', 'tags', 'cred', 'aux'].forEach(key => { ['desc', 'sub', 'tags', 'cred', 'aux'].forEach(key => {
if (params.hasOwnProperty(key)) { if (params.hasOwnProperty(key)) {
what.push(key); what.push(key);
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long