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; \
}
struct SandboxDataStruct {
QString LangSystemISO;
int32 LangSystem = languageDefault;
namespace Sandbox {
QByteArray LastCrashDump;
ConnectionProxy PreLaunchProxy;
};
SandboxDataStruct *SandboxData = 0;
namespace internal {
struct Data {
QString LangSystemISO;
int32 LangSystem = languageDefault;
QByteArray LastCrashDump;
ConnectionProxy PreLaunchProxy;
};
}
}
Sandbox::internal::Data *SandboxData = 0;
uint64 SandboxUserTag = 0;
namespace Sandbox {
@ -320,7 +328,7 @@ namespace Sandbox {
}
void start() {
SandboxData = new SandboxDataStruct();
SandboxData = new internal::Data();
SandboxData->LangSystemISO = psCurrentLanguage();
if (SandboxData->LangSystemISO.isEmpty()) SandboxData->LangSystemISO = qstr("en");
@ -349,36 +357,46 @@ namespace Sandbox {
}
struct GlobalDataStruct {
uint64 LaunchId = 0;
namespace Global {
namespace internal {
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
bool AdaptiveForWide = true;
struct Data {
uint64 LaunchId = 0;
int32 DebugLoggingFlags = 0;
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
bool AdaptiveForWide = true;
// 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;
int32 DebugLoggingFlags = 0;
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;
};
GlobalDataStruct *GlobalData = 0;
HiddenPinnedMessagesMap HiddenPinnedMessages;
PendingItemsMap PendingInitDimensionsItems;
PendingItemsMap PendingRepaintItems;
CircleMasksMap CircleMasks;
};
}
}
Global::internal::Data *GlobalData = 0;
namespace Global {
@ -387,7 +405,7 @@ namespace Global {
}
void start() {
GlobalData = new GlobalDataStruct();
GlobalData = new internal::Data();
memset_rand(&GlobalData->LaunchId, sizeof(GlobalData->LaunchId));
}
@ -423,6 +441,9 @@ namespace Global {
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);
DefineRefVar(Global, PendingItemsMap, PendingInitDimensionsItems);
DefineRefVar(Global, PendingItemsMap, PendingRepaintItems);
DefineRefVar(Global, CircleMasksMap, CircleMasks);
};

View File

@ -170,6 +170,10 @@ namespace Global {
typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap;
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);
typedef OrderedSet<HistoryItem*> PendingItemsMap;
DeclareRefVar(PendingItemsMap, PendingInitDimensionsItems);
DeclareRefVar(PendingItemsMap, PendingRepaintItems);
typedef QMap<uint64, QPixmap> CircleMasksMap;
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 *addToBack(const MTPgeoChatMessage &msg, bool newMsg = true);
typedef QMap<History*, uint64> TypingHistories; // when typing in this history started
TypingHistories typing;
@ -208,7 +207,6 @@ struct HistoryEditDraft : public HistoryDraft {
class HistoryMedia;
class HistoryMessage;
class HistoryUnreadBar;
enum AddToOverviewMethod {
AddToOverviewNew, // when new message is added to history
@ -244,9 +242,9 @@ public:
virtual ~History();
HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction);
HistoryItem *createItemForwarded(HistoryBlock *block, 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 *createItemPhoto(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
HistoryItem *createItemForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg);
HistoryItem *createItemDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, 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 *addNewMessage(const MTPMessage &msg, NewMessageType type);
@ -276,6 +274,7 @@ public:
void setMute(bool newMute);
void getNextShowFrom(HistoryBlock *block, int32 i);
void addUnreadBar();
void destroyUnreadBar();
void clearNotifications();
bool loadedAtBottom() const; // last message is in the list
@ -347,7 +346,7 @@ public:
int32 width, height, msgCount, unreadCount;
int32 inboxReadBefore, outboxReadBefore;
HistoryItem *showFrom;
HistoryUnreadBar *unreadBar;
HistoryItem *unreadBar;
PeerData *peer;
bool oldLoaded, newLoaded;
@ -446,7 +445,6 @@ private:
friend class HistoryBlock;
friend class ChannelHistory;
void createInitialDateBlock(const QDateTime &date);
HistoryItem *addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block);
HistoryItem *addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex);
HistoryItem *addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg);
@ -809,9 +807,12 @@ struct DialogsIndexed {
class HistoryBlock {
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;
Items items;
@ -825,8 +826,14 @@ public:
int32 y, height;
History *history;
HistoryBlock(const HistoryBlock &) = delete;
HistoryBlock &operator=(const HistoryBlock &) = delete;
HistoryBlock *previous() const {
return (_indexInHistory > 0) ? history->blocks.at(_indexInHistory - 1) : nullptr;
}
protected:
int _indexInHistory;
};
class HistoryElem {
@ -876,8 +883,6 @@ inline bool isImportantChannelMessage(MsgId id, int32 flags) { // client-side im
enum HistoryItemType {
HistoryItemMsg = 0,
HistoryItemDate,
HistoryItemUnreadBar,
HistoryItemGroup,
HistoryItemCollapse,
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 HistoryItem : public HistoryElem, public Interfaces {
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 int32 resize(int32 width) = 0; // return new height
@ -975,8 +1009,13 @@ public:
bool detached() const {
return !_block;
}
void attach(HistoryBlock *block) {
void attachToBlock(HistoryBlock *block, int index) {
t_assert(_block == nullptr && _indexInBlock < 0);
_block = block;
_indexInBlock = index;
}
void setIndexInBlock(int index) {
_indexInBlock = index;
}
bool out() const {
return _flags & MTPDmessage::flag_out;
@ -1064,6 +1103,7 @@ public:
virtual bool hasBubble() const {
return false;
}
virtual void previousItemChanged();
virtual QString selectedText(uint32 selection) const {
return qsl("[-]");
@ -1204,21 +1244,73 @@ public:
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);
virtual ~HistoryItem();
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;
History *_history;
HistoryBlock *_block;
HistoryBlock *_block = nullptr;
int _indexInBlock = -1;
int32 _flags;
mutable int32 _authorNameVersion;
HistoryItem(const HistoryItem &) = delete;
HistoryItem &operator=(const HistoryItem &) = delete;
HistoryItem *previous() const {
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 {
@ -1254,8 +1346,6 @@ private:
HistoryItem *_item;
};
HistoryItem *regItem(HistoryItem *item);
class RadialAnimation {
public:
@ -1338,10 +1428,10 @@ public:
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) {
@ -1495,8 +1585,8 @@ public:
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
bool hasReplyPreview() const {
return !_data->thumb->isNull();
@ -1564,8 +1654,8 @@ public:
return _data->uploading();
}
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
bool hasReplyPreview() const {
return !_data->thumb->isNull();
@ -1675,8 +1765,8 @@ public:
return _data;
}
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1720,7 +1810,7 @@ protected:
private:
void create(bool caption);
void createInterfaces(bool caption);
const HistoryItem *_parent;
DocumentData *_data;
@ -1764,8 +1854,8 @@ public:
bool playInline(HistoryItem *item);
void stopInline(HistoryItem *item);
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1839,8 +1929,8 @@ public:
return _data;
}
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1898,8 +1988,8 @@ public:
const QString inDialogsText() const;
const QString inHistoryText() const;
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
@ -1974,8 +2064,8 @@ public:
if (_attach) _attach->stopInline(item);
}
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
bool hasReplyPreview() const {
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:
HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg);
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd); // local forwarded
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
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo
static HistoryMessage *create(History *history, const MTPDmessage &msg) {
return _create(history, msg);
}
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd) {
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 initMedia(const MTPMessageMedia *media, QString &currentText);
void initMediaFromDocument(DocumentData *doc, const QString &caption);
void initDimensions();
void initDimensions() override;
void fromNameUpdated(int32 width) 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 setViewsCount(int32 count, bool reinit = true);
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;
@ -2247,7 +2347,14 @@ public:
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 {
if (const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>()) {
@ -2267,12 +2374,18 @@ protected:
};
class HistoryReply : public HistoryMessage {
class HistoryReply : public HistoryMessage, private HistoryItemInstantiated<HistoryReply> {
public:
HistoryReply(History *history, HistoryBlock *block, 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);
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, const MTPDmessage &msg) {
return _create(history, msg);
}
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;
@ -2316,6 +2429,12 @@ public:
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);
void replyToNameUpdated() const;
@ -2358,11 +2477,15 @@ struct HistoryServicePinned : public BasicInterface<HistoryServicePinned> {
TextLinkPtr lnk;
};
class HistoryServiceMsg : public HistoryItem {
class HistoryServiceMsg : public HistoryItem, private HistoryItemInstantiated<HistoryServiceMsg> {
public:
HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg);
HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0);
static HistoryServiceMsg *create(History *history, const MTPDmessageService &msg) {
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;
@ -2421,6 +2544,10 @@ public:
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);
bool updatePinned(bool force = false);
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);
@ -2431,33 +2558,16 @@ protected:
int32 _textWidth, _textHeight;
};
class HistoryDateMsg : public HistoryServiceMsg {
class HistoryGroup : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryGroup> {
public:
HistoryDateMsg(History *history, HistoryBlock *block, const QDate &date);
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const {
lnk = TextLinkPtr();
state = HistoryDefaultCursorState;
static HistoryGroup *create(History *history, const MTPDmessageGroup &group, const QDateTime &date) {
return _create(history, group, date);
}
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
symbol = 0xFFFF;
after = false;
upon = false;
static HistoryGroup *create(History *history, HistoryItem *newItem, const QDateTime &date) {
return _create(history, newItem, date);
}
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 getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
symbol = 0xFFFF;
@ -2487,6 +2597,13 @@ public:
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:
MsgId _minId, _maxId;
int32 _count;
@ -2497,10 +2614,13 @@ private:
};
class HistoryCollapse : public HistoryServiceMsg {
class HistoryCollapse : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryCollapse> {
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 getState(TextLinkPtr &lnk, HistoryCursorState &state, 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;
}
protected:
HistoryCollapse(History *history, MsgId wasMinId, const QDateTime &date);
using HistoryItemInstantiated<HistoryCollapse>::_create;
friend class HistoryItemInstantiated<HistoryCollapse>;
private:
MsgId _wasMinId;
};
class HistoryJoined : public HistoryServiceMsg {
class HistoryJoined : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryJoined> {
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 {
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:
QString text;
bool freezed;
HistoryJoined(History *history, const QDateTime &date, UserData *from, int32 flags);
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->lastScrollTop = _scroll.scrollTop();
if (_history->unreadBar) {
_history->unreadBar->destroy();
}
if (_migrated && _migrated->unreadBar) {
_migrated->unreadBar->destroy();
}
if (_pinnedBar) {
destroyPinnedBar();
}
_history = _migrated = 0;
destroyUnreadBar();
if (_pinnedBar) destroyPinnedBar();
_history = _migrated = nullptr;
updateBotKeyboard();
}
@ -4132,12 +4125,17 @@ void HistoryWidget::updateMouseTracking() {
setMouseTracking(trackMouse);
}
void HistoryWidget::destroyUnreadBar() {
if (_history) _history->destroyUnreadBar();
if (_migrated) _migrated->destroyUnreadBar();
}
void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
if (App::wnd()->historyIsActive()) {
if (_history == history) {
historyWasRead();
if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) {
if (history->unreadBar) history->unreadBar->destroy();
destroyUnreadBar();
}
} else {
App::wnd()->notifySchedule(history, item);
@ -4146,8 +4144,7 @@ void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
} else {
if (_history == history) {
if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) {
if (history->unreadBar) history->unreadBar->destroy();
if (_migrated && _migrated->unreadBar) _migrated->unreadBar->destroy();
destroyUnreadBar();
}
}
App::wnd()->notifySchedule(history, item);
@ -4332,12 +4329,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
void HistoryWidget::historyLoaded() {
countHistoryShowFrom();
if (_history->unreadBar) {
_history->unreadBar->destroy();
}
if (_migrated && _migrated->unreadBar) {
_migrated->unreadBar->destroy();
}
destroyUnreadBar();
doneShow();
}

View File

@ -754,6 +754,9 @@ private:
void updateMouseTracking();
// destroys _history and _migrated unread bars
void destroyUnreadBar();
mtpRequestId _saveEditMsgRequestId;
void saveEditMsg();
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) {
if (!MTP::authedId()) return;
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 {
_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;
typedef void(*InterfaceConstruct)(void *location, Interfaces *interfaces);
typedef void(*InterfaceDestruct)(void *location);
typedef void(*InterfaceAssign)(void *location, void *waslocation);
typedef void(*InterfaceMove)(void *location, void *waslocation);
struct InterfaceWrapStruct {
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)
, Construct(construct)
, Destruct(destruct)
, Assign(assign) {
, Move(move) {
}
int Size;
InterfaceConstruct Construct;
InterfaceDestruct Destruct;
InterfaceAssign Assign;
InterfaceMove Move;
};
template <int Value, int Denominator>
@ -564,8 +564,8 @@ struct InterfaceWrapTemplate {
static void Destruct(void *location) {
((Type*)location)->~Type();
}
static void Assign(void *location, void *waslocation) {
*((Type*)location) = *((Type*)waslocation);
static void Move(void *location, void *waslocation) {
*(Type*)location = *(Type*)waslocation;
}
};
@ -585,7 +585,7 @@ public:
if (InterfaceIndexLast.testAndSetOrdered(last, last + 1)) {
t_assert(last < 64);
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;
}
@ -634,9 +634,15 @@ public:
int size, last;
int offsets[64];
bool equals(const uint64 &mask) const {
bool equals(uint64 mask) const {
return _mask == mask;
}
uint64 maskadd(uint64 mask) const {
return _mask | mask;
}
uint64 maskremove(uint64 mask) const {
return _mask & (~mask);
}
private:
uint64 _mask;
@ -682,18 +688,23 @@ public:
if (!_meta()->equals(mask)) {
Interfaces tmp(mask);
tmp.swap(*this);
if (_data != zerodata() && tmp._data != zerodata()) {
const InterfacesMetadata *meta = _meta(), *wasmeta = tmp._meta();
for (int i = 0; i < meta->last; ++i) {
int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i];
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() {
if (_data != zerodata()) {
const InterfacesMetadata *meta = _meta();