blob: 69b6d12a5102280b830c84c382490a2aed3e9867 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/commander/commander_controller.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/commander/commander_view_model.h"
namespace commander {
namespace {
CommanderController::CommandSources CreateDefaultSources() {
return {};
}
} // namespace
CommanderController::CommanderController()
: CommanderController(CreateDefaultSources()) {}
CommanderController::CommanderController(CommandSources sources)
: current_result_set_id_(0), sources_(std::move(sources)) {}
CommanderController::~CommanderController() = default;
void CommanderController::OnDelegateViewModelCallback(
CommanderViewModel view_model) {
view_model.result_set_id = ++current_result_set_id_;
callback_.Run(view_model);
}
void CommanderController::OnTextChanged(const base::string16& text,
Browser* browser) {
if (delegate_.get())
return delegate_->OnTextChanged(text, browser);
std::vector<std::unique_ptr<CommandItem>> items;
for (auto& source : sources_) {
auto commands = source->GetCommands(text, browser);
items.insert(items.end(), std::make_move_iterator(commands.begin()),
std::make_move_iterator(commands.end()));
}
// Just sort for now.
std::sort(std::begin(items), std::end(items),
[](const std::unique_ptr<CommandItem>& left,
const std::unique_ptr<CommandItem>& right) {
return left->score > right->score;
});
// TODO(lgrey): Threshold this at some kind of max items.
current_items_ = std::move(items);
CommanderViewModel vm;
vm.result_set_id = ++current_result_set_id_;
vm.action = CommanderViewModel::Action::kDisplayResults;
for (auto& item : current_items_) {
vm.items.emplace_back(*item);
}
callback_.Run(vm);
}
void CommanderController::OnCommandSelected(size_t command_index,
int result_set_id) {
if (delegate_.get())
return delegate_->OnCommandSelected(command_index, result_set_id);
if (command_index >= current_items_.size() ||
result_set_id != current_result_set_id_)
return;
CommandItem* item = current_items_[command_index].get();
if (item->GetType() == CommandItem::Type::kOneShot) {
base::OnceClosure command = std::move(*(item->command));
// Dismiss the view.
CommanderViewModel vm;
vm.result_set_id = ++current_result_set_id_;
vm.action = CommanderViewModel::Action::kClose;
callback_.Run(vm);
std::move(command).Run();
} else {
delegate_ = std::move(*(item->delegate_factory)).Run();
// base::Unretained is safe since we own |delegate_|.
delegate_->SetUpdateCallback(
base::BindRepeating(&CommanderController::OnDelegateViewModelCallback,
base::Unretained(this)));
// Tell the view to requery.
CommanderViewModel vm;
vm.result_set_id = ++current_result_set_id_;
vm.action = CommanderViewModel::Action::kPrompt;
callback_.Run(vm);
}
}
void CommanderController::SetUpdateCallback(ViewModelUpdateCallback callback) {
callback_ = std::move(callback);
}
void CommanderController::Reset() {
current_items_.clear();
}
// static
std::unique_ptr<CommanderController>
CommanderController::CreateWithSourcesForTesting(CommandSources sources) {
auto* instance = new CommanderController(std::move(sources));
return base::WrapUnique(instance);
}
} // namespace commander