File indexing completed on 2024-05-05 05:40:26
0001 /*************************************************************************** 0002 * Copyright (C) 2020 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * This software is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "data/chatroom.h" 0021 0022 #include <QtConcurrent> 0023 #include <set> 0024 0025 #include "model/playermodel.h" 0026 #include "worker/utilshelper.h" 0027 #include <diceparser_qobject/diceroller.h> 0028 0029 namespace InstantMessaging 0030 { 0031 namespace 0032 { 0033 InstantMessaging::MessageInterface::MessageType textToType(const QString& text) 0034 { 0035 auto type= InstantMessaging::MessageInterface::Text; 0036 if(text.startsWith("!")) 0037 type= InstantMessaging::MessageInterface::Dice; 0038 else if(text.startsWith("/")) 0039 type= InstantMessaging::MessageInterface::Command; 0040 0041 return type; 0042 } 0043 } // namespace 0044 ChatRoom::ChatRoom(PlayerModel* model, ChatRoomType type, const QStringList& recipiants, const QString& id, 0045 QObject* parent) 0046 : QObject(parent) 0047 , m_recipiants(new FilteredPlayerModel(recipiants)) 0048 , m_messageModel(new MessageModel(model)) 0049 , m_type(type) 0050 , m_uuid(id) 0051 { 0052 connect(m_messageModel.get(), &MessageModel::localIdChanged, this, &ChatRoom::localIdChanged); 0053 connect(m_messageModel.get(), &MessageModel::unreadMessageChanged, this, [this]() { setUnreadMessage(true); }); 0054 } 0055 0056 ChatRoom::~ChatRoom()= default; 0057 0058 MessageModel* ChatRoom::messageModel() const 0059 { 0060 return m_messageModel.get(); 0061 } 0062 0063 bool ChatRoom::unreadMessage() const 0064 { 0065 return m_unreadMessage; 0066 } 0067 0068 QString ChatRoom::uuid() const 0069 { 0070 return m_uuid; 0071 } 0072 0073 QString ChatRoom::localId() const 0074 { 0075 return m_messageModel->localId(); 0076 } 0077 0078 FilteredPlayerModel* ChatRoom::recipiants() const 0079 { 0080 return m_recipiants.get(); 0081 } 0082 0083 QString ChatRoom::title() const 0084 { 0085 return m_title; 0086 } 0087 0088 ChatRoom::ChatRoomType ChatRoom::type() const 0089 { 0090 return m_type; 0091 } 0092 0093 int ChatRoom::recipiantCount() const 0094 { 0095 return m_recipiants->rowCount(); 0096 } 0097 0098 void ChatRoom::setUuid(const QString& id) 0099 { 0100 if(id == m_uuid) 0101 return; 0102 m_uuid= id; 0103 emit uuidChanged(m_uuid); 0104 } 0105 0106 void ChatRoom::setTitle(const QString& title) 0107 { 0108 if(m_title == title) 0109 return; 0110 m_title= title; 0111 emit titleChanged(m_title); 0112 } 0113 0114 void ChatRoom::setUnreadMessage(bool b) 0115 { 0116 if(b == m_unreadMessage) 0117 return; 0118 m_unreadMessage= b; 0119 emit unreadMessageChanged(m_unreadMessage); 0120 } 0121 0122 void ChatRoom::addMessage(const QString& text, const QUrl& url, const QString& personId, const QString& personName) 0123 { 0124 auto type= textToType(text); 0125 using IM= InstantMessaging::MessageInterface; 0126 bool valid= false; 0127 if(type == IM::Dice) 0128 { // dice 0129 auto command= text; 0130 valid= rollDice(command.remove(0, 1), personId); 0131 } 0132 else if(type == IM::Command) 0133 { 0134 auto command= text; 0135 valid= runCommand(command.remove(0, 1), personId, personName); 0136 } 0137 0138 if(type == IM::Text || !valid) 0139 { 0140 m_messageModel->addMessage(text, url, QDateTime::currentDateTime(), localId(), 0141 personId.isEmpty() ? localId() : personId, type); 0142 } 0143 } 0144 0145 bool ChatRoom::rollDice(const QString& command, const QString& personId) 0146 { 0147 using IM= InstantMessaging::MessageInterface; 0148 auto id= personId.isEmpty() ? localId() : personId; 0149 0150 helper::utils::setContinuation<std::pair<bool, QString>>( 0151 QtConcurrent::run( 0152 [this, command, id]() -> std::pair<bool, QString> 0153 { 0154 if(!m_diceParser) 0155 return {false, tr("No Diceparser Object")}; 0156 0157 auto diceParser= m_diceParser->parser(); 0158 0159 if(!diceParser->parseLine(command)) 0160 { 0161 auto error= diceParser->humanReadableError(); 0162 return {false, error}; 0163 } 0164 0165 diceParser->start(); 0166 auto error= diceParser->humanReadableError(); 0167 if(!error.isEmpty()) 0168 return {false, error}; 0169 0170 auto result= diceParser->resultAsJSon( 0171 [](const QString& value, const QString& color, bool highlight) 0172 { 0173 QString resultTmp= value; 0174 bool hasColor= !color.isEmpty(); 0175 QString style; 0176 if(hasColor) 0177 { 0178 style+= QStringLiteral("color:%1;").arg(color); 0179 } 0180 if(highlight) 0181 { 0182 if(style.isEmpty()) 0183 style+= QStringLiteral("color:%1;") 0184 .arg("red"); // default color must get the value from the setting object 0185 style+= QStringLiteral("font-weight:bold;"); 0186 } 0187 if(!style.isEmpty()) 0188 resultTmp= QString("<span style=\"%2\">%1</span>").arg(value).arg(style); 0189 return resultTmp; 0190 }); 0191 return {true, result}; 0192 }), 0193 this, 0194 [this, id](const std::pair<bool, QString>& result) 0195 { 0196 m_messageModel->addMessage(result.second, {}, QDateTime::currentDateTime(), localId(), id, 0197 result.first ? IM::Dice : IM::Error); 0198 }); 0199 0200 return true; 0201 } 0202 0203 bool ChatRoom::runCommand(const QString& command, const QString& personId, const QString& personName) 0204 { 0205 QStringList meCommand({"emote ", "me ", "em ", "e "}); 0206 auto text= command; 0207 for(auto const& e : qAsConst(meCommand)) 0208 { 0209 if(text.startsWith(e)) 0210 { 0211 text.remove(0, e.size()); 0212 text= QString("<i>%2 %1<\\i>").arg(text).arg(personName); 0213 m_messageModel->addMessage(text, {}, QDateTime::currentDateTime(), localId(), 0214 personId.isEmpty() ? localId() : personId, 0215 InstantMessaging::MessageInterface::Command); 0216 return true; 0217 } 0218 } 0219 0220 return false; 0221 } 0222 0223 void ChatRoom::addMessageInterface(MessageInterface* message) 0224 { 0225 m_messageModel->addMessageInterface(message); 0226 } 0227 0228 void ChatRoom::setLocalId(const QString& id) 0229 { 0230 m_messageModel->setLocalId(id); 0231 } 0232 bool ChatRoom::hasRecipiant(const QString& id) 0233 { 0234 return m_recipiants->hasRecipiant(id); 0235 } 0236 0237 void ChatRoom::setDiceParser(DiceRoller* diceParser) 0238 { 0239 m_diceParser= diceParser; 0240 } 0241 } // namespace InstantMessaging