Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0570c14343 | ||
|
|
66f2171995 | ||
|
|
3178f11596 | ||
|
|
e2d9db8928 | ||
|
|
945d1f3ae6 |
@@ -1,89 +1,89 @@
|
|||||||
{
|
{
|
||||||
"Launch": "Запуск",
|
"Launch": "Запуск",
|
||||||
"Options": "Параметры",
|
"Options": "Параметры",
|
||||||
"Homebrew Options": "Варианты домашнего пивоварения",
|
"Homebrew Options": "Параметры Homebrew",
|
||||||
"Sort By": "Сортировать по",
|
"Sort By": "Сортировать по",
|
||||||
"Sort Options": "Параметры сортировки",
|
"Sort Options": "Параметры сортировки",
|
||||||
"Updated": "Обновлено",
|
"Updated": "Обновлено",
|
||||||
"Size": "Размер",
|
"Size": "Размер",
|
||||||
"Alphabetical": "Алфавитный",
|
"Alphabetical": "По наименованию",
|
||||||
"Decending": "по убыванию",
|
"Decending": "По убыванию",
|
||||||
"Ascending": "восходящий",
|
"Ascending": "По возрастанию",
|
||||||
"Sort": "Сортировать",
|
"Sort": "Сортировать",
|
||||||
"Order": "Заказ",
|
"Order": "Порядок",
|
||||||
"Info": "Информация",
|
"Info": "Информация",
|
||||||
"Delete": "Удалить",
|
"Delete": "Удалить",
|
||||||
"Hide Sphaira": "Скрыть Сфаиру",
|
"Hide Sphaira": "Скрыть Sphaira",
|
||||||
"Are you sure you want to delete ": "Вы уверены, что хотите удалить ",
|
"Are you sure you want to delete ": "Вы уверены, что хотите удалить ",
|
||||||
"Install Forwarder": "Установить переадресатор",
|
"Install Forwarder": "Установить форвардер",
|
||||||
"WARNING: Installing forwarders will lead to a ban!": "ВНИМАНИЕ: Установка форвардеров приведет к бану!",
|
"WARNING: Installing forwarders will lead to a ban!": "ВНИМАНИЕ: Установка форвардеров приведет к бану!",
|
||||||
"Back": "Назад",
|
"Back": "Назад",
|
||||||
"Install": "Установить",
|
"Install": "Установить",
|
||||||
"Fs": "Фс",
|
"Fs": "Фс",
|
||||||
"App": "Приложение",
|
"App": "Приложение",
|
||||||
"Menu": "Меню",
|
"Menu": "Меню",
|
||||||
"Homebrew": "Домашнее пиво",
|
"Homebrew": "Homebrew",
|
||||||
"FileBrowser": "ФайлБраузер",
|
"FileBrowser": "Файловый менеджер",
|
||||||
"Open": "Открыть",
|
"Open": "Открыть",
|
||||||
"Theme Options": "Параметры темы",
|
"Theme Options": "Параметры темы",
|
||||||
"Select Theme": "Выберите тему",
|
"Select Theme": "Выберите тему",
|
||||||
"Shuffle": "Перетасовать",
|
"Shuffle": "Перетасовать",
|
||||||
"Music": "Музыка",
|
"Music": "Музыка",
|
||||||
"Show Hidden": "Показать скрытое",
|
"Show Hidden": "Показать скрытые",
|
||||||
"Folders First": "Папки в первую очередь",
|
"Folders First": "Папки в первую очередь",
|
||||||
"Hidden Last": "Скрытый последний",
|
"Hidden Last": "Скрытые в последнюю очередь",
|
||||||
"Yes": "Да",
|
"Yes": "Да",
|
||||||
"No": "Нет",
|
"No": "Нет",
|
||||||
"Network Options": "Параметры сети",
|
"Network Options": "Параметры сети",
|
||||||
"Nxlink": "Нкслинк",
|
"Nxlink": "Nxlink",
|
||||||
"Check for update": "Проверить наличие обновлений",
|
"Check for update": "Проверить наличие обновлений",
|
||||||
"File Options": "Параметры файла",
|
"File Options": "Параметры файла",
|
||||||
"Cut": "Резать",
|
"Cut": "Вырезать",
|
||||||
"Copy": "Копировать",
|
"Copy": "Копировать",
|
||||||
"Rename": "Переименовать",
|
"Rename": "Переименовать",
|
||||||
"Advanced Options": "Создать файл",
|
"Advanced Options": "Расширенные параметры",
|
||||||
"Create File": "Создать файл",
|
"Create File": "Создать файл",
|
||||||
"Create Folder": "Создать папку",
|
"Create Folder": "Создать папку",
|
||||||
"View as text": "Посмотреть как текст",
|
"View as text": "Посмотреть как текст",
|
||||||
"View as text (unfinished)": "Посмотреть как текст (незакончено)",
|
"View as text (unfinished)": "Посмотреть как текст (незакончено)",
|
||||||
"Set Archive Bit": "Установить бит архива",
|
"Set Archive Bit": "Установить Archive Bit",
|
||||||
"AppStore Options": "Параметры магазина приложений",
|
"AppStore Options": "Параметры магазина приложений",
|
||||||
"All": "Все",
|
"All": "Все",
|
||||||
"Games": "Игры",
|
"Games": "Игры",
|
||||||
"Emulators": "Эмуляторы",
|
"Emulators": "Эмуляторы",
|
||||||
"Tools": "Инструменты",
|
"Tools": "Инструменты",
|
||||||
"Advanced": "Передовой",
|
"Advanced": "Продвинутые",
|
||||||
"Themes": "Темы",
|
"Themes": "Темы",
|
||||||
"Legacy": "Наследие",
|
"Legacy": "Легаси",
|
||||||
"Misc": "Разное",
|
"Misc": "Прочее",
|
||||||
"Downloads": "Загрузки",
|
"Downloads": "Загрузки",
|
||||||
"Filter": "Фильтр",
|
"Filter": "Фильтр",
|
||||||
"Search": "Поиск",
|
"Search": "Поиск",
|
||||||
"Menu Options": "Опции меню",
|
"Menu Options": "Параметры меню",
|
||||||
"Header": "Заголовок",
|
"Header": "Заголовок",
|
||||||
"Theme": "Тема",
|
"Theme": "Тема",
|
||||||
"Network": "Сеть",
|
"Network": "Сеть",
|
||||||
"Logging": "Ведение журнала",
|
"Logging": "Журналирование",
|
||||||
"Enabled": "Включено",
|
"Enabled": "Включено",
|
||||||
"Disabled": "Неполноценный",
|
"Disabled": "Отключено",
|
||||||
"Replace hbmenu on exit": "Заменить hbmenu при выходе",
|
"Replace hbmenu on exit": "Заменить hbmenu при выходе",
|
||||||
"Misc Options": "Разные параметры",
|
"Misc Options": "Прочие параметры",
|
||||||
"Themezer": "Темезер",
|
"Themezer": "Themezer",
|
||||||
"Irs": "IRS",
|
"Irs": "Irs",
|
||||||
"Web": "Интернет",
|
"Web": "Интернет",
|
||||||
"Download": "Скачать",
|
"Download": "Скачать",
|
||||||
"Next Page": "Следующая страница",
|
"Next Page": "Следующая страница",
|
||||||
"Prev Page": "Предыдущая страница",
|
"Prev Page": "Предыдущая страница",
|
||||||
"Pad ": "Подушка ",
|
"Pad ": "Pad ",
|
||||||
" (Unconnected)": " (Не подключено)",
|
" (Unconnected)": " (Не подключено)",
|
||||||
"HandHeld": "Ручной",
|
"HandHeld": "Портативный",
|
||||||
" (Available)": " (Доступный)",
|
" (Available)": " (Доступно)",
|
||||||
"0 (Sideways)": "0 (вбок)",
|
"0 (Sideways)": "0 (набок)",
|
||||||
"90 (Flat)": "90 (квартира)",
|
"90 (Flat)": "90 (ровно)",
|
||||||
"180 (-Sideways)": "180 (-вбок)",
|
"180 (-Sideways)": "180 (-вбок)",
|
||||||
"270 (Upside down)": "270 (перевернутый)",
|
"270 (Upside down)": "270 (перевернуто)",
|
||||||
"Grey": "Серый",
|
"Grey": "Серый",
|
||||||
"Ironbow": "Железный лук",
|
"Ironbow": "Стальной",
|
||||||
"Green": "Зеленый",
|
"Green": "Зеленый",
|
||||||
"Red": "Красный",
|
"Red": "Красный",
|
||||||
"Blue": "Синий",
|
"Blue": "Синий",
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
"Dim group": "Тусклая группа",
|
"Dim group": "Тусклая группа",
|
||||||
"None": "Никто",
|
"None": "Никто",
|
||||||
"Normal image": "Обычное изображение",
|
"Normal image": "Обычное изображение",
|
||||||
"Negative image": "Негативный имидж",
|
"Negative image": "Негативное изображение",
|
||||||
"320x240": "320x240",
|
"320x240": "320x240",
|
||||||
"160x120": "160x120",
|
"160x120": "160x120",
|
||||||
"80x60": "80х60",
|
"80x60": "80х60",
|
||||||
@@ -101,13 +101,13 @@
|
|||||||
"Controller": "Контроллер",
|
"Controller": "Контроллер",
|
||||||
"Rotation": "Вращение",
|
"Rotation": "Вращение",
|
||||||
"Colour": "Цвет",
|
"Colour": "Цвет",
|
||||||
"Light Target": "Легкая мишень",
|
"Light Target": "Световая мишень",
|
||||||
"Gain": "Прирост",
|
"Gain": "Прирост",
|
||||||
"Negative Image": "Негативное изображение",
|
"Negative Image": "Негативное изображение",
|
||||||
"Format": "Формат",
|
"Format": "Формат",
|
||||||
"Trimming Format": "Формат обрезки",
|
"Trimming Format": "Формат обрезки",
|
||||||
"External Light Filter": "Внешний светофильтр",
|
"External Light Filter": "Внешний светофильтр",
|
||||||
"Load Default": "Загрузить по умолчанию",
|
"Load Default": "Загрузить умолчания",
|
||||||
"No Internet": "Нет Интернета",
|
"No Internet": "Нет Интернета",
|
||||||
"[Applet Mode]": "[Режим апплета]",
|
"[Applet Mode]": "[Режим апплета]",
|
||||||
"Language": "Язык"
|
"Language": "Язык"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(sphaira_VERSION 0.4.0)
|
set(sphaira_VERSION 0.4.1)
|
||||||
|
|
||||||
project(sphaira
|
project(sphaira
|
||||||
VERSION ${sphaira_VERSION}
|
VERSION ${sphaira_VERSION}
|
||||||
|
|||||||
@@ -1087,21 +1087,14 @@ Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"AppStore"}, m_n
|
|||||||
// check the date, if older than 1day, then fetch new file
|
// check the date, if older than 1day, then fetch new file
|
||||||
// this relaxes the spam to their server, don't want to fetch repo
|
// this relaxes the spam to their server, don't want to fetch repo
|
||||||
// every time the user opens the app!
|
// every time the user opens the app!
|
||||||
const auto time_file = (time_t)time_stamp.created;
|
const auto time_file = time_stamp.created;
|
||||||
const auto time_cur = (time_t)current_time;
|
const auto time_cur = current_time;
|
||||||
const auto tm_file = *gmtime(&time_file);
|
const auto day = 60 * 60 * 24;
|
||||||
const auto tm_cur = *gmtime(&time_cur);
|
if (time_file > time_cur || time_cur - time_file >= day) {
|
||||||
if (tm_cur.tm_yday > tm_file.tm_yday || tm_cur.tm_year > tm_file.tm_year) {
|
log_write("repo.json expired, downloading new! time_file: %zu time_cur: %zu\n", time_file, time_cur);
|
||||||
log_write("repo.json expired, downloading new! cur_yday: %d file_yday: %d | cur_year: %d file_year: %d\n", tm_cur.tm_yday, tm_file.tm_yday, tm_cur.tm_year, tm_file.tm_year);
|
|
||||||
download_file = true;
|
download_file = true;
|
||||||
} else {
|
} else {
|
||||||
log_write("repo.json not expired! cur_yday: %d file_yday: %d | cur_year: %d file_year: %d\n", tm_cur.tm_yday, tm_file.tm_yday, tm_cur.tm_year, tm_file.tm_year);
|
log_write("repo.json not expired! time_file: %zu time_cur: %zu\n", time_file, time_cur);
|
||||||
// time_file = (time_t)time_stamp.modified;
|
|
||||||
// tm_file = *gmtime(&time_file);
|
|
||||||
// log_write("repo.json not expired! cur_yday: %d file_yday: %d | cur_year: %d file_year: %d\n", tm_cur.tm_yday, tm_file.tm_yday, tm_cur.tm_year, tm_file.tm_year);
|
|
||||||
// time_file = (time_t)time_stamp.accessed;
|
|
||||||
// tm_file = *gmtime(&time_file);
|
|
||||||
// log_write("repo.json not expired! cur_yday: %d file_yday: %d | cur_year: %d file_year: %d\n", tm_cur.tm_yday, tm_file.tm_yday, tm_cur.tm_year, tm_file.tm_year);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1438,7 +1431,7 @@ void Menu::Sort() {
|
|||||||
|
|
||||||
|
|
||||||
char subheader[128]{};
|
char subheader[128]{};
|
||||||
std::snprintf(subheader, sizeof(subheader), "Sort: %s | Filter: %s | Order: %s", i18n::get(SORT_STR[m_sort]), i18n::get(FILTER_STR[m_filter]), i18n::get(ORDER_STR[m_order]));
|
std::snprintf(subheader, sizeof(subheader), "Sort: %s | Filter: %s | Order: %s", i18n::get(SORT_STR[m_sort]).c_str(), i18n::get(FILTER_STR[m_filter]).c_str(), i18n::get(ORDER_STR[m_order]).c_str());
|
||||||
SetTitleSubHeading(subheader);
|
SetTitleSubHeading(subheader);
|
||||||
|
|
||||||
std::sort(m_entries_current.begin(), m_entries_current.end(), sorter);
|
std::sort(m_entries_current.begin(), m_entries_current.end(), sorter);
|
||||||
|
|||||||
@@ -791,8 +791,9 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto t = (time_t)(e.time_stamp.modified);
|
const auto t = (time_t)(e.time_stamp.modified);
|
||||||
const auto tm = gmtime(&t);
|
struct tm tm{};
|
||||||
gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) + 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP, theme->elements[text_id].colour, "%02u/%02u/%u", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
|
localtime_r(&t, &tm);
|
||||||
|
gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) + 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP, theme->elements[text_id].colour, "%02u/%02u/%u", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
|
||||||
if ((double)e.file_size / 1024.0 / 1024.0 <= 0.009) {
|
if ((double)e.file_size / 1024.0 / 1024.0 <= 0.009) {
|
||||||
gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) - 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_BOTTOM, theme->elements[text_id].colour, "%.2f KiB", (double)e.file_size / 1024.0);
|
gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) - 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_BOTTOM, theme->elements[text_id].colour, "%.2f KiB", (double)e.file_size / 1024.0);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,34 +17,11 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <minizip/unzip.h>
|
#include <minizip/unzip.h>
|
||||||
|
#include <yyjson.h>
|
||||||
|
|
||||||
namespace sphaira::ui::menu::main {
|
namespace sphaira::ui::menu::main {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool parseSearch(const char *parse_string, const char *filter, char* new_string) {
|
|
||||||
char c;
|
|
||||||
u32 offset = 0;
|
|
||||||
const u32 filter_len = std::strlen(filter) - 1;
|
|
||||||
|
|
||||||
while ((c = parse_string[offset++]) != '\0') {
|
|
||||||
if (c == *filter) {
|
|
||||||
for (u32 i = 0; c == filter[i]; i++) {
|
|
||||||
c = parse_string[offset++];
|
|
||||||
if (i == filter_len) {
|
|
||||||
for (u32 j = 0; c != '\"'; j++) {
|
|
||||||
new_string[j] = c;
|
|
||||||
new_string[j+1] = '\0';
|
|
||||||
c = parse_string[offset++];
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string version) -> bool {
|
auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string version) -> bool {
|
||||||
static fs::FsPath zip_out{"/switch/sphaira/cache/update.zip"};
|
static fs::FsPath zip_out{"/switch/sphaira/cache/update.zip"};
|
||||||
constexpr auto chunk_size = 1024 * 512; // 512KiB
|
constexpr auto chunk_size = 1024 * 512; // 512KiB
|
||||||
@@ -169,33 +146,41 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MainMenu::MainMenu() {
|
MainMenu::MainMenu() {
|
||||||
// todo: replace below with yyjson, this is old code from ams updater, lol.
|
|
||||||
DownloadMemoryAsync("https://api.github.com/repos/ITotalJustice/sphaira/releases/latest", "", [this](std::vector<u8>& data, bool success){
|
DownloadMemoryAsync("https://api.github.com/repos/ITotalJustice/sphaira/releases/latest", "", [this](std::vector<u8>& data, bool success){
|
||||||
data.push_back('\0');
|
m_update_state = UpdateState::None;
|
||||||
auto raw_str = (const char*)data.data();
|
auto json = yyjson_read((const char*)data.data(), data.size(), 0);
|
||||||
char out_str[0x301];
|
R_UNLESS(json, false);
|
||||||
|
ON_SCOPE_EXIT(yyjson_doc_free(json));
|
||||||
|
|
||||||
if (parseSearch(raw_str, "tag_name\":\"", out_str)) {
|
auto root = yyjson_doc_get_root(json);
|
||||||
m_update_version = out_str;
|
R_UNLESS(root, false);
|
||||||
if (std::strcmp(APP_VERSION, m_update_version.c_str()) < 0) {
|
|
||||||
m_update_state = UpdateState::Update;
|
|
||||||
App::Notify("Update avaliable: "_i18n + m_update_version);
|
|
||||||
} else {
|
|
||||||
m_update_state = UpdateState::None;
|
|
||||||
}
|
|
||||||
log_write("found update tag : %s vs %s\n", APP_VERSION, out_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseSearch(raw_str, "browser_download_url\":\"", out_str)) {
|
auto tag_key = yyjson_obj_get(root, "tag_name");
|
||||||
m_update_url = out_str;
|
R_UNLESS(tag_key, false);
|
||||||
log_write("found download url : %s\n", out_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseSearch(raw_str, "body\":\"", out_str)) {
|
const auto version = yyjson_get_str(tag_key);
|
||||||
m_update_description = out_str;
|
R_UNLESS(version, false);
|
||||||
// m_update_description.replace("\r\n\r\n", "\n");
|
R_UNLESS(std::strcmp(APP_VERSION, version) < 0, false);
|
||||||
log_write("found description : %s\n", out_str);
|
|
||||||
}
|
auto assets = yyjson_obj_get(root, "assets");
|
||||||
|
R_UNLESS(assets, false);
|
||||||
|
|
||||||
|
auto idx0 = yyjson_arr_get(assets, 0);
|
||||||
|
R_UNLESS(idx0, false);
|
||||||
|
|
||||||
|
auto url_key = yyjson_obj_get(idx0, "browser_download_url");
|
||||||
|
R_UNLESS(url_key, false);
|
||||||
|
|
||||||
|
const auto url = yyjson_get_str(url_key);
|
||||||
|
R_UNLESS(url, false);
|
||||||
|
|
||||||
|
m_update_version = version;
|
||||||
|
m_update_url = url;
|
||||||
|
m_update_state = UpdateState::Update;
|
||||||
|
log_write("found url: %s\n", url);
|
||||||
|
App::Notify("Update avaliable: "_i18n + m_update_version);
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
AddOnLPress();
|
AddOnLPress();
|
||||||
|
|||||||
@@ -32,12 +32,9 @@ void MenuBase::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
u32 strength{};
|
u32 strength{};
|
||||||
u32 ip{};
|
u32 ip{};
|
||||||
|
|
||||||
const auto _time = time(NULL);
|
const auto t = time(NULL);
|
||||||
struct tm tm{};
|
struct tm tm{};
|
||||||
const auto gmt = gmtime(&_time);
|
localtime_r(&t, &tm);
|
||||||
if (gmt) {
|
|
||||||
tm = *gmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: app thread poll every 1s and this query the result
|
// todo: app thread poll every 1s and this query the result
|
||||||
psmGetBatteryChargePercentage(&battery_percetange);
|
psmGetBatteryChargePercentage(&battery_percetange);
|
||||||
|
|||||||
Reference in New Issue
Block a user