update homebrew menu when app is installed from the appstore, add same effect to a few other menus (unused).

This commit is contained in:
ITotalJustice
2025-06-07 13:03:44 +01:00
parent 16c074db1a
commit 04f6e5d2a8
9 changed files with 116 additions and 21 deletions

View File

@@ -192,6 +192,28 @@ public:
}
}
static auto GetAccountList() -> std::vector<AccountProfileBase> {
std::vector<AccountProfileBase> out;
AccountUid uids[8];
s32 account_count;
if (R_SUCCEEDED(accountListAllUsers(uids, std::size(uids), &account_count))) {
for (s32 i = 0; i < account_count; i++) {
AccountProfile profile;
if (R_SUCCEEDED(accountGetProfile(&profile, uids[i]))) {
ON_SCOPE_EXIT(accountProfileClose(&profile));
AccountProfileBase base;
if (R_SUCCEEDED(accountProfileGet(&profile, nullptr, &base))) {
out.emplace_back(base);
}
}
}
}
return out;
}
// private:
static constexpr inline auto CONFIG_PATH = "/config/sphaira/config.ini";
static constexpr inline auto PLAYLOG_PATH = "/config/sphaira/playlog.ini";

View File

@@ -154,6 +154,8 @@ struct FsDirCollection {
using FsDirCollections = std::vector<FsDirCollection>;
void SignalChange();
struct Menu;
struct FsView final : Widget {
@@ -244,7 +246,7 @@ private:
}
void Sort();
void SortAndFindLastFile();
void SortAndFindLastFile(bool scan = false);
void SetIndexFromLastFile(const LastFile& last_file);
void OnDeleteCallback();

View File

@@ -25,6 +25,7 @@ enum OrderType {
using LayoutType = grid::LayoutType;
auto GetNroEntries() -> std::span<const NroEntry>;
void SignalChange();
struct Menu final : grid::Menu {
Menu();
@@ -47,7 +48,7 @@ private:
void InstallHomebrew();
void ScanHomebrew();
void Sort();
void SortAndFindLastFile();
void SortAndFindLastFile(bool scan = false);
void FreeEntries();
void OnLayoutChange();
@@ -61,6 +62,7 @@ private:
std::vector<NroEntry> m_entries{};
s64 m_index{}; // where i am in the array
std::unique_ptr<List> m_list{};
bool m_dirty{};
option::OptionLong m_sort{INI_SECTION, "sort", SortType::SortType_AlphabeticalStar};
option::OptionLong m_order{INI_SECTION, "order", OrderType::OrderType_Descending};

View File

@@ -81,6 +81,8 @@ enum OrderType {
using LayoutType = grid::LayoutType;
void SignalChange();
struct Menu final : grid::Menu {
Menu(u32 flags);
~Menu();

View File

@@ -1,4 +1,5 @@
#include "ui/menus/appstore.hpp"
#include "ui/menus/homebrew.hpp"
#include "ui/sidebar.hpp"
#include "ui/popup_list.hpp"
#include "ui/progress_box.hpp"
@@ -798,6 +799,7 @@ void EntryMenu::UpdateOptions() {
App::Push(std::make_shared<ProgressBox>(m_entry.image.image, "Downloading "_i18n, m_entry.title, [this](auto pbox){
return InstallApp(pbox, m_entry);
}, [this](Result rc){
homebrew::SignalChange();
App::PushErrorBox(rc, "Failed to, TODO: add message here"_i18n);
if (R_SUCCEEDED(rc)) {
@@ -813,6 +815,7 @@ void EntryMenu::UpdateOptions() {
App::Push(std::make_shared<ProgressBox>(m_entry.image.image, "Uninstalling "_i18n, m_entry.title, [this](auto pbox){
return UninstallApp(pbox, m_entry);
}, [this](Result rc){
homebrew::SignalChange();
App::PushErrorBox(rc, "Failed to, TODO: add message here"_i18n);
if (R_SUCCEEDED(rc)) {

View File

@@ -44,6 +44,8 @@
namespace sphaira::ui::menu::filebrowser {
namespace {
constinit UEvent g_change_uevent;
constexpr FsEntry FS_ENTRY_DEFAULT{
"microSD card", "/", FsType::Sd, FsEntryFlag_Assoc,
};
@@ -289,6 +291,10 @@ auto GetRomIcon(fs::Fs* fs, ProgressBox* pbox, std::string filename, const RomDa
} // namespace
void SignalChange() {
ueventSignal(&g_change_uevent);
}
FsView::FsView(Menu* menu, const fs::FsPath& path, const FsEntry& entry, ViewSide side) : m_menu{menu}, m_side{side} {
this->SetActions(
std::make_pair(Button::L2, Action{[this](){
@@ -1083,13 +1089,17 @@ void FsView::Sort() {
std::sort(m_entries_current.begin(), m_entries_current.end(), sorter);
}
void FsView::SortAndFindLastFile() {
void FsView::SortAndFindLastFile(bool scan) {
std::optional<LastFile> last_file;
if (!m_path.empty() && !m_entries_current.empty()) {
last_file = LastFile(GetEntry().name, m_index, m_list->GetYoff(), m_entries_current.size());
}
Sort();
if (scan) {
Scan(m_path);
} else {
Sort();
}
if (last_file.has_value()) {
SetIndexFromLastFile(*last_file);
@@ -1851,12 +1861,22 @@ Menu::Menu(u32 flags) : MenuBase{"FileBrowser"_i18n, flags} {
}
view = view_left = std::make_shared<FsView>(this, ViewSide::Left);
ueventCreate(&g_change_uevent, true);
}
Menu::~Menu() {
}
void Menu::Update(Controller* controller, TouchInfo* touch) {
if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) {
if (IsSplitScreen()) {
view_left->SortAndFindLastFile(true);
view_right->SortAndFindLastFile(true);
} else {
view->SortAndFindLastFile(true);
}
}
// workaround the buttons not being display properly.
// basically, inherit all actions from the view, draw them,
// then restore state after.

View File

@@ -5,6 +5,7 @@
#include "defines.hpp"
#include "i18n.hpp"
#include "image.hpp"
#include "swkbd.hpp"
#include "ui/menus/game_menu.hpp"
#include "ui/sidebar.hpp"
@@ -945,6 +946,33 @@ Menu::Menu(u32 flags) : grid::Menu{"Games"_i18n, flags} {
options->Add(std::make_shared<SidebarEntryBool>("Title cache"_i18n, m_title_cache.Get(), [this](bool& v_out){
m_title_cache.Set(v_out);
}));
// todo: impl this.
#if 0
options->Add(std::make_shared<SidebarEntryCallback>("Create save"_i18n, [this](){
ui::PopupList::Items items{};
const auto accounts = App::GetAccountList();
for (auto& p : accounts) {
items.emplace_back(p.nickname);
}
fsCreateSaveDataFileSystem;
App::Push(std::make_shared<ui::PopupList>(
"Select user to create save for"_i18n, items, [accounts](auto op_index){
if (op_index) {
s64 out;
if (R_SUCCEEDED(swkbd::ShowNumPad(out, "Enter the save size"_i18n.c_str()))) {
}
}
}
));
// 1. Select user to create save for.
// 2. Enter the save size.
// 3. Enter the journal size (0 for default).
}));
#endif
}})
);

View File

@@ -20,6 +20,7 @@ namespace sphaira::ui::menu::homebrew {
namespace {
Menu* g_menu{};
constinit UEvent g_change_uevent;
auto GenerateStarPath(const fs::FsPath& nro_path) -> fs::FsPath {
fs::FsPath out{};
@@ -35,6 +36,10 @@ void FreeEntry(NVGcontext* vg, NroEntry& e) {
} // namespace
void SignalChange() {
ueventSignal(&g_change_uevent);
}
auto GetNroEntries() -> std::span<const NroEntry> {
if (!g_menu) {
return {};
@@ -139,6 +144,7 @@ Menu::Menu() : grid::Menu{"Homebrew"_i18n, MenuFlag_Tab} {
);
OnLayoutChange();
ueventCreate(&g_change_uevent, true);
}
Menu::~Menu() {
@@ -147,6 +153,14 @@ Menu::~Menu() {
}
void Menu::Update(Controller* controller, TouchInfo* touch) {
if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) {
m_dirty = true;
}
if (m_dirty) {
SortAndFindLastFile(true);
}
MenuBase::Update(controller, touch);
m_list->OnUpdate(controller, touch, m_index, m_entries.size(), [this](bool touch, auto i) {
if (touch && m_index == i) {
@@ -297,6 +311,7 @@ void Menu::ScanHomebrew() {
this->Sort();
SetIndex(0);
m_dirty = false;
}
void Menu::Sort() {
@@ -391,9 +406,13 @@ void Menu::Sort() {
std::sort(m_entries.begin(), m_entries.end(), sorter);
}
void Menu::SortAndFindLastFile() {
void Menu::SortAndFindLastFile(bool scan) {
const auto path = m_entries[m_index].path;
Sort();
if (scan) {
ScanHomebrew();
} else {
Sort();
}
SetIndex(0);
s64 index = -1;

View File

@@ -41,6 +41,8 @@ constexpr u32 NX_SAVE_META_MAGIC = 0x4A4B5356; // JKSV
constexpr u32 NX_SAVE_META_VERSION = 1;
constexpr const char* NX_SAVE_META_NAME = ".nx_save_meta.bin";
constinit UEvent g_change_uevent;
// https://github.com/J-D-K/JKSV/issues/264#issuecomment-2618962807
struct NXSaveMeta {
u32 magic{}; // NX_SAVE_META_MAGIC
@@ -714,6 +716,10 @@ void ThreadFunc(void* user) {
} // namespace
void SignalChange() {
ueventSignal(&g_change_uevent);
}
ThreadData::ThreadData() {
ueventCreate(&m_uevent, true);
mutexInit(&m_mutex_id);
@@ -928,21 +934,7 @@ Menu::Menu(u32 flags) : grid::Menu{"Saves"_i18n, flags} {
OnLayoutChange();
nsInitialize();
AccountUid uids[8];
s32 account_count;
if (R_SUCCEEDED(accountListAllUsers(uids, std::size(uids), &account_count))) {
for (s32 i = 0; i < account_count; i++) {
AccountProfile profile;
if (R_SUCCEEDED(accountGetProfile(&profile, uids[i]))) {
ON_SCOPE_EXIT(accountProfileClose(&profile));
AccountProfileBase base;
if (R_SUCCEEDED(accountProfileGet(&profile, nullptr, &base))) {
m_accounts.emplace_back(base);
}
}
}
}
m_accounts = App::GetAccountList();
// try and find the last / default account and set that.
AccountUid uid{};
@@ -965,6 +957,7 @@ Menu::Menu(u32 flags) : grid::Menu{"Saves"_i18n, flags} {
threadCreate(&m_thread, ThreadFunc, &m_thread_data, nullptr, 1024*32, THREAD_PRIO, THREAD_CORE);
svcSetThreadCoreMask(m_thread.handle, THREAD_CORE, THREAD_AFFINITY_DEFAULT(THREAD_CORE));
threadStart(&m_thread);
ueventCreate(&g_change_uevent, true);
}
Menu::~Menu() {
@@ -982,6 +975,10 @@ Menu::~Menu() {
}
void Menu::Update(Controller* controller, TouchInfo* touch) {
if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) {
m_dirty = true;
}
if (m_dirty) {
App::Notify("Updating application record list");
SortAndFindLastFile(true);