Skip to content
Snippets Groups Projects
InputBar.cpp 39.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •     else
            file(filename, encryptedFile, url, mime, size);
    
        removeRunUpload(upload);
    }
    
    void
    InputBar::removeRunUpload(MediaUpload *upload)
    {
        auto it = std::find_if(runningUploads.begin(),
                               runningUploads.end(),
                               [upload](const UploadHandle &h) { return h.get() == upload; });
        if (it != runningUploads.end())
            runningUploads.erase(it);
    
        if (runningUploads.empty())
            setUploading(false);
        else
            runningUploads.front()->startUpload();
    }
    
    void
    InputBar::startUploadFromPath(const QString &path)
    {
        if (path.isEmpty())
            return;
    
        auto file = std::make_unique<QFile>(path);
    
        if (!file->open(QIODevice::ReadOnly)) {
            nhlog::ui()->warn(
              "Failed to open file ({}): {}", path.toStdString(), file->errorString().toStdString());
            return;
        }
    
        QMimeDatabase db;
        auto mime = db.mimeTypeForFileNameAndData(path, file.get());
    
        startUpload(std::move(file), path, mime.name());
    }
    
    void
    InputBar::startUploadFromMimeData(const QMimeData &source, const QString &format)
    {
        auto file = std::make_unique<QBuffer>();
        file->setData(source.data(format));
    
        if (!file->open(QIODevice::ReadOnly)) {
            nhlog::ui()->warn("Failed to open buffer: {}", file->errorString().toStdString());
            return;
        }
    
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        startUpload(std::move(file), {}, format);
    
    }
    void
    InputBar::startUpload(std::unique_ptr<QIODevice> dev, const QString &orgPath, const QString &format)
    {
        auto upload =
          UploadHandle(new MediaUpload(std::move(dev), format, orgPath, room->isEncrypted(), this));
        connect(upload.get(), &MediaUpload::uploadComplete, this, &InputBar::finalizeUpload);
    
        unconfirmedUploads.push_back(std::move(upload));
    
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        nhlog::ui()->debug("Uploads {}", unconfirmedUploads.size());
    
        emit uploadsChanged();
    }
    
    void
    InputBar::acceptUploads()
    {
        if (unconfirmedUploads.empty())
            return;
    
        bool wasntRunning = runningUploads.empty();
        runningUploads.insert(runningUploads.end(),
                              std::make_move_iterator(unconfirmedUploads.begin()),
                              std::make_move_iterator(unconfirmedUploads.end()));
        unconfirmedUploads.clear();
        emit uploadsChanged();
    
        if (wasntRunning) {
            setUploading(true);
            runningUploads.front()->startUpload();
        }
    }
    
    void
    InputBar::declineUploads()
    {
        unconfirmedUploads.clear();
        emit uploadsChanged();
    }
    
    QVariantList
    InputBar::uploads() const
    {
        QVariantList l;
        l.reserve((int)unconfirmedUploads.size());
    
        for (auto &e : unconfirmedUploads)
            l.push_back(QVariant::fromValue(e.get()));
        return l;
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    }
    
    void
    InputBar::startTyping()
    {
    
        if (!typingRefresh_.isActive()) {
            typingRefresh_.start();
    
            if (ChatPage::instance()->userSettings()->typingNotifications()) {
                http::client()->start_typing(
                  room->roomId().toStdString(), 10'000, [](mtx::http::RequestErr err) {
                      if (err) {
                          nhlog::net()->warn("failed to send typing notification: {}",
                                             err->matrix_error.error);
                      }
                  });
    
        }
        typingTimeout_.start();
    
    }
    void
    InputBar::stopTyping()
    {
    
        typingRefresh_.stop();
        typingTimeout_.stop();
    
        if (!ChatPage::instance()->userSettings()->typingNotifications())
            return;
    
        http::client()->stop_typing(room->roomId().toStdString(), [](mtx::http::RequestErr err) {
            if (err) {
                nhlog::net()->warn("failed to stop typing notifications: {}", err->matrix_error.error);
            }
        });
    
    
    void
    InputBar::reaction(const QString &reactedEvent, const QString &reactionKey)
    {
    
        auto reactions = room->reactions(reactedEvent.toStdString());
    
        QString selfReactedEvent;
        for (const auto &reaction : reactions) {
            if (reactionKey == reaction.key_) {
                selfReactedEvent = reaction.selfReactedEvent_;
                break;
    
        if (selfReactedEvent.startsWith(QLatin1String("m")))
    
            return;
    
        // If selfReactedEvent is empty, that means we haven't previously reacted
        if (selfReactedEvent.isEmpty()) {
            mtx::events::msg::Reaction reaction;
            mtx::common::Relation rel;
            rel.rel_type = mtx::common::RelationType::Annotation;
            rel.event_id = reactedEvent.toStdString();
            rel.key      = reactionKey.toStdString();
            reaction.relations.relations.push_back(rel);
    
            room->sendMessageEvent(reaction, mtx::events::EventType::Reaction);
    
    
            auto recents = UserSettings::instance()->recentReactions();
            if (recents.contains(reactionKey))
                recents.removeOne(reactionKey);
            else if (recents.size() >= 6)
                recents.removeLast();
            recents.push_front(reactionKey);
            UserSettings::instance()->setRecentReactions(recents);
    
            // Otherwise, we have previously reacted and the reaction should be redacted
        } else {
            room->redactEvent(selfReactedEvent);
        }