| 443 | } |
| 444 | |
| 445 | void Stories::parseAndApply( |
| 446 | const MTPPeerStories &stories, |
| 447 | ParseSource source) { |
| 448 | const auto &data = stories.data(); |
| 449 | const auto peerId = peerFromMTP(data.vpeer()); |
| 450 | const auto already = _readTill.find(peerId); |
| 451 | const auto readTill = std::max( |
| 452 | data.vmax_read_id().value_or_empty(), |
| 453 | (already != end(_readTill) ? already->second : 0)); |
| 454 | const auto peer = _owner->peer(peerId); |
| 455 | auto result = StoriesSource{ |
| 456 | .peer = peer, |
| 457 | .readTill = readTill, |
| 458 | .hidden = peer->hasStoriesHidden(), |
| 459 | }; |
| 460 | const auto &list = data.vstories().v; |
| 461 | const auto now = base::unixtime::now(); |
| 462 | result.ids.reserve(list.size()); |
| 463 | for (const auto &story : list) { |
| 464 | if (const auto id = parseAndApply(result.peer, story, now)) { |
| 465 | result.ids.emplace(id); |
| 466 | |
| 467 | if (story.type() == mtpc_storyItem) { |
| 468 | const auto &media = story.c_storyItem().vmedia(); |
| 469 | if (media.type() == mtpc_messageMediaVideoStream) { |
| 470 | result.hasVideoStream = true; |
| 471 | } |
| 472 | } |
| 473 | } |
| 474 | } |
| 475 | if (result.ids.empty()) { |
| 476 | applyDeletedFromSources(peerId, StorySourcesList::NotHidden); |
| 477 | applyDeletedFromSources(peerId, StorySourcesList::Hidden); |
| 478 | peer->setStoriesState(PeerData::StoriesState::None); |
| 479 | return; |
| 480 | } else if (peer->isSelf()) { |
| 481 | result.readTill = result.ids.back().id; |
| 482 | } |
| 483 | _readTill[peerId] = result.readTill; |
| 484 | const auto info = result.info(); |
| 485 | const auto i = _all.find(peerId); |
| 486 | if (i != end(_all)) { |
| 487 | if (i->second != result) { |
| 488 | i->second = std::move(result); |
| 489 | } |
| 490 | } else { |
| 491 | _all.emplace(peerId, std::move(result)); |
| 492 | } |
| 493 | const auto add = [&](StorySourcesList list) { |
| 494 | auto &sources = _sources[static_cast<int>(list)]; |
| 495 | const auto i = ranges::find( |
| 496 | sources, |
| 497 | peerId, |
| 498 | &StoriesSourceInfo::id); |
| 499 | if (i == end(sources)) { |
| 500 | sources.push_back(info); |
| 501 | } else if (*i == info) { |
| 502 | return; |
nothing calls this directly
no test coverage detected