2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 06:35:14 +00:00

comments show-hide in channels

This commit is contained in:
John Preston
2015-09-19 12:13:21 +03:00
parent ab7a745a49
commit 56a63a5b10
28 changed files with 1762 additions and 738 deletions

View File

@@ -34,9 +34,11 @@ extern TextParseOptions _textNameOptions, _textDlgOptions, _historyTextOptions,
#include "structs.h"
struct History;
struct Histories : public QHash<PeerId, History*>, public Animated {
typedef QHash<PeerId, History*> Parent;
class History;
class Histories : public Animated {
public:
typedef QHash<PeerId, History*> Map;
Map map;
Histories() : unreadFull(0), unreadMuted(0) {
}
@@ -44,16 +46,17 @@ struct Histories : public QHash<PeerId, History*>, public Animated {
void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action);
bool animStep(float64 ms);
History *find(const PeerId &peerId);
History *findOrInsert(const PeerId &peerId, int32 unreadCount, int32 maxInboxRead);
void clear();
Parent::iterator erase(Parent::iterator i);
void remove(const PeerId &peer);
~Histories() {
clear();
unreadFull = unreadMuted = 0;
}
HistoryItem *addToBack(const MTPmessage &msg, int msgState = 1); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message
HistoryItem *addNewMessage(const MTPmessage &msg, int msgState = 1); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message
// HistoryItem *addToBack(const MTPgeoChatMessage &msg, bool newMsg = true);
typedef QMap<History*, uint64> TypingHistories; // when typing in this history started
@@ -62,7 +65,7 @@ struct Histories : public QHash<PeerId, History*>, public Animated {
int32 unreadFull, unreadMuted;
};
struct HistoryBlock;
class HistoryBlock;
struct DialogRow {
DialogRow(History *history = 0, DialogRow *prev = 0, DialogRow *next = 0, int32 pos = 0) : prev(prev), next(next), history(history), pos(pos), attached(0) {
@@ -158,19 +161,29 @@ struct SendAction {
class HistoryMedia;
class HistoryMessage;
class HistoryUnreadBar;
struct History : public QList<HistoryBlock*> {
class ChannelHistory;
class History {
public:
History(const PeerId &peerId);
ChannelId channelId() const {
return peerToChannel(peer->id);
}
bool isChannel() const {
return peerIsChannel(peer->id);
}
ChannelHistory *asChannelHistory();
const ChannelHistory *asChannelHistory() const;
typedef QList<HistoryBlock*> Parent;
bool isEmpty() const {
return blocks.isEmpty();
}
void clear(bool leaveItems = false);
Parent::iterator erase(Parent::iterator i);
void blockResized(HistoryBlock *block, int32 dh);
void removeBlock(HistoryBlock *block);
~History() {
virtual ~History() {
clear();
}
@@ -178,16 +191,14 @@ struct History : public QList<HistoryBlock*> {
HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, QDateTime date, int32 from, HistoryMessage *msg);
HistoryItem *createItemDocument(HistoryBlock *block, MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
HistoryItem *addToBackService(MsgId msgId, QDateTime date, const QString &text, int32 flags = 0, HistoryMedia *media = 0, bool newMsg = true);
HistoryItem *addToBack(const MTPmessage &msg, bool newMsg = true);
HistoryItem *addNewService(MsgId msgId, QDateTime date, const QString &text, int32 flags = 0, HistoryMedia *media = 0, bool newMsg = true);
HistoryItem *addNewMessage(const MTPmessage &msg, bool newMsg = true);
HistoryItem *addToHistory(const MTPmessage &msg);
HistoryItem *addToBackForwarded(MsgId id, QDateTime date, int32 from, HistoryMessage *item);
HistoryItem *addToBackDocument(MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
HistoryItem *addNewForwarded(MsgId id, QDateTime date, int32 from, HistoryMessage *item);
HistoryItem *addNewDocument(MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
void addToFront(const QVector<MTPMessage> &slice);
void addToBack(const QVector<MTPMessage> &slice);
void createInitialDateBlock(const QDateTime &date);
HistoryItem *doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg);
void addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
void addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
void addToOverview(HistoryItem *item, MediaOverviewType type);
bool addToOverviewFront(HistoryItem *item, MediaOverviewType type);
@@ -195,6 +206,7 @@ struct History : public QList<HistoryBlock*> {
void unregTyping(UserData *from);
int32 countUnread(MsgId upTo);
void updateShowFrom();
MsgId inboxRead(MsgId upTo);
MsgId inboxRead(HistoryItem *wasRead);
MsgId outboxRead(MsgId upTo);
@@ -210,8 +222,8 @@ struct History : public QList<HistoryBlock*> {
bool loadedAtBottom() const; // last message is in the list
void setNotLoadedAtBottom();
bool loadedAtTop() const; // nothing was added after loading history back
bool isReadyFor(MsgId msgId, bool check = false) const; // has messages for showing history at msgId
void getReadyFor(MsgId msgId);
bool isReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop); // has messages for showing history at msgId
void getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop);
void setLastMessage(HistoryItem *msg, bool updatePosInDialogs = true);
void setPosInDialogsDate(const QDateTime &date);
@@ -222,18 +234,6 @@ struct History : public QList<HistoryBlock*> {
MsgId msgIdForRead() const;
int32 geomResize(int32 newWidth, int32 *ytransform = 0, HistoryItem *resizedItem = 0); // return new size
int32 width, height, msgCount, unreadCount;
int32 inboxReadBefore, outboxReadBefore;
HistoryItem *showFrom;
HistoryUnreadBar *unreadBar;
PeerData *peer;
bool oldLoaded, newLoaded;
HistoryItem *lastMsg;
QDateTime lastMsgDate;
typedef QList<HistoryItem*> NotifyQueue;
NotifyQueue notifies;
void removeNotification(HistoryItem *item) {
if (!notifies.isEmpty()) {
@@ -275,6 +275,27 @@ struct History : public QList<HistoryBlock*> {
// showFrom can't be detached
}
void paintDialog(Painter &p, int32 w, bool sel) const;
void eraseFromOverview(MediaOverviewType type, MsgId msgId);
bool updateTyping(uint64 ms = 0, uint32 dots = 0, bool force = false);
void clearLastKeyboard();
typedef QList<HistoryBlock*> Blocks;
Blocks blocks;
int32 width, height, msgCount, unreadCount;
int32 inboxReadBefore, outboxReadBefore;
HistoryItem *showFrom;
HistoryUnreadBar *unreadBar;
PeerData *peer;
bool oldLoaded, newLoaded;
HistoryItem *lastMsg;
QDateTime lastMsgDate;
typedef QList<HistoryItem*> NotifyQueue;
NotifyQueue notifies;
QString draft;
MsgId draftToId;
MessageCursor draftCursor;
@@ -286,15 +307,12 @@ struct History : public QList<HistoryBlock*> {
bool lastKeyboardInited, lastKeyboardUsed;
MsgId lastKeyboardId;
PeerId lastKeyboardFrom;
void clearLastKeyboard();
mtpRequestId sendRequestId;
mutable const HistoryItem *textCachedFor; // cache
mutable Text lastItemTextCache;
void paintDialog(Painter &p, int32 w, bool sel) const;
typedef QMap<QChar, DialogRow*> DialogLinks;
DialogLinks dialogs;
uint64 posInDialogs; // like ((unixtime) << 32) | (incremented counter)
@@ -306,19 +324,71 @@ struct History : public QList<HistoryBlock*> {
QString typingStr;
Text typingText;
uint32 typingFrame;
bool updateTyping(uint64 ms = 0, uint32 dots = 0, bool force = false);
QMap<SendActionType, uint64> mySendActions;
typedef QList<MsgId> MediaOverview;
typedef QMap<MsgId, NullType> MediaOverviewIds;
MediaOverview overview[OverviewCount];
MediaOverviewIds overviewIds[OverviewCount];
int32 overviewCount[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
MediaOverview _overview[OverviewCount];
MediaOverviewIds _overviewIds[OverviewCount];
int32 _overviewCount[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
private:
void eraseFromOverview(MediaOverviewType type, MsgId msgId);
HistoryItem *addMessageGroupAfterPrevToBlock(const MTPDmessageGroup &group, const QDateTime &date, HistoryItem *prev, HistoryBlock *block);
HistoryItem *addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg);
protected:
void createInitialDateBlock(const QDateTime &date);
HistoryItem *addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block);
HistoryItem *addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex);
friend class HistoryBlock;
};
class HistoryGroup;
class HistoryCollapse;
class ChannelHistory : public History {
public:
ChannelHistory(const PeerId &peer);
void messageDetached(HistoryItem *msg);
void messageDeleted(HistoryItem *msg);
void messageWithIdDeleted(MsgId msgId);
bool isSwitchReadyFor(MsgId switchId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop); // has messages for showing history after switching mode at switchId
void getSwitchReadyFor(MsgId switchId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop);
void insertCollapseItem(MsgId wasMinId);
int32 unreadCountAll;
bool onlyImportant() const {
return _onlyImportant;
}
HistoryCollapse *collapse() const {
return _collapse;
}
private:
HistoryGroup *findGroup(MsgId msgId) const;
HistoryBlock *findGroupBlock(MsgId msgId) const;
HistoryGroup *findGroupInOther(MsgId msgId) const;
HistoryItem *findPrevItem(HistoryItem *item) const;
bool _onlyImportant;
typedef QList<HistoryItem*> OtherList;
OtherList _otherList;
bool _otherOldLoaded, _otherNewLoaded;
int32 _otherMsgCount;
HistoryCollapse *_collapse;
void switchMode();
static const int32 ScrollMax = INT_MAX;
};
enum DialogsSortMode {
@@ -596,13 +666,15 @@ struct DialogsIndexed {
DialogsIndex index;
};
struct HistoryBlock : public QVector<HistoryItem*> {
class HistoryBlock {
public:
HistoryBlock(History *hist) : y(0), height(0), history(hist) {
}
typedef QVector<HistoryItem*> Parent;
typedef QVector<HistoryItem*> Items;
Items items;
void clear(bool leaveItems = false);
Parent::iterator erase(Parent::iterator i);
~HistoryBlock() {
clear();
}
@@ -667,18 +739,25 @@ enum InfoDisplayType {
InfoDisplayOverImage,
};
inline bool isImportantChannelMessage(int32 flags) {
/*(flags & MTPDmessage_flag_out) || (flags & MTPDmessage_flag_notify_by_from) || */
return !(flags & MTPDmessage::flag_from_id) && (flags != 0); // always has_from_id || has_views
}
enum HistoryItemType {
HistoryItemMsg = 0,
HistoryItemDate,
HistoryItemUnreadBar,
HistoryItemGroup,
HistoryItemCollapse
};
class HistoryMedia;
class HistoryItem : public HistoryElem {
public:
HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from);
enum {
MsgType = 0,
DateType,
UnreadBarType
};
virtual void initDimensions() = 0;
virtual int32 resize(int32 width) = 0; // return new height
virtual void draw(Painter &p, uint32 selection) const = 0;
@@ -732,6 +811,9 @@ public:
bool fromChannel() const {
return _from->isChannel();
}
bool isImportant() const {
return _history->isChannel() && isImportantChannelMessage(_flags);
}
virtual bool needCheck() const {
return out();
}
@@ -750,8 +832,8 @@ public:
virtual uint32 adjustSelection(uint16 from, uint16 to, TextSelectType type) const {
return (from << 16) | to;
}
virtual int32 itemType() const {
return MsgType;
virtual HistoryItemType type() const {
return HistoryItemMsg;
}
virtual bool serviceMsg() const {
return false;
@@ -896,6 +978,18 @@ private:
MsgId _msgid;
};
class CommentsLink : public ITextLink {
TEXT_LINK_CLASS(CommentsLink)
public:
CommentsLink(HistoryItem *item) : _item(item) {
}
void onClick(Qt::MouseButton button) const;
private:
HistoryItem *_item;
};
HistoryItem *regItem(HistoryItem *item, bool returnExisting = false);
class HistoryMedia : public HistoryElem {
@@ -1596,6 +1690,8 @@ public:
return _media ? _media->animating() : false;
}
void setText(const QString &text);
~HistoryServiceMsg();
protected:
@@ -1624,11 +1720,77 @@ public:
QString selectedText(uint32 selection) const {
return QString();
}
int32 itemType() const {
return DateType;
HistoryItemType type() const {
return HistoryItemDate;
}
};
class HistoryGroup : public HistoryServiceMsg {
public:
HistoryGroup(History *history, HistoryBlock *block, const MTPDmessageGroup &group, const QDateTime &date);
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
symbol = 0xFFFF;
after = false;
upon = false;
}
QString selectedText(uint32 selection) const {
return QString();
}
HistoryItemType type() const {
return HistoryItemGroup;
}
void uniteWith(MsgId minId, MsgId maxId, int32 count);
void uniteWith(const HistoryGroup *other) {
uniteWith(other->_minId, other->_maxId, other->_count);
}
bool decrementCount(); // returns true if result count > 0
MsgId minId() const {
return _minId;
}
MsgId maxId() const {
return _maxId;
}
private:
MsgId _minId, _maxId;
int32 _count;
TextLinkPtr _lnk;
void updateText();
};
class HistoryCollapse : public HistoryServiceMsg {
public:
HistoryCollapse(History *history, HistoryBlock *block, MsgId wasMinId, const QDateTime &date);
void draw(Painter &p, uint32 selection) const;
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
symbol = 0xFFFF;
after = false;
upon = false;
}
QString selectedText(uint32 selection) const {
return QString();
}
HistoryItemType type() const {
return HistoryItemCollapse;
}
MsgId wasMinId() const {
return _wasMinId;
}
private:
MsgId _wasMinId;
};
HistoryItem *createDayServiceMsg(History *history, HistoryBlock *block, QDateTime date);
class HistoryUnreadBar : public HistoryItem {
@@ -1649,8 +1811,8 @@ public:
QString selectedText(uint32 selection) const {
return QString();
}
int32 itemType() const {
return UnreadBarType;
HistoryItemType type() const {
return HistoryItemUnreadBar;
}
protected: