summary refs log tree commit diff
path: root/src/RoomState.cc
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2017-08-26 13:49:16 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2017-08-26 13:49:16 +0300
commit7fbfe3af153e37227087771389cf4068ff9a1fa4 (patch)
tree0a7a3e392ce97323409f502edca38202ae18f4c8 /src/RoomState.cc
parentRemove nick colors (diff)
downloadnheko-7fbfe3af153e37227087771389cf4068ff9a1fa4.tar.xz
Update the cache state at once to avoid being in an invalid state
Diffstat (limited to 'src/RoomState.cc')
-rw-r--r--src/RoomState.cc479
1 files changed, 286 insertions, 193 deletions
diff --git a/src/RoomState.cc b/src/RoomState.cc

index b22177b2..de0ed6ea 100644 --- a/src/RoomState.cc +++ b/src/RoomState.cc
@@ -26,272 +26,365 @@ namespace events = matrix::events; void RoomState::resolveName() { - name_ = "Empty Room"; - userAvatar_.clear(); + name_ = "Empty Room"; + userAvatar_.clear(); - if (!name.content().name().isEmpty()) { - name_ = name.content().name().simplified(); - return; - } + if (!name.content().name().isEmpty()) { + name_ = name.content().name().simplified(); + return; + } - if (!canonical_alias.content().alias().isEmpty()) { - name_ = canonical_alias.content().alias().simplified(); - return; - } + if (!canonical_alias.content().alias().isEmpty()) { + name_ = canonical_alias.content().alias().simplified(); + return; + } - // FIXME: Doesn't follow the spec guidelines. - if (aliases.content().aliases().size() != 0) { - name_ = aliases.content().aliases()[0].simplified(); - return; - } + // FIXME: Doesn't follow the spec guidelines. + if (aliases.content().aliases().size() != 0) { + name_ = aliases.content().aliases()[0].simplified(); + return; + } - QSettings settings; - auto user_id = settings.value("auth/user_id"); + QSettings settings; + auto user_id = settings.value("auth/user_id"); - // TODO: Display names should be sorted alphabetically. - for (const auto membership : memberships) { - if (membership.stateKey() == user_id) - continue; + // TODO: Display names should be sorted alphabetically. + for (const auto membership : memberships) { + if (membership.stateKey() == user_id) + continue; - if (membership.content().membershipState() == events::Membership::Join) { - userAvatar_ = membership.stateKey(); + if (membership.content().membershipState() == events::Membership::Join) { + userAvatar_ = membership.stateKey(); - if (membership.content().displayName().isEmpty()) - name_ = membership.stateKey(); - else - name_ = membership.content().displayName(); + if (membership.content().displayName().isEmpty()) + name_ = membership.stateKey(); + else + name_ = membership.content().displayName(); - break; - } - } + break; + } + } - // TODO: pluralization - if (memberships.size() > 2) - name_ = QString("%1 and %2 others").arg(name_).arg(memberships.size()); + // TODO: pluralization + if (memberships.size() > 2) + name_ = QString("%1 and %2 others").arg(name_).arg(memberships.size()); } void RoomState::resolveAvatar() { - if (userAvatar_.isEmpty()) { - avatar_ = avatar.content().url(); - return; - } + if (userAvatar_.isEmpty()) { + avatar_ = avatar.content().url(); + return; + } - if (memberships.contains(userAvatar_)) { - avatar_ = memberships[userAvatar_].content().avatarUrl(); - } else { - qWarning() << "Setting room avatar from unknown user id" << userAvatar_; - } + if (memberships.contains(userAvatar_)) { + avatar_ = memberships[userAvatar_].content().avatarUrl(); + } else { + qWarning() << "Setting room avatar from unknown user id" << userAvatar_; + } } // Should be used only after initial sync. void RoomState::removeLeaveMemberships() { - for (auto it = memberships.begin(); it != memberships.end();) { - if (it.value().content().membershipState() == events::Membership::Leave) { - it = memberships.erase(it); - } else { - ++it; - } - } + for (auto it = memberships.begin(); it != memberships.end();) { + if (it.value().content().membershipState() == events::Membership::Leave) { + it = memberships.erase(it); + } else { + ++it; + } + } } void RoomState::update(const RoomState &state) { - bool needsNameCalculation = false; - bool needsAvatarCalculation = false; + bool needsNameCalculation = false; + bool needsAvatarCalculation = false; - if (aliases.eventId() != state.aliases.eventId()) { - aliases = state.aliases; - } + if (aliases.eventId() != state.aliases.eventId()) { + aliases = state.aliases; + } - if (avatar.eventId() != state.avatar.eventId()) { - avatar = state.avatar; - needsAvatarCalculation = true; - } + if (avatar.eventId() != state.avatar.eventId()) { + avatar = state.avatar; + needsAvatarCalculation = true; + } - if (canonical_alias.eventId() != state.canonical_alias.eventId()) { - canonical_alias = state.canonical_alias; - needsNameCalculation = true; - } + if (canonical_alias.eventId() != state.canonical_alias.eventId()) { + canonical_alias = state.canonical_alias; + needsNameCalculation = true; + } - if (create.eventId() != state.create.eventId()) - create = state.create; - if (history_visibility.eventId() != state.history_visibility.eventId()) - history_visibility = state.history_visibility; - if (join_rules.eventId() != state.join_rules.eventId()) - join_rules = state.join_rules; + if (create.eventId() != state.create.eventId()) + create = state.create; + if (history_visibility.eventId() != state.history_visibility.eventId()) + history_visibility = state.history_visibility; + if (join_rules.eventId() != state.join_rules.eventId()) + join_rules = state.join_rules; - if (name.eventId() != state.name.eventId()) { - name = state.name; - needsNameCalculation = true; - } + if (name.eventId() != state.name.eventId()) { + name = state.name; + needsNameCalculation = true; + } - if (power_levels.eventId() != state.power_levels.eventId()) - power_levels = state.power_levels; - if (topic.eventId() != state.topic.eventId()) - topic = state.topic; + if (power_levels.eventId() != state.power_levels.eventId()) + power_levels = state.power_levels; + if (topic.eventId() != state.topic.eventId()) + topic = state.topic; - for (auto it = state.memberships.constBegin(); it != state.memberships.constEnd(); ++it) { - auto membershipState = it.value().content().membershipState(); + for (auto it = state.memberships.constBegin(); it != state.memberships.constEnd(); ++it) { + auto membershipState = it.value().content().membershipState(); - if (it.key() == userAvatar_) { - needsNameCalculation = true; - needsAvatarCalculation = true; - } + if (it.key() == userAvatar_) { + needsNameCalculation = true; + needsAvatarCalculation = true; + } - if (membershipState == events::Membership::Leave) - this->memberships.remove(it.key()); - else - this->memberships.insert(it.key(), it.value()); - } + if (membershipState == events::Membership::Leave) + this->memberships.remove(it.key()); + else + this->memberships.insert(it.key(), it.value()); + } - if (needsNameCalculation) - resolveName(); + if (needsNameCalculation) + resolveName(); - if (needsAvatarCalculation) - resolveAvatar(); + if (needsAvatarCalculation) + resolveAvatar(); } QJsonObject RoomState::serialize() const { - QJsonObject obj; + QJsonObject obj; - if (!aliases.eventId().isEmpty()) - obj["aliases"] = aliases.serialize(); + if (!aliases.eventId().isEmpty()) + obj["aliases"] = aliases.serialize(); - if (!avatar.eventId().isEmpty()) - obj["avatar"] = avatar.serialize(); + if (!avatar.eventId().isEmpty()) + obj["avatar"] = avatar.serialize(); - if (!canonical_alias.eventId().isEmpty()) - obj["canonical_alias"] = canonical_alias.serialize(); + if (!canonical_alias.eventId().isEmpty()) + obj["canonical_alias"] = canonical_alias.serialize(); - if (!create.eventId().isEmpty()) - obj["create"] = create.serialize(); + if (!create.eventId().isEmpty()) + obj["create"] = create.serialize(); - if (!history_visibility.eventId().isEmpty()) - obj["history_visibility"] = history_visibility.serialize(); + if (!history_visibility.eventId().isEmpty()) + obj["history_visibility"] = history_visibility.serialize(); - if (!join_rules.eventId().isEmpty()) - obj["join_rules"] = join_rules.serialize(); + if (!join_rules.eventId().isEmpty()) + obj["join_rules"] = join_rules.serialize(); - if (!name.eventId().isEmpty()) - obj["name"] = name.serialize(); + if (!name.eventId().isEmpty()) + obj["name"] = name.serialize(); - if (!power_levels.eventId().isEmpty()) - obj["power_levels"] = power_levels.serialize(); + if (!power_levels.eventId().isEmpty()) + obj["power_levels"] = power_levels.serialize(); - if (!topic.eventId().isEmpty()) - obj["topic"] = topic.serialize(); + if (!topic.eventId().isEmpty()) + obj["topic"] = topic.serialize(); - return obj; + return obj; } void RoomState::parse(const QJsonObject &object) { - // FIXME: Make this less versbose. + // FIXME: Make this less versbose. - if (object.contains("aliases")) { - events::StateEvent<events::AliasesEventContent> event; + if (object.contains("aliases")) { + events::StateEvent<events::AliasesEventContent> event; - try { - event.deserialize(object["aliases"]); - aliases = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - aliases" << e.what(); - } - } + try { + event.deserialize(object["aliases"]); + aliases = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - aliases" << e.what(); + } + } - if (object.contains("avatar")) { - events::StateEvent<events::AvatarEventContent> event; + if (object.contains("avatar")) { + events::StateEvent<events::AvatarEventContent> event; - try { - event.deserialize(object["avatar"]); - avatar = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - avatar" << e.what(); - } - } + try { + event.deserialize(object["avatar"]); + avatar = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - avatar" << e.what(); + } + } - if (object.contains("canonical_alias")) { - events::StateEvent<events::CanonicalAliasEventContent> event; + if (object.contains("canonical_alias")) { + events::StateEvent<events::CanonicalAliasEventContent> event; - try { - event.deserialize(object["canonical_alias"]); - canonical_alias = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - canonical_alias" << e.what(); - } - } + try { + event.deserialize(object["canonical_alias"]); + canonical_alias = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - canonical_alias" << e.what(); + } + } - if (object.contains("create")) { - events::StateEvent<events::CreateEventContent> event; + if (object.contains("create")) { + events::StateEvent<events::CreateEventContent> event; - try { - event.deserialize(object["create"]); - create = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - create" << e.what(); - } - } + try { + event.deserialize(object["create"]); + create = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - create" << e.what(); + } + } - if (object.contains("history_visibility")) { - events::StateEvent<events::HistoryVisibilityEventContent> event; + if (object.contains("history_visibility")) { + events::StateEvent<events::HistoryVisibilityEventContent> event; - try { - event.deserialize(object["history_visibility"]); - history_visibility = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - history_visibility" << e.what(); - } - } + try { + event.deserialize(object["history_visibility"]); + history_visibility = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - history_visibility" << e.what(); + } + } - if (object.contains("join_rules")) { - events::StateEvent<events::JoinRulesEventContent> event; + if (object.contains("join_rules")) { + events::StateEvent<events::JoinRulesEventContent> event; - try { - event.deserialize(object["join_rules"]); - join_rules = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - join_rules" << e.what(); - } - } + try { + event.deserialize(object["join_rules"]); + join_rules = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - join_rules" << e.what(); + } + } - if (object.contains("name")) { - events::StateEvent<events::NameEventContent> event; + if (object.contains("name")) { + events::StateEvent<events::NameEventContent> event; - try { - event.deserialize(object["name"]); - name = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - name" << e.what(); - } - } + try { + event.deserialize(object["name"]); + name = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - name" << e.what(); + } + } - if (object.contains("power_levels")) { - events::StateEvent<events::PowerLevelsEventContent> event; + if (object.contains("power_levels")) { + events::StateEvent<events::PowerLevelsEventContent> event; - try { - event.deserialize(object["power_levels"]); - power_levels = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - power_levels" << e.what(); - } - } + try { + event.deserialize(object["power_levels"]); + power_levels = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - power_levels" << e.what(); + } + } - if (object.contains("topic")) { - events::StateEvent<events::TopicEventContent> event; + if (object.contains("topic")) { + events::StateEvent<events::TopicEventContent> event; - try { - event.deserialize(object["topic"]); - topic = event; - } catch (const DeserializationException &e) { - qWarning() << "RoomState::parse - topic" << e.what(); - } - } + try { + event.deserialize(object["topic"]); + topic = event; + } catch (const DeserializationException &e) { + qWarning() << "RoomState::parse - topic" << e.what(); + } + } +} + +void +RoomState::updateFromEvents(const QJsonArray &events) +{ + events::EventType ty; + + for (const auto &event : events) { + try { + ty = events::extractEventType(event.toObject()); + } catch (const DeserializationException &e) { + qWarning() << e.what() << event; + continue; + } + + if (!events::isStateEvent(ty)) + continue; + + try { + switch (ty) { + case events::EventType::RoomAliases: { + events::StateEvent<events::AliasesEventContent> aliases; + aliases.deserialize(event); + this->aliases = aliases; + break; + } + case events::EventType::RoomAvatar: { + events::StateEvent<events::AvatarEventContent> avatar; + avatar.deserialize(event); + this->avatar = avatar; + break; + } + case events::EventType::RoomCanonicalAlias: { + events::StateEvent<events::CanonicalAliasEventContent> + canonical_alias; + canonical_alias.deserialize(event); + this->canonical_alias = canonical_alias; + break; + } + case events::EventType::RoomCreate: { + events::StateEvent<events::CreateEventContent> create; + create.deserialize(event); + this->create = create; + break; + } + case events::EventType::RoomHistoryVisibility: { + events::StateEvent<events::HistoryVisibilityEventContent> + history_visibility; + history_visibility.deserialize(event); + this->history_visibility = history_visibility; + break; + } + case events::EventType::RoomJoinRules: { + events::StateEvent<events::JoinRulesEventContent> join_rules; + join_rules.deserialize(event); + this->join_rules = join_rules; + break; + } + case events::EventType::RoomName: { + events::StateEvent<events::NameEventContent> name; + name.deserialize(event); + this->name = name; + break; + } + case events::EventType::RoomMember: { + events::StateEvent<events::MemberEventContent> member; + member.deserialize(event); + + this->memberships.insert(member.stateKey(), member); + + break; + } + case events::EventType::RoomPowerLevels: { + events::StateEvent<events::PowerLevelsEventContent> power_levels; + power_levels.deserialize(event); + this->power_levels = power_levels; + break; + } + case events::EventType::RoomTopic: { + events::StateEvent<events::TopicEventContent> topic; + topic.deserialize(event); + this->topic = topic; + break; + } + default: { + continue; + } + } + } catch (const DeserializationException &e) { + qWarning() << e.what() << event; + continue; + } + } }