removed Date service messages, removed UnreadBar service message, started adding them to HistoryItems, saving item index in block to keep an eye on the previous message

This commit is contained in:
John Preston 2016-03-18 22:05:08 +03:00
parent baf1e31b76
commit 9d00ec273b
8 changed files with 517 additions and 539 deletions

View File

@ -226,14 +226,22 @@ void Set##Name(const Type &Name) { \
Namespace##Data->Name = Name; \ Namespace##Data->Name = Name; \
} }
struct SandboxDataStruct { namespace Sandbox {
QString LangSystemISO;
int32 LangSystem = languageDefault;
QByteArray LastCrashDump; namespace internal {
ConnectionProxy PreLaunchProxy;
}; struct Data {
SandboxDataStruct *SandboxData = 0; QString LangSystemISO;
int32 LangSystem = languageDefault;
QByteArray LastCrashDump;
ConnectionProxy PreLaunchProxy;
};
}
}
Sandbox::internal::Data *SandboxData = 0;
uint64 SandboxUserTag = 0; uint64 SandboxUserTag = 0;
namespace Sandbox { namespace Sandbox {
@ -320,7 +328,7 @@ namespace Sandbox {
} }
void start() { void start() {
SandboxData = new SandboxDataStruct(); SandboxData = new internal::Data();
SandboxData->LangSystemISO = psCurrentLanguage(); SandboxData->LangSystemISO = psCurrentLanguage();
if (SandboxData->LangSystemISO.isEmpty()) SandboxData->LangSystemISO = qstr("en"); if (SandboxData->LangSystemISO.isEmpty()) SandboxData->LangSystemISO = qstr("en");
@ -349,36 +357,46 @@ namespace Sandbox {
} }
struct GlobalDataStruct { namespace Global {
uint64 LaunchId = 0; namespace internal {
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout; struct Data {
bool AdaptiveForWide = true; uint64 LaunchId = 0;
int32 DebugLoggingFlags = 0; Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
bool AdaptiveForWide = true;
// config int32 DebugLoggingFlags = 0;
int32 ChatSizeMax = 200;
int32 MegagroupSizeMax = 1000;
int32 ForwardedCountMax = 100;
int32 OnlineUpdatePeriod = 120000;
int32 OfflineBlurTimeout = 5000;
int32 OfflineIdleTimeout = 30000;
int32 OnlineFocusTimeout = 1000;
int32 OnlineCloudTimeout = 300000;
int32 NotifyCloudDelay = 30000;
int32 NotifyDefaultDelay = 1500;
int32 ChatBigSize = 10;
int32 PushChatPeriod = 60000;
int32 PushChatLimit = 2;
int32 SavedGifsLimit = 200;
int32 EditTimeLimit = 172800;
Global::HiddenPinnedMessagesMap HiddenPinnedMessages; // config
int32 ChatSizeMax = 200;
int32 MegagroupSizeMax = 1000;
int32 ForwardedCountMax = 100;
int32 OnlineUpdatePeriod = 120000;
int32 OfflineBlurTimeout = 5000;
int32 OfflineIdleTimeout = 30000;
int32 OnlineFocusTimeout = 1000;
int32 OnlineCloudTimeout = 300000;
int32 NotifyCloudDelay = 30000;
int32 NotifyDefaultDelay = 1500;
int32 ChatBigSize = 10;
int32 PushChatPeriod = 60000;
int32 PushChatLimit = 2;
int32 SavedGifsLimit = 200;
int32 EditTimeLimit = 172800;
Global::CircleMasksMap CircleMasks; HiddenPinnedMessagesMap HiddenPinnedMessages;
};
GlobalDataStruct *GlobalData = 0; PendingItemsMap PendingInitDimensionsItems;
PendingItemsMap PendingRepaintItems;
CircleMasksMap CircleMasks;
};
}
}
Global::internal::Data *GlobalData = 0;
namespace Global { namespace Global {
@ -387,7 +405,7 @@ namespace Global {
} }
void start() { void start() {
GlobalData = new GlobalDataStruct(); GlobalData = new internal::Data();
memset_rand(&GlobalData->LaunchId, sizeof(GlobalData->LaunchId)); memset_rand(&GlobalData->LaunchId, sizeof(GlobalData->LaunchId));
} }
@ -423,6 +441,9 @@ namespace Global {
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages); DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);
DefineRefVar(Global, PendingItemsMap, PendingInitDimensionsItems);
DefineRefVar(Global, PendingItemsMap, PendingRepaintItems);
DefineRefVar(Global, CircleMasksMap, CircleMasks); DefineRefVar(Global, CircleMasksMap, CircleMasks);
}; };

View File

@ -170,6 +170,10 @@ namespace Global {
typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap; typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap;
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages); DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);
typedef OrderedSet<HistoryItem*> PendingItemsMap;
DeclareRefVar(PendingItemsMap, PendingInitDimensionsItems);
DeclareRefVar(PendingItemsMap, PendingRepaintItems);
typedef QMap<uint64, QPixmap> CircleMasksMap; typedef QMap<uint64, QPixmap> CircleMasksMap;
DeclareRefVar(CircleMasksMap, CircleMasks); DeclareRefVar(CircleMasksMap, CircleMasks);

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,6 @@ public:
} }
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type); HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
// HistoryItem *addToBack(const MTPgeoChatMessage &msg, bool newMsg = true);
typedef QMap<History*, uint64> TypingHistories; // when typing in this history started typedef QMap<History*, uint64> TypingHistories; // when typing in this history started
TypingHistories typing; TypingHistories typing;
@ -208,7 +207,6 @@ struct HistoryEditDraft : public HistoryDraft {
class HistoryMedia; class HistoryMedia;
class HistoryMessage; class HistoryMessage;
class HistoryUnreadBar;
enum AddToOverviewMethod { enum AddToOverviewMethod {
AddToOverviewNew, // when new message is added to history AddToOverviewNew, // when new message is added to history
@ -244,9 +242,9 @@ public:
virtual ~History(); virtual ~History();
HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction); HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction);
HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg); HistoryItem *createItemForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg);
HistoryItem *createItemDocument(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); HistoryItem *createItemDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
HistoryItem *createItemPhoto(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); HistoryItem *createItemPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
HistoryItem *addNewService(MsgId msgId, QDateTime date, const QString &text, int32 flags = 0, HistoryMedia *media = 0, 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, NewMessageType type); HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
@ -276,6 +274,7 @@ public:
void setMute(bool newMute); void setMute(bool newMute);
void getNextShowFrom(HistoryBlock *block, int32 i); void getNextShowFrom(HistoryBlock *block, int32 i);
void addUnreadBar(); void addUnreadBar();
void destroyUnreadBar();
void clearNotifications(); void clearNotifications();
bool loadedAtBottom() const; // last message is in the list bool loadedAtBottom() const; // last message is in the list
@ -347,7 +346,7 @@ public:
int32 width, height, msgCount, unreadCount; int32 width, height, msgCount, unreadCount;
int32 inboxReadBefore, outboxReadBefore; int32 inboxReadBefore, outboxReadBefore;
HistoryItem *showFrom; HistoryItem *showFrom;
HistoryUnreadBar *unreadBar; HistoryItem *unreadBar;
PeerData *peer; PeerData *peer;
bool oldLoaded, newLoaded; bool oldLoaded, newLoaded;
@ -446,7 +445,6 @@ private:
friend class HistoryBlock; friend class HistoryBlock;
friend class ChannelHistory; friend class ChannelHistory;
void createInitialDateBlock(const QDateTime &date);
HistoryItem *addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block); HistoryItem *addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block);
HistoryItem *addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex); HistoryItem *addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex);
HistoryItem *addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg); HistoryItem *addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg);
@ -809,9 +807,12 @@ struct DialogsIndexed {
class HistoryBlock { class HistoryBlock {
public: public:
HistoryBlock(History *hist) : y(0), height(0), history(hist) { HistoryBlock(History *hist) : y(0), height(0), history(hist), _indexInHistory(-1) {
} }
HistoryBlock(const HistoryBlock &) = delete;
HistoryBlock &operator=(const HistoryBlock &) = delete;
typedef QVector<HistoryItem*> Items; typedef QVector<HistoryItem*> Items;
Items items; Items items;
@ -825,8 +826,14 @@ public:
int32 y, height; int32 y, height;
History *history; History *history;
HistoryBlock(const HistoryBlock &) = delete; HistoryBlock *previous() const {
HistoryBlock &operator=(const HistoryBlock &) = delete; return (_indexInHistory > 0) ? history->blocks.at(_indexInHistory - 1) : nullptr;
}
protected:
int _indexInHistory;
}; };
class HistoryElem { class HistoryElem {
@ -876,8 +883,6 @@ inline bool isImportantChannelMessage(MsgId id, int32 flags) { // client-side im
enum HistoryItemType { enum HistoryItemType {
HistoryItemMsg = 0, HistoryItemMsg = 0,
HistoryItemDate,
HistoryItemUnreadBar,
HistoryItemGroup, HistoryItemGroup,
HistoryItemCollapse, HistoryItemCollapse,
HistoryItemJoined HistoryItemJoined
@ -931,11 +936,40 @@ private:
}; };
// any HistoryItem can have this Interface for
// displaying the day mark above the message
struct HistoryMessageDate : public BasicInterface<HistoryMessageDate> {
HistoryMessageDate(Interfaces *);
void init(const QDateTime &date);
QString _text;
int _width;
};
// any HistoryItem can have this Interface for
// displaying the unread messages bar above the message
struct HistoryMessageUnreadBar : public BasicInterface<HistoryMessageUnreadBar> {
HistoryMessageUnreadBar(Interfaces *);
void init(int count);
QString _text;
int _width;
// if unread bar is freezed the new messages do not
// increment the counter displayed by this bar
//
// it happens when we've opened the conversation and
// we've seen the bar and new messages are marked as read
// as soon as they are added to the chat history
bool _freezed;
};
class HistoryMedia; class HistoryMedia;
class HistoryItem : public HistoryElem, public Interfaces { class HistoryItem : public HistoryElem, public Interfaces {
public: public:
HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from); HistoryItem(const HistoryItem &) = delete;
HistoryItem &operator=(const HistoryItem &) = delete;
virtual void initDimensions() = 0; virtual void initDimensions() = 0;
virtual int32 resize(int32 width) = 0; // return new height virtual int32 resize(int32 width) = 0; // return new height
@ -975,8 +1009,13 @@ public:
bool detached() const { bool detached() const {
return !_block; return !_block;
} }
void attach(HistoryBlock *block) { void attachToBlock(HistoryBlock *block, int index) {
t_assert(_block == nullptr && _indexInBlock < 0);
_block = block; _block = block;
_indexInBlock = index;
}
void setIndexInBlock(int index) {
_indexInBlock = index;
} }
bool out() const { bool out() const {
return _flags & MTPDmessage::flag_out; return _flags & MTPDmessage::flag_out;
@ -1064,6 +1103,7 @@ public:
virtual bool hasBubble() const { virtual bool hasBubble() const {
return false; return false;
} }
virtual void previousItemChanged();
virtual QString selectedText(uint32 selection) const { virtual QString selectedText(uint32 selection) const {
return qsl("[-]"); return qsl("[-]");
@ -1204,21 +1244,73 @@ public:
return author(); return author();
} }
// count > 0 - creates the unread bar if necessary and
// sets unread messages count if bar is not freezed yet
// count <= 0 - destroys the unread bar
void setUnreadBarCount(int count);
void destroyUnreadBar();
// marks the unread bar as freezed so that unread
// messages count will not change for this bar
// when the new messages arrive in this chat history
void setUnreadBarFreezed();
void clipCallback(ClipReaderNotification notification); void clipCallback(ClipReaderNotification notification);
virtual ~HistoryItem(); virtual ~HistoryItem();
protected: protected:
HistoryItem(History *history, MsgId msgId, int32 flags, QDateTime msgDate, int32 from);
// to completely create history item we need to
// call a virtual initDimensions() method,
// that can not be done from constructor
void finishCreate();
PeerData *_from; PeerData *_from;
History *_history; History *_history;
HistoryBlock *_block; HistoryBlock *_block = nullptr;
int _indexInBlock = -1;
int32 _flags; int32 _flags;
mutable int32 _authorNameVersion; mutable int32 _authorNameVersion;
HistoryItem(const HistoryItem &) = delete; HistoryItem *previous() const {
HistoryItem &operator=(const HistoryItem &) = delete; if (_block && _indexInBlock >= 0) {
if (_indexInBlock > 0) return _block->items.at(_indexInBlock - 1);
if (HistoryBlock *previousBlock = _block->previous()) {
return previousBlock->items.back();
}
}
return nullptr;
}
// this should be used only in initDimensions()
// to add required bits to the Interfaces mask
// after that always use Is<HistoryMessageDate>()
bool displayDate() const {
if (HistoryItem *prev = previous()) {
return prev->date.date().day() != date.date().day();
}
return true;
}
};
// make all the constructors in HistoryItem children protected
// and wrapped with a static create() call with the same args
// so that history item can not be created directly, without
// a finishCreate() call, which calls a virtual method initDimensions()
template <typename T>
class HistoryItemInstantiated {
public:
template <typename ... Args>
static T *_create(Args ... args) {
T *result = new T(args ...);
result->finishCreate();
return result;
}
}; };
class MessageLink : public ITextLink { class MessageLink : public ITextLink {
@ -1254,8 +1346,6 @@ private:
HistoryItem *_item; HistoryItem *_item;
}; };
HistoryItem *regItem(HistoryItem *item);
class RadialAnimation { class RadialAnimation {
public: public:
@ -1338,10 +1428,10 @@ public:
virtual void stopInline(HistoryItem *item) { virtual void stopInline(HistoryItem *item) {
} }
virtual void regItem(HistoryItem *item) { virtual void attachToItem(HistoryItem *item) {
} }
virtual void unregItem(HistoryItem *item) { virtual void detachFromItem(HistoryItem *item) {
} }
virtual void updateFrom(const MTPMessageMedia &media, HistoryItem *parent) { virtual void updateFrom(const MTPMessageMedia &media, HistoryItem *parent) {
@ -1495,8 +1585,8 @@ public:
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent); void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
void regItem(HistoryItem *item); void attachToItem(HistoryItem *item) override;
void unregItem(HistoryItem *item); void detachFromItem(HistoryItem *item) override;
bool hasReplyPreview() const { bool hasReplyPreview() const {
return !_data->thumb->isNull(); return !_data->thumb->isNull();
@ -1564,8 +1654,8 @@ public:
return _data->uploading(); return _data->uploading();
} }
void regItem(HistoryItem *item); void attachToItem(HistoryItem *item) override;
void unregItem(HistoryItem *item); void detachFromItem(HistoryItem *item) override;
bool hasReplyPreview() const { bool hasReplyPreview() const {
return !_data->thumb->isNull(); return !_data->thumb->isNull();
@ -1675,8 +1765,8 @@ public:
return _data; return _data;
} }
void regItem(HistoryItem *item); void attachToItem(HistoryItem *item) override;
void unregItem(HistoryItem *item); void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent); void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1720,7 +1810,7 @@ protected:
private: private:
void create(bool caption); void createInterfaces(bool caption);
const HistoryItem *_parent; const HistoryItem *_parent;
DocumentData *_data; DocumentData *_data;
@ -1764,8 +1854,8 @@ public:
bool playInline(HistoryItem *item); bool playInline(HistoryItem *item);
void stopInline(HistoryItem *item); void stopInline(HistoryItem *item);
void regItem(HistoryItem *item); void attachToItem(HistoryItem *item) override;
void unregItem(HistoryItem *item); void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent); void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1839,8 +1929,8 @@ public:
return _data; return _data;
} }
void regItem(HistoryItem *item); void attachToItem(HistoryItem *item) override;
void unregItem(HistoryItem *item); void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent); void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1898,8 +1988,8 @@ public:
const QString inDialogsText() const; const QString inDialogsText() const;
const QString inHistoryText() const; const QString inHistoryText() const;
void regItem(HistoryItem *item); void attachToItem(HistoryItem *item) override;
void unregItem(HistoryItem *item); void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent); void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1974,8 +2064,8 @@ public:
if (_attach) _attach->stopInline(item); if (_attach) _attach->stopInline(item);
} }
void regItem(HistoryItem *item); void attachToItem(HistoryItem *item) override;
void unregItem(HistoryItem *item); void detachFromItem(HistoryItem *item) override;
bool hasReplyPreview() const { bool hasReplyPreview() const {
return (_data->photo && !_data->photo->thumb->isNull()) || (_data->doc && !_data->doc->thumb->isNull()); return (_data->photo && !_data->photo->thumb->isNull()) || (_data->doc && !_data->doc->thumb->isNull());
@ -2113,19 +2203,29 @@ private:
}; };
class HistoryMessage : public HistoryItem { class HistoryMessage : public HistoryItem, private HistoryItemInstantiated<HistoryMessage> {
public: public:
HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg); static HistoryMessage *create(History *history, const MTPDmessage &msg) {
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd); // local forwarded return _create(history, msg);
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities); // local message }
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption); // local document static HistoryMessage *create(History *history, MsgId msgId, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd) {
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo return _create(history, msgId, flags, date, from, fwd);
}
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities) {
return _create(history, msgId, flags, viaBotId, date, from, msg, entities);
}
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
return _create(history, msgId, flags, viaBotId, date, from, doc, caption);
}
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
return _create(history, msgId, flags, viaBotId, date, from, photo, caption);
}
void initTime(); void initTime();
void initMedia(const MTPMessageMedia *media, QString &currentText); void initMedia(const MTPMessageMedia *media, QString &currentText);
void initMediaFromDocument(DocumentData *doc, const QString &caption); void initMediaFromDocument(DocumentData *doc, const QString &caption);
void initDimensions(); void initDimensions() override;
void fromNameUpdated(int32 width) const; void fromNameUpdated(int32 width) const;
virtual UserData *viaBot() const { virtual UserData *viaBot() const {
@ -2157,7 +2257,7 @@ public:
void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const; void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const;
void setViewsCount(int32 count, bool reinit = true); void setViewsCount(int32 count, bool reinit = true);
void setId(MsgId newId); void setId(MsgId newId);
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const; void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override;
virtual void drawMessageText(Painter &p, QRect trect, uint32 selection) const; virtual void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
@ -2247,7 +2347,14 @@ public:
protected: protected:
void create(int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal = 0, const PeerId &fromIdOriginal = 0, MsgId originalId = 0); HistoryMessage(History *history, const MTPDmessage &msg);
HistoryMessage(History *history, MsgId msgId, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd); // local forwarded
HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities); // local message
HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption); // local document
HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo
friend class HistoryItemInstantiated<HistoryMessage>;
void createInterfaces(int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal = 0, const PeerId &fromIdOriginal = 0, MsgId originalId = 0);
bool displayForwardedFrom() const { bool displayForwardedFrom() const {
if (const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>()) { if (const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>()) {
@ -2267,12 +2374,18 @@ protected:
}; };
class HistoryReply : public HistoryMessage { class HistoryReply : public HistoryMessage, private HistoryItemInstantiated<HistoryReply> {
public: public:
HistoryReply(History *history, HistoryBlock *block, const MTPDmessage &msg); static HistoryReply *create(History *history, const MTPDmessage &msg) {
HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); return _create(history, msg);
HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); }
static HistoryReply *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
return _create(history, msgId, flags, viaBotId, replyTo, date, from, doc, caption);
}
static HistoryReply *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
return _create(history, msgId, flags, viaBotId, replyTo, date, from, photo, caption);
}
void initDimensions() override; void initDimensions() override;
@ -2316,6 +2429,12 @@ public:
protected: protected:
HistoryReply(History *history, const MTPDmessage &msg);
HistoryReply(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
HistoryReply(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
using HistoryItemInstantiated<HistoryReply>::_create;
friend class HistoryItemInstantiated<HistoryReply>;
bool updateReplyTo(bool force = false); bool updateReplyTo(bool force = false);
void replyToNameUpdated() const; void replyToNameUpdated() const;
@ -2358,11 +2477,15 @@ struct HistoryServicePinned : public BasicInterface<HistoryServicePinned> {
TextLinkPtr lnk; TextLinkPtr lnk;
}; };
class HistoryServiceMsg : public HistoryItem { class HistoryServiceMsg : public HistoryItem, private HistoryItemInstantiated<HistoryServiceMsg> {
public: public:
HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg); static HistoryServiceMsg *create(History *history, const MTPDmessageService &msg) {
HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0); return _create(history, msg);
}
static HistoryServiceMsg *create(History *history, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0) {
return _create(history, msgId, date, msg, flags, media, from);
}
void initDimensions() override; void initDimensions() override;
@ -2421,6 +2544,10 @@ public:
protected: protected:
HistoryServiceMsg(History *history, const MTPDmessageService &msg);
HistoryServiceMsg(History *history, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0);
friend class HistoryItemInstantiated<HistoryServiceMsg>;
void setMessageByAction(const MTPmessageAction &action); void setMessageByAction(const MTPmessageAction &action);
bool updatePinned(bool force = false); bool updatePinned(bool force = false);
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr); bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);
@ -2431,33 +2558,16 @@ protected:
int32 _textWidth, _textHeight; int32 _textWidth, _textHeight;
}; };
class HistoryDateMsg : public HistoryServiceMsg { class HistoryGroup : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryGroup> {
public: public:
HistoryDateMsg(History *history, HistoryBlock *block, const QDate &date); static HistoryGroup *create(History *history, const MTPDmessageGroup &group, const QDateTime &date) {
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const { return _create(history, group, date);
lnk = TextLinkPtr();
state = HistoryDefaultCursorState;
} }
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const { static HistoryGroup *create(History *history, HistoryItem *newItem, const QDateTime &date) {
symbol = 0xFFFF; return _create(history, newItem, date);
after = false;
upon = false;
} }
void setDate(const QDateTime &date);
QString selectedText(uint32 selection) const {
return QString();
}
HistoryItemType type() const {
return HistoryItemDate;
}
};
class HistoryGroup : public HistoryServiceMsg {
public:
HistoryGroup(History *history, HistoryBlock *block, const MTPDmessageGroup &group, const QDateTime &date);
HistoryGroup(History *history, HistoryBlock *block, HistoryItem *newItem, const QDateTime &date);
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) 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 { void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
symbol = 0xFFFF; symbol = 0xFFFF;
@ -2487,6 +2597,13 @@ public:
return _maxId; return _maxId;
} }
protected:
HistoryGroup(History *history, const MTPDmessageGroup &group, const QDateTime &date);
HistoryGroup(History *history, HistoryItem *newItem, const QDateTime &date);
using HistoryItemInstantiated<HistoryGroup>::_create;
friend class HistoryItemInstantiated<HistoryGroup>;
private: private:
MsgId _minId, _maxId; MsgId _minId, _maxId;
int32 _count; int32 _count;
@ -2497,10 +2614,13 @@ private:
}; };
class HistoryCollapse : public HistoryServiceMsg { class HistoryCollapse : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryCollapse> {
public: public:
HistoryCollapse(History *history, HistoryBlock *block, MsgId wasMinId, const QDateTime &date); static HistoryCollapse *create(History *history, MsgId wasMinId, const QDateTime &date) {
return _create(history, wasMinId, date);
}
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const; void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const;
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) 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 { void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
@ -2518,46 +2638,32 @@ public:
return _wasMinId; return _wasMinId;
} }
protected:
HistoryCollapse(History *history, MsgId wasMinId, const QDateTime &date);
using HistoryItemInstantiated<HistoryCollapse>::_create;
friend class HistoryItemInstantiated<HistoryCollapse>;
private: private:
MsgId _wasMinId; MsgId _wasMinId;
}; };
class HistoryJoined : public HistoryServiceMsg { class HistoryJoined : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryJoined> {
public: public:
HistoryJoined(History *history, HistoryBlock *block, const QDateTime &date, UserData *from, int32 flags); static HistoryJoined *create(History *history, const QDateTime &date, UserData *from, int32 flags) {
return _create(history, date, from, flags);
}
HistoryItemType type() const { HistoryItemType type() const {
return HistoryItemJoined; return HistoryItemJoined;
} }
};
HistoryItem *createDayServiceMsg(History *history, HistoryBlock *block, QDateTime date);
class HistoryUnreadBar : public HistoryItem {
public:
HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date);
void initDimensions();
void setCount(int32 count);
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const;
int32 resize(int32 width);
void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const;
QString notificationText() const;
QString selectedText(uint32 selection) const {
return QString();
}
HistoryItemType type() const {
return HistoryItemUnreadBar;
}
protected: protected:
QString text; HistoryJoined(History *history, const QDateTime &date, UserData *from, int32 flags);
bool freezed; using HistoryItemInstantiated<HistoryJoined>::_create;
friend class HistoryItemInstantiated<HistoryJoined>;
}; };

View File

@ -3601,16 +3601,9 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_history->lastShowAtMsgId = ShowAtUnreadMsgId; _history->lastShowAtMsgId = ShowAtUnreadMsgId;
} }
_history->lastScrollTop = _scroll.scrollTop(); _history->lastScrollTop = _scroll.scrollTop();
if (_history->unreadBar) { destroyUnreadBar();
_history->unreadBar->destroy(); if (_pinnedBar) destroyPinnedBar();
} _history = _migrated = nullptr;
if (_migrated && _migrated->unreadBar) {
_migrated->unreadBar->destroy();
}
if (_pinnedBar) {
destroyPinnedBar();
}
_history = _migrated = 0;
updateBotKeyboard(); updateBotKeyboard();
} }
@ -4132,12 +4125,17 @@ void HistoryWidget::updateMouseTracking() {
setMouseTracking(trackMouse); setMouseTracking(trackMouse);
} }
void HistoryWidget::destroyUnreadBar() {
if (_history) _history->destroyUnreadBar();
if (_migrated) _migrated->destroyUnreadBar();
}
void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) { void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
if (App::wnd()->historyIsActive()) { if (App::wnd()->historyIsActive()) {
if (_history == history) { if (_history == history) {
historyWasRead(); historyWasRead();
if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) { if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) {
if (history->unreadBar) history->unreadBar->destroy(); destroyUnreadBar();
} }
} else { } else {
App::wnd()->notifySchedule(history, item); App::wnd()->notifySchedule(history, item);
@ -4146,8 +4144,7 @@ void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
} else { } else {
if (_history == history) { if (_history == history) {
if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) { if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) {
if (history->unreadBar) history->unreadBar->destroy(); destroyUnreadBar();
if (_migrated && _migrated->unreadBar) _migrated->unreadBar->destroy();
} }
} }
App::wnd()->notifySchedule(history, item); App::wnd()->notifySchedule(history, item);
@ -4332,12 +4329,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
void HistoryWidget::historyLoaded() { void HistoryWidget::historyLoaded() {
countHistoryShowFrom(); countHistoryShowFrom();
if (_history->unreadBar) { destroyUnreadBar();
_history->unreadBar->destroy();
}
if (_migrated && _migrated->unreadBar) {
_migrated->unreadBar->destroy();
}
doneShow(); doneShow();
} }

View File

@ -754,6 +754,9 @@ private:
void updateMouseTracking(); void updateMouseTracking();
// destroys _history and _migrated unread bars
void destroyUnreadBar();
mtpRequestId _saveEditMsgRequestId; mtpRequestId _saveEditMsgRequestId;
void saveEditMsg(); void saveEditMsg();
void saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req); void saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req);

View File

@ -1685,9 +1685,9 @@ void MainWidget::overviewLoaded(History *history, const MTPmessages_Messages &re
void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) { void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) {
if (!MTP::authedId()) return; if (!MTP::authedId()) return;
if (peer->isChannel()) { if (peer->isChannel()) {
_readRequests.insert(peer, qMakePair(MTP::send(MTPchannels_ReadHistory(peer->asChannel()->inputChannel, MTP_int(upTo)), rpcDone(&MainWidget::channelWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo)); // _readRequests.insert(peer, qMakePair(MTP::send(MTPchannels_ReadHistory(peer->asChannel()->inputChannel, MTP_int(upTo)), rpcDone(&MainWidget::channelWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
} else { } else {
_readRequests.insert(peer, qMakePair(MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo)), rpcDone(&MainWidget::historyWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo)); // _readRequests.insert(peer, qMakePair(MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo)), rpcDone(&MainWidget::historyWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
} }
} }

View File

@ -533,21 +533,21 @@ inline void destroyImplementation(I *&ptr) {
class Interfaces; class Interfaces;
typedef void(*InterfaceConstruct)(void *location, Interfaces *interfaces); typedef void(*InterfaceConstruct)(void *location, Interfaces *interfaces);
typedef void(*InterfaceDestruct)(void *location); typedef void(*InterfaceDestruct)(void *location);
typedef void(*InterfaceAssign)(void *location, void *waslocation); typedef void(*InterfaceMove)(void *location, void *waslocation);
struct InterfaceWrapStruct { struct InterfaceWrapStruct {
InterfaceWrapStruct() : Size(0), Construct(0), Destruct(0) { InterfaceWrapStruct() : Size(0), Construct(0), Destruct(0) {
} }
InterfaceWrapStruct(int size, InterfaceConstruct construct, InterfaceDestruct destruct, InterfaceAssign assign) InterfaceWrapStruct(int size, InterfaceConstruct construct, InterfaceDestruct destruct, InterfaceMove move)
: Size(size) : Size(size)
, Construct(construct) , Construct(construct)
, Destruct(destruct) , Destruct(destruct)
, Assign(assign) { , Move(move) {
} }
int Size; int Size;
InterfaceConstruct Construct; InterfaceConstruct Construct;
InterfaceDestruct Destruct; InterfaceDestruct Destruct;
InterfaceAssign Assign; InterfaceMove Move;
}; };
template <int Value, int Denominator> template <int Value, int Denominator>
@ -564,8 +564,8 @@ struct InterfaceWrapTemplate {
static void Destruct(void *location) { static void Destruct(void *location) {
((Type*)location)->~Type(); ((Type*)location)->~Type();
} }
static void Assign(void *location, void *waslocation) { static void Move(void *location, void *waslocation) {
*((Type*)location) = *((Type*)waslocation); *(Type*)location = *(Type*)waslocation;
} }
}; };
@ -585,7 +585,7 @@ public:
if (InterfaceIndexLast.testAndSetOrdered(last, last + 1)) { if (InterfaceIndexLast.testAndSetOrdered(last, last + 1)) {
t_assert(last < 64); t_assert(last < 64);
if (_index.testAndSetOrdered(0, last + 1)) { if (_index.testAndSetOrdered(0, last + 1)) {
InterfaceWraps[last] = InterfaceWrapStruct(InterfaceWrapTemplate<Type>::Size, InterfaceWrapTemplate<Type>::Construct, InterfaceWrapTemplate<Type>::Destruct, InterfaceWrapTemplate<Type>::Assign); InterfaceWraps[last] = InterfaceWrapStruct(InterfaceWrapTemplate<Type>::Size, InterfaceWrapTemplate<Type>::Construct, InterfaceWrapTemplate<Type>::Destruct, InterfaceWrapTemplate<Type>::Move);
} }
break; break;
} }
@ -634,9 +634,15 @@ public:
int size, last; int size, last;
int offsets[64]; int offsets[64];
bool equals(const uint64 &mask) const { bool equals(uint64 mask) const {
return _mask == mask; return _mask == mask;
} }
uint64 maskadd(uint64 mask) const {
return _mask | mask;
}
uint64 maskremove(uint64 mask) const {
return _mask & (~mask);
}
private: private:
uint64 _mask; uint64 _mask;
@ -682,18 +688,23 @@ public:
if (!_meta()->equals(mask)) { if (!_meta()->equals(mask)) {
Interfaces tmp(mask); Interfaces tmp(mask);
tmp.swap(*this); tmp.swap(*this);
if (_data != zerodata() && tmp._data != zerodata()) { if (_data != zerodata() && tmp._data != zerodata()) {
const InterfacesMetadata *meta = _meta(), *wasmeta = tmp._meta(); const InterfacesMetadata *meta = _meta(), *wasmeta = tmp._meta();
for (int i = 0; i < meta->last; ++i) { for (int i = 0; i < meta->last; ++i) {
int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i]; int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i];
if (offset >= 0 && wasoffset >= 0) { if (offset >= 0 && wasoffset >= 0) {
InterfaceWraps[i].Assign(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset)); InterfaceWraps[i].Move(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset));
} }
} }
} }
} }
} }
void AddInterfaces(uint64 mask = 0) {
UpdateInterfaces(_meta()->maskadd(mask));
}
void RemoveInterfaces(uint64 mask = 0) {
UpdateInterfaces(_meta()->maskremove(mask));
}
~Interfaces() { ~Interfaces() {
if (_data != zerodata()) { if (_data != zerodata()) {
const InterfacesMetadata *meta = _meta(); const InterfacesMetadata *meta = _meta();