From c4a2c182d570cb484270874410cccb0c4e4a695a Mon Sep 17 00:00:00 2001 From: cooolgamer <64099608+cooolgamer@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:28:22 +0100 Subject: [PATCH 1/6] added french in settings --- source/scenes/setting_menu.cpp | 1304 ++++++++++++++++---------------- 1 file changed, 653 insertions(+), 651 deletions(-) diff --git a/source/scenes/setting_menu.cpp b/source/scenes/setting_menu.cpp index 5ce75788..9097f71f 100644 --- a/source/scenes/setting_menu.cpp +++ b/source/scenes/setting_menu.cpp @@ -1,651 +1,653 @@ -#include "headers.hpp" -#include -#include - -#include "data_io/settings.hpp" -#include "data_io/history.hpp" -#include "util/misc_tasks.hpp" -#include "scenes/setting_menu.hpp" -#include "scenes/video_player.hpp" -#include "ui/overlay.hpp" -#include "ui/ui.hpp" -#include "youtube_parser/parser.hpp" -#include "network_decoder/thumbnail_loader.hpp" -#include "network_decoder/network_io.hpp" -#include "rapidjson_wrapper.hpp" - -namespace Settings { - bool thread_suspend = false; - bool already_init = false; - bool exiting = false; - - bool is_3dsx = false; - std::string path_3dsx; - - TextView *toast_view; - int toast_frames_left = 0; - - OverlayDialogView *popup_view; - VerticalListView *main_view; - TabView *main_tab_view; - - ProgressBarView *update_progress_bar_view; - - int CONTENT_Y_HIGH = 240; - constexpr int TOP_HEIGHT = MIDDLE_FONT_INTERVAL + SMALL_MARGIN * 2; - - constexpr int DIALOG_WIDTH = 240; - - // used for updating of the app - enum class UpdateState { - CHECKING_UPDATES, - FAILED_CHECKING, - UP_TO_DATE, - UPDATES_AVAILABLE, - INSTALLING, - FAILED_INSTALLING, - SUCCEEDED_INSTALLING - }; - UpdateState update_state = UpdateState::CHECKING_UPDATES; - - static std::string update_error_message; - - static std::string update_url_cia; - static std::string update_url_3dsx; - static std::string next_version_str; - static Mutex resource_lock; - static std::string install_progress_str; - - static Thread update_worker_thread; - - Thread settings_misc_thread; -}; -using namespace Settings; - - - -std::string install_update(NetworkSessionList &session_list) { - std::string new_error_message = ""; - auto url = is_3dsx ? update_url_3dsx : update_url_cia; - // auto url = update_url_cia; - - resource_lock.lock(); - install_progress_str = LOCALIZED(ACCESSING); - resource_lock.unlock(); - update_progress_bar_view->set_progress(0); - update_progress_bar_view->set_is_visible(true); - - bool first = true; - auto result = session_list.perform(HttpRequest::GET(url, {}).with_progress_func([&] (u64 now, u64 total) { - if (total < 10000) return; // ignore header(?) - if (first) { - first = false; - resource_lock.lock(); - install_progress_str = LOCALIZED(DOWNLOADING); - resource_lock.unlock(); - } - update_progress_bar_view->set_progress((double) now / total); - })); - - if (result.fail) return "curl deep fail : " + result.error; - if (result.status_code != 200) return "http returned " + std::to_string(result.status_code); - - resource_lock.lock(); - install_progress_str = LOCALIZED(INSTALLING); - resource_lock.unlock(); - update_progress_bar_view->set_progress(1.0); - - Result libctru_result; - if (is_3dsx) { - char *slash_ptr = strrchr(path_3dsx.c_str(), '/'); - if (!slash_ptr) return "no slash in 3dsx path : " + path_3dsx; - size_t slash_index = slash_ptr - path_3dsx.c_str(); - auto tmp_res = Path(path_3dsx).write_file(result.data.data(), result.data.size()); - if (tmp_res.code != 0) return "Failed to write to .3dsx file : " + tmp_res.string + " " + std::to_string(tmp_res.code); - } else { - Handle am_handle = 0; - if ((libctru_result = AM_StartCiaInstall(MEDIATYPE_SD, &am_handle))) return "AM_StartCiaInstall() returned " + std::to_string(libctru_result); - - update_progress_bar_view->set_progress(0.0); - - const size_t BLOCK_SIZE = 200000; - for (size_t i = 0; i < result.data.size(); ) { - size_t size = std::min(BLOCK_SIZE, result.data.size() - i); - u32 size_written; - libctru_result = FSFILE_Write(am_handle, &size_written, i, result.data.data() + i, size, FS_WRITE_FLUSH); - i += size_written; - if (libctru_result) return "FSFILE_Write() returned " + std::to_string(libctru_result); - update_progress_bar_view->set_progress((double) i / result.data.size()); - } - update_progress_bar_view->set_progress(1.0); - - libctru_result = AM_FinishCiaInstall(am_handle); - if (libctru_result) return "AM_FinishCiaInstall() returned " + std::to_string(libctru_result); - } - return ""; -} - -static void update_worker_thread_func(void *) { - logger.info("updater", "Thread started."); - - static NetworkSessionList session_list; - session_list.init(); - - while (!exiting) { - if (update_state == UpdateState::CHECKING_UPDATES) { - std::string new_error_message; - - bool check_success = false; - auto result = session_list.perform(HttpRequest::GET("https://api.github.com/repos/windows-server-2003/ThirdTube/releases/latest", {})); - if (result.fail) new_error_message = "Failed accessing(deep fail) : " + result.fail; - else if (result.status_code == 200) { - result.data.push_back('\0'); - rapidjson::Document json_root; - std::string error; - RJson result_json = RJson::parse(json_root, (char *) result.data.data(), error); - if (error != "") { - logger.error("updater", "failed to parse json : " + error); - new_error_message = "failed to parse json : " + error; - } else { - update_url_3dsx = update_url_cia; - for (auto item : result_json["assets"].array_items()) { - auto url = item["browser_download_url"].string_value(); - if (url.size() >= 5 && url.substr(url.size() - 5, 5) == ".3dsx") update_url_3dsx = url; - if (url.size() >= 4 && url.substr(url.size() - 4, 4) == ".cia") update_url_cia = url; - } - if (update_url_cia == "") new_error_message = "could not find .cia url"; - if (update_url_3dsx == "") new_error_message = "could not find .3dsx url"; - if (update_url_cia != "" && update_url_3dsx != "") { - // lexicographically compare the sequence of version numbers ([0, 4, 1] if v0.4.1) - auto version_str_to_vector = [] (const std::string &str) { - size_t head = 0; - std::vector res; - while (head < str.size()) { - while (head < str.size() && !isdigit(str[head])) head++; - if (head >= str.size()) break; - int cur = 0; - while (head < str.size() && isdigit(str[head])) cur = cur * 10 + str[head++] - '0'; - res.push_back(cur); - } - return res; - }; - auto new_version_seq = version_str_to_vector(result_json["tag_name"].string_value()); - auto cur_version_seq = version_str_to_vector(DEF_CURRENT_APP_VER); - bool update_available = cur_version_seq < new_version_seq; - if (update_available) update_state = UpdateState::UPDATES_AVAILABLE, next_version_str = result_json["tag_name"].string_value(); - else update_state = UpdateState::UP_TO_DATE; - check_success = true; - } - } - } else new_error_message = "http returned " + std::to_string(result.status_code); - if (!check_success) update_state = UpdateState::FAILED_CHECKING; - if (new_error_message != "") { - resource_lock.lock(); - update_error_message = new_error_message; - resource_lock.unlock(); - } - } - if (update_state == UpdateState::INSTALLING) { - std::string error = install_update(session_list); - if (error == "") update_state = UpdateState::SUCCEEDED_INSTALLING; - else { - resource_lock.lock(); - update_error_message = error; - resource_lock.unlock(); - update_state = UpdateState::FAILED_INSTALLING; - } - } - usleep(100000); - } - - logger.info("updater", "Thread exit."); - threadExit(0); -} - - - -void Sem_init(void) { - logger.info("settings/init", "Initializing..."); - Result_with_string result; - - load_settings(); - load_string_resources(var_lang); - - popup_view = new OverlayDialogView(0, 0, 320, 240); - popup_view->set_is_visible(false); - toast_view = new TextView((320 - 150) / 2, 190, 150, DEFAULT_FONT_INTERVAL + SMALL_MARGIN); - toast_view->set_is_visible(false); - - main_tab_view = (new TabView(0, 0, 320, CONTENT_Y_HIGH - TOP_HEIGHT)) - ->set_stretch_subview(true) - ->set_views({ - // Tab #1 : UI/Display - (new ScrollView(0, 0, 320, 0)) - ->set_views({ - // UI language - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(LANG_EN); }, - (std::function) []() { return LOCALIZED(LANG_JA); } - }, var_lang == "ja" ? 1 : 0) - ->set_title([](const SelectorView &) { return LOCALIZED(UI_LANGUAGE); }) - ->set_on_change([](const SelectorView &view) { - auto next_lang = std::vector{"en", "ja"}[view.selected_button]; - if (var_lang != next_lang) { - var_lang = next_lang; - misc_tasks_request(TASK_RELOAD_STRING_RESOURCE); - misc_tasks_request(TASK_SAVE_SETTINGS); - } - }), - // Content language - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(LANG_EN); }, - (std::function) []() { return LOCALIZED(LANG_JA); } - }, var_lang_content == "ja" ? 1 : 0) - ->set_title([](const SelectorView &) { return LOCALIZED(CONTENT_LANGUAGE); }) - ->set_on_change([](const SelectorView &view) { - auto next_lang = std::vector{"en", "ja"}[view.selected_button]; - if (var_lang_content != next_lang) { - var_lang_content = next_lang; - misc_tasks_request(TASK_SAVE_SETTINGS); - youtube_change_content_language(var_lang_content); - } - }), - // LCD Brightness - (new BarView(0, 0, 320, 40)) - ->set_values_sync(15, 163, &var_lcd_brightness) - ->set_title([] (const BarView &view) { return LOCALIZED(LCD_BRIGHTNESS); }) - ->set_while_holding([] (const BarView &view) { misc_tasks_request(TASK_CHANGE_BRIGHTNESS); }) - ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), - // Time to turn off LCD - (new BarView(0, 0, 320, 40)) - ->set_values(10, 310, var_time_to_turn_off_lcd <= 309 ? var_time_to_turn_off_lcd : 310) - ->set_title([] (const BarView &view) { return LOCALIZED(TIME_TO_TURN_OFF_LCD) + " : " + - (view.get_value() <= 309 ? std::to_string((int) view.get_value()) + " " + LOCALIZED(SECONDS) : LOCALIZED(NEVER_TURN_OFF)); }) - ->set_on_release([] (const BarView &view) { - var_time_to_turn_off_lcd = view.get_value() <= 309 ? view.get_value() : 1000000000; - misc_tasks_request(TASK_SAVE_SETTINGS); - }), - // full screen mode - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(OFF); }, - (std::function) []() { return LOCALIZED(ON); } - }, var_full_screen_mode) - ->set_title([](const SelectorView &) { return LOCALIZED(FULL_SCREEN_MODE); }) - ->set_on_change([](const SelectorView &view) { - if (var_full_screen_mode != view.selected_button) { - var_full_screen_mode = view.selected_button; - misc_tasks_request(TASK_SAVE_SETTINGS); - } - }), - // Dark theme (plus flash) - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(OFF); }, - (std::function) []() { return LOCALIZED(ON); }, - (std::function) []() { return LOCALIZED(FLASH); } - }, var_flash_mode ? 2 : var_night_mode) - ->set_title([](const SelectorView &) { return LOCALIZED(DARK_THEME); }) - ->set_on_change([](const SelectorView &view) { - if (var_flash_mode != (view.selected_button == 2)) { - var_flash_mode = (view.selected_button == 2); - misc_tasks_request(TASK_SAVE_SETTINGS); - } - if (!var_flash_mode && var_night_mode != view.selected_button) { - var_night_mode = view.selected_button; - misc_tasks_request(TASK_SAVE_SETTINGS); - } - }), - // Scroll speed 0 - (new BarView(0, 0, 320, 35)) - ->set_values_sync(DPAD_SCROLL_SPEED_MIN, DPAD_SCROLL_SPEED_MAX, &var_dpad_scroll_speed0) - ->set_title([] (const BarView &view) { return LOCALIZED(SCROLL_SPEED0) + " : " + double2str(var_dpad_scroll_speed0, 1); }) - ->set_while_holding([] (const BarView &view) { - var_dpad_scroll_speed1 = std::max(var_dpad_scroll_speed1, var_dpad_scroll_speed0); - }) - ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), - // Scroll speed 1 - (new BarView(0, 0, 320, 35)) - ->set_values_sync(DPAD_SCROLL_SPEED_MIN, DPAD_SCROLL_SPEED_MAX, &var_dpad_scroll_speed1) - ->set_title([] (const BarView &view) { return LOCALIZED(SCROLL_SPEED1) + " : " + double2str(var_dpad_scroll_speed1, 1); }) - ->set_while_holding([] (const BarView &view) { - var_dpad_scroll_speed0 = std::min(var_dpad_scroll_speed0, var_dpad_scroll_speed1); - }) - ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), - // Scroll speed change threashold - (new BarView(0, 0, 320, 40)) - ->set_values_sync(DPAD_SCROLL_THREASHOLD_MIN, DPAD_SCROLL_THREASHOLD_MAX, &var_dpad_scroll_speed1_threashold) - ->set_title([] (const BarView &view) { return LOCALIZED(SCROLL_SPEED_THREASHOLD) + " : " + double2str(var_dpad_scroll_speed1_threashold, 1); }) - ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), - // Size of images in community posts - (new BarView(0, 0, 320, 40)) - ->set_values_sync(COMMUNITY_IMAGE_SIZE_MIN, COMMUNITY_IMAGE_SIZE_MAX, &var_community_image_size) - ->set_title([] (const BarView &view) { return LOCALIZED(COMMUNITY_POST_IMAGE_SIZE) + " : " + std::to_string(var_community_image_size) + " px"; }) - ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), - (new EmptyView(0, 0, 320, 10)) - }), - // Tab #2 : Playback - (new ScrollView(0, 0, 320, 0)) - ->set_views({ - // Autoplay - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(OFF); }, - (std::function) []() { return LOCALIZED(ONLY_IN_PLAYLIST); }, - (std::function) []() { return LOCALIZED(ON); } - }, var_autoplay_level) - ->set_title([](const SelectorView &) { return LOCALIZED(AUTOPLAY); }) - ->set_on_change([](const SelectorView &view) { - if (var_autoplay_level != view.selected_button) { - var_autoplay_level = view.selected_button; - misc_tasks_request(TASK_CHANGE_BRIGHTNESS); - } - }), - // Forward buffer ratio - (new BarView(0, 0, 320, 40)) - ->set_values_sync(0.1, 1.0, &var_forward_buffer_ratio) - ->set_title([] (const BarView &view) { - char ratio_str[16]; - snprintf(ratio_str, 16, "%.2f", var_forward_buffer_ratio); - return LOCALIZED(FORWARD_BUFFER_RATIO) + " : " + ratio_str; - }) - ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }) - }), - // Tab #3 : Data - (new ScrollView(0, 0, 320, 0)) - ->set_views({ - // History recording - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(DISABLED); }, - (std::function) []() { return LOCALIZED(ENABLED); } - }, var_history_enabled) - ->set_title([](const SelectorView &) { return LOCALIZED(WATCH_HISTORY); }) - ->set_on_change([](const SelectorView &view) { - if (var_history_enabled != view.selected_button) { - var_history_enabled = view.selected_button; - misc_tasks_request(TASK_SAVE_SETTINGS); - } - }), - (new EmptyView(0, 0, 320, 10)), - // Erase history - (new TextView(10, 0, 120, DEFAULT_FONT_INTERVAL + SMALL_MARGIN * 2)) - ->set_text((std::function) [] () { return LOCALIZED(REMOVE_ALL_HISTORY); }) - ->set_x_alignment(TextView::XAlign::CENTER) - ->set_text_offset(0, -2) - ->set_get_background_color([] (const View &view) { - int red = std::min(0xFF, 0xD0 + 0x30 * view.touch_darkness); - int other = 0x30 * (1 - view.touch_darkness); - return 0xFF000000 | other << 8 | other << 16 | red; - }) - ->set_on_view_released([] (View &view) { - popup_view->get_message_view()->set_text_lines(split_string(LOCALIZED(REMOVE_ALL_HISTORY_CONFIRM), '\n'))->update_y_range(0, 30); - popup_view->set_buttons >({ - [] () { return LOCALIZED(CANCEL); }, - [] () { return LOCALIZED(OK); } - }, - [] (OverlayDialogView &, int button_pressed) { - if (button_pressed == 1) { - history_erase_all(); - misc_tasks_request(TASK_SAVE_HISTORY); - - float tabbed_content_y_high = CONTENT_Y_HIGH - main_tab_view->tab_selector_height; - toast_view - ->set_text((std::function) [] () { return LOCALIZED(ALL_HISTORY_REMOVED); }) - ->set_x_alignment(TextView::XAlign::CENTER) - ->set_text_offset(0, -1) - ->set_get_text_color([] () { return (u32) -1; }) - ->update_y_range(tabbed_content_y_high - 20, tabbed_content_y_high - 5) - ->set_get_background_color([] (const View &) { return 0x50000000; }) - ->set_is_visible(true); - toast_frames_left = 120; - } - return true; // close the dialog - }); - popup_view->set_is_visible(true); - var_need_reflesh = true; - }), - (new EmptyView(0, 0, 320, 10)) - }), - // Tab #4 : Update - (new ScrollView(0, 0, 320, 0)) - ->set_views({ - (new TextView(0, 0, 320, DEFAULT_FONT_INTERVAL + SMALL_MARGIN * 2)) - ->set_text((std::function) [] () { return LOCALIZED(UPDATE); }) - ->set_font_size(0.6, DEFAULT_FONT_INTERVAL) - ->set_text_offset(0, -2), - (new TextView(0, 0, 320, DEFAULT_FONT_INTERVAL + SMALL_MARGIN)) - ->set_text((std::function) [] () -> std::string { - if (update_state == UpdateState::CHECKING_UPDATES) return LOCALIZED(CHECKING_FOR_UPDATES); - if (update_state == UpdateState::FAILED_CHECKING) return LOCALIZED(FAILED_CHECKING_UPDATES) + " : " + update_error_message; - if (update_state == UpdateState::UP_TO_DATE) return LOCALIZED(APP_UP_TO_DATE); - if (update_state == UpdateState::UPDATES_AVAILABLE) return LOCALIZED(UPDATES_AVAILABLE) + " : " + next_version_str; - if (update_state == UpdateState::INSTALLING) return install_progress_str; - if (update_state == UpdateState::FAILED_INSTALLING) return LOCALIZED(UPDATE_FAIL) + " : " + update_error_message; - if (update_state == UpdateState::SUCCEEDED_INSTALLING) return LOCALIZED(UPDATE_SUCCESS); - return ""; - }), - (new EmptyView(0, 0, 320, SMALL_MARGIN)), - (update_progress_bar_view = (new ProgressBarView(10, 0, 300, 5))) - ->set_get_color([] () { return DEF_DRAW_BLUE; }) - ->set_is_visible(false), - (new EmptyView(0, 0, 320, SMALL_MARGIN)), - (new TextView(10, 0, 100, DEFAULT_FONT_INTERVAL + SMALL_MARGIN * 2)) - ->set_text((std::function) [] () -> std::string { - if (update_state == UpdateState::FAILED_CHECKING || update_state == UpdateState::UP_TO_DATE) return LOCALIZED(RETRY); - if (update_state == UpdateState::UPDATES_AVAILABLE) return LOCALIZED(UPDATE); - if (update_state == UpdateState::FAILED_INSTALLING) return LOCALIZED(RETRY); - return ""; - }) - ->set_x_alignment(TextView::XAlign::CENTER) - ->set_text_offset(0, -1) - ->set_on_view_released([] (const View &) { - if (update_state == UpdateState::FAILED_CHECKING || update_state == UpdateState::UP_TO_DATE) { - update_state = UpdateState::CHECKING_UPDATES; - var_need_reflesh = true; - } - if (update_state == UpdateState::UPDATES_AVAILABLE || update_state == UpdateState::FAILED_INSTALLING) { - std::vector confirm_lines; - if (is_3dsx) confirm_lines = truncate_str(std::regex_replace(LOCALIZED(OVERWRITE_3DSX_CONFIRM), std::regex("%0"), path_3dsx), DIALOG_WIDTH, 3, 0.5, 0.5); - else confirm_lines = {LOCALIZED(INSTALL_CIA_CONFIRM)}; - - popup_view->get_message_view()->set_text_lines(confirm_lines)->update_y_range(0, 45); - popup_view->set_buttons >({ - [] () { return LOCALIZED(CANCEL); }, - [] () { return LOCALIZED(OK); } - }, - [] (OverlayDialogView &, int button_pressed) { - if (button_pressed == 1) update_state = UpdateState::INSTALLING; - return true; // close the dialog - }); - popup_view->set_is_visible(true); - var_need_reflesh = true; - } - }) - ->set_get_background_color([] (const View &view) -> u32 { - if (update_state == UpdateState::FAILED_CHECKING || update_state == UpdateState::UPDATES_AVAILABLE || update_state == UpdateState::UP_TO_DATE) { - int blue = std::min(0xFF, 0xB0 + 0x30 * view.touch_darkness); - int other = 0x50 + 0x20 * (1 - view.touch_darkness); - return 0xFF000000 | blue << 16 | other << 8 | other; - } - return DEFAULT_BACK_COLOR; - }) - }), - // Tab #5 : Advanced - (new ScrollView(0, 0, 320, 0)) - ->set_views({ - // Eco mode - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(OFF); }, - (std::function) []() { return LOCALIZED(ON); } - }, var_eco_mode) - ->set_title([](const SelectorView &) { return LOCALIZED(ECO_MODE); }) - ->set_on_change([](const SelectorView &view) { - if (var_eco_mode != view.selected_button) { - var_eco_mode = view.selected_button; - misc_tasks_request(TASK_SAVE_SETTINGS); - } - }), - // Use linear filter - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(OFF); }, - (std::function) []() { return LOCALIZED(ON); } - }, var_video_linear_filter) - ->set_title([](const SelectorView &) { return LOCALIZED(LINEAR_FILTER); }) - ->set_on_change([](const SelectorView &view) { - if (var_video_linear_filter != view.selected_button) { - var_video_linear_filter = view.selected_button; - video_set_linear_filter_enabled(var_video_linear_filter); - misc_tasks_request(TASK_SAVE_SETTINGS); - } - }), - (new EmptyView(0, 0, 320, 10)), - // Debug info in the control tab - (new SelectorView(0, 0, 320, 35)) - ->set_texts({ - (std::function) []() { return LOCALIZED(OFF); }, - (std::function) []() { return LOCALIZED(ON); } - }, var_video_show_debug_info) - ->set_title([](const SelectorView &view) { return LOCALIZED(VIDEO_SHOW_DEBUG_INFO); }) - ->set_on_change([](const SelectorView &view) { - if (var_video_show_debug_info != view.selected_button) { - var_video_show_debug_info = view.selected_button; - video_set_show_debug_info(var_video_show_debug_info); - misc_tasks_request(TASK_SAVE_SETTINGS); - } - }), - (new EmptyView(0, 0, 320, 10)) - }) - }, 0) - ->set_tab_texts >({ - [] () { return LOCALIZED(SETTINGS_DISPLAY_UI); }, - [] () { return LOCALIZED(PLAYBACK); }, - [] () { return LOCALIZED(SETTINGS_DATA); }, - [] () { return LOCALIZED(UPDATE); }, - [] () { return LOCALIZED(SETTINGS_ADVANCED); } - }); - main_view = (new VerticalListView(0, 0, 320)) - ->set_views({ - // 'Settings' - (new TextView(0, 0, 320, MIDDLE_FONT_INTERVAL)) - ->set_text((std::function) [] () { return LOCALIZED(SETTINGS); }) - ->set_font_size(MIDDLE_FONT_SIZE, MIDDLE_FONT_INTERVAL) - ->set_get_background_color([] (const View &) { return DEFAULT_BACK_COLOR; }), - // --------------------- - (new RuleView(0, 0, 320, SMALL_MARGIN * 2)) - ->set_get_background_color([] (const View &) { return DEFAULT_BACK_COLOR; }), - main_tab_view - }) - ->set_draw_order({2, 1, 0}); - - - is_3dsx = envIsHomebrew(); - if (is_3dsx) { - const char *arglist = envGetSystemArgList(); - int argc = *(u32 *) arglist; - if (argc) { - arglist += 4; - path_3dsx = arglist; - if (path_3dsx.substr(0, 6) == "sdmc:/") path_3dsx = path_3dsx.substr(5, path_3dsx.size() - 5); - } - } - - update_worker_thread = threadCreate(update_worker_thread_func, (void*)(""), DEF_STACKSIZE, DEF_THREAD_PRIORITY_LOW, 1, false); - - Sem_resume(""); - already_init = true; -} -void Sem_exit(void) { - already_init = false; - thread_suspend = false; - exiting = true; - - save_settings(); - - u64 time_out = 10000000000; - logger.info(DEF_MENU_EXIT_STR, "threadJoin()...", threadJoin(update_worker_thread, time_out)); - threadFree(update_worker_thread); - - main_view->recursive_delete_subviews(); - delete main_view; - main_view = NULL; - main_tab_view = NULL; - - logger.info("settings/exit", "Exited."); -} -void Sem_suspend(void) { - thread_suspend = true; -} -void Sem_resume(std::string arg) { - overlay_menu_on_resume(); - thread_suspend = false; - var_need_reflesh = true; -} - - -void Sem_draw(void) -{ - Hid_info key; - Util_hid_query_key_state(&key); - - thumbnail_set_active_scene(SceneType::SETTINGS); - - bool video_playing_bar_show = video_is_playing(); - CONTENT_Y_HIGH = 240; - if (video_playing_bar_show) CONTENT_Y_HIGH -= VIDEO_PLAYING_BAR_HEIGHT; - main_tab_view->update_y_range(0, CONTENT_Y_HIGH - TOP_HEIGHT); - - if(var_need_reflesh || !var_eco_mode) - { - var_need_reflesh = false; - Draw_frame_ready(); - video_draw_top_screen(); - - Draw_screen_ready(1, DEFAULT_BACK_COLOR); - - resource_lock.lock(); - main_view->draw(); - popup_view->draw(); - toast_view->draw(); - resource_lock.unlock(); - - if (video_playing_bar_show) video_draw_playing_bar(); - draw_overlay_menu(CONTENT_Y_HIGH - main_tab_view->tab_selector_height - OVERLAY_MENU_ICON_SIZE); - - if(Util_expl_query_show_flag()) - Util_expl_draw(); - - if(Util_err_query_error_show_flag()) - Util_err_draw(); - - Draw_touch_pos(); - - Draw_apply_draw(); - } - else - gspWaitForVBlank(); - - if (--toast_frames_left <= 0) toast_view->set_is_visible(false); - - if (Util_err_query_error_show_flag()) { - Util_err_main(key); - } else if(Util_expl_query_show_flag()) { - Util_expl_main(key); - } else { - update_overlay_menu(&key); - - // toast_view is never 'updated' - resource_lock.lock(); - if (popup_view->is_visible) popup_view->update(key); - else main_view->update(key); - resource_lock.unlock(); - - if (video_playing_bar_show) video_update_playing_bar(key); - - if (key.p_b) global_intent.next_scene = SceneType::BACK; - } -} +#include "headers.hpp" +#include +#include + +#include "data_io/settings.hpp" +#include "data_io/history.hpp" +#include "util/misc_tasks.hpp" +#include "scenes/setting_menu.hpp" +#include "scenes/video_player.hpp" +#include "ui/overlay.hpp" +#include "ui/ui.hpp" +#include "youtube_parser/parser.hpp" +#include "network_decoder/thumbnail_loader.hpp" +#include "network_decoder/network_io.hpp" +#include "rapidjson_wrapper.hpp" + +namespace Settings { + bool thread_suspend = false; + bool already_init = false; + bool exiting = false; + + bool is_3dsx = false; + std::string path_3dsx; + + TextView *toast_view; + int toast_frames_left = 0; + + OverlayDialogView *popup_view; + VerticalListView *main_view; + TabView *main_tab_view; + + ProgressBarView *update_progress_bar_view; + + int CONTENT_Y_HIGH = 240; + constexpr int TOP_HEIGHT = MIDDLE_FONT_INTERVAL + SMALL_MARGIN * 2; + + constexpr int DIALOG_WIDTH = 240; + + // used for updating of the app + enum class UpdateState { + CHECKING_UPDATES, + FAILED_CHECKING, + UP_TO_DATE, + UPDATES_AVAILABLE, + INSTALLING, + FAILED_INSTALLING, + SUCCEEDED_INSTALLING + }; + UpdateState update_state = UpdateState::CHECKING_UPDATES; + + static std::string update_error_message; + + static std::string update_url_cia; + static std::string update_url_3dsx; + static std::string next_version_str; + static Mutex resource_lock; + static std::string install_progress_str; + + static Thread update_worker_thread; + + Thread settings_misc_thread; +}; +using namespace Settings; + + + +std::string install_update(NetworkSessionList &session_list) { + std::string new_error_message = ""; + auto url = is_3dsx ? update_url_3dsx : update_url_cia; + // auto url = update_url_cia; + + resource_lock.lock(); + install_progress_str = LOCALIZED(ACCESSING); + resource_lock.unlock(); + update_progress_bar_view->set_progress(0); + update_progress_bar_view->set_is_visible(true); + + bool first = true; + auto result = session_list.perform(HttpRequest::GET(url, {}).with_progress_func([&] (u64 now, u64 total) { + if (total < 10000) return; // ignore header(?) + if (first) { + first = false; + resource_lock.lock(); + install_progress_str = LOCALIZED(DOWNLOADING); + resource_lock.unlock(); + } + update_progress_bar_view->set_progress((double) now / total); + })); + + if (result.fail) return "curl deep fail : " + result.error; + if (result.status_code != 200) return "http returned " + std::to_string(result.status_code); + + resource_lock.lock(); + install_progress_str = LOCALIZED(INSTALLING); + resource_lock.unlock(); + update_progress_bar_view->set_progress(1.0); + + Result libctru_result; + if (is_3dsx) { + char *slash_ptr = strrchr(path_3dsx.c_str(), '/'); + if (!slash_ptr) return "no slash in 3dsx path : " + path_3dsx; + size_t slash_index = slash_ptr - path_3dsx.c_str(); + auto tmp_res = Path(path_3dsx).write_file(result.data.data(), result.data.size()); + if (tmp_res.code != 0) return "Failed to write to .3dsx file : " + tmp_res.string + " " + std::to_string(tmp_res.code); + } else { + Handle am_handle = 0; + if ((libctru_result = AM_StartCiaInstall(MEDIATYPE_SD, &am_handle))) return "AM_StartCiaInstall() returned " + std::to_string(libctru_result); + + update_progress_bar_view->set_progress(0.0); + + const size_t BLOCK_SIZE = 200000; + for (size_t i = 0; i < result.data.size(); ) { + size_t size = std::min(BLOCK_SIZE, result.data.size() - i); + u32 size_written; + libctru_result = FSFILE_Write(am_handle, &size_written, i, result.data.data() + i, size, FS_WRITE_FLUSH); + i += size_written; + if (libctru_result) return "FSFILE_Write() returned " + std::to_string(libctru_result); + update_progress_bar_view->set_progress((double) i / result.data.size()); + } + update_progress_bar_view->set_progress(1.0); + + libctru_result = AM_FinishCiaInstall(am_handle); + if (libctru_result) return "AM_FinishCiaInstall() returned " + std::to_string(libctru_result); + } + return ""; +} + +static void update_worker_thread_func(void *) { + logger.info("updater", "Thread started."); + + static NetworkSessionList session_list; + session_list.init(); + + while (!exiting) { + if (update_state == UpdateState::CHECKING_UPDATES) { + std::string new_error_message; + + bool check_success = false; + auto result = session_list.perform(HttpRequest::GET("https://api.github.com/repos/windows-server-2003/ThirdTube/releases/latest", {})); + if (result.fail) new_error_message = "Failed accessing(deep fail) : " + result.fail; + else if (result.status_code == 200) { + result.data.push_back('\0'); + rapidjson::Document json_root; + std::string error; + RJson result_json = RJson::parse(json_root, (char *) result.data.data(), error); + if (error != "") { + logger.error("updater", "failed to parse json : " + error); + new_error_message = "failed to parse json : " + error; + } else { + update_url_3dsx = update_url_cia; + for (auto item : result_json["assets"].array_items()) { + auto url = item["browser_download_url"].string_value(); + if (url.size() >= 5 && url.substr(url.size() - 5, 5) == ".3dsx") update_url_3dsx = url; + if (url.size() >= 4 && url.substr(url.size() - 4, 4) == ".cia") update_url_cia = url; + } + if (update_url_cia == "") new_error_message = "could not find .cia url"; + if (update_url_3dsx == "") new_error_message = "could not find .3dsx url"; + if (update_url_cia != "" && update_url_3dsx != "") { + // lexicographically compare the sequence of version numbers ([0, 4, 1] if v0.4.1) + auto version_str_to_vector = [] (const std::string &str) { + size_t head = 0; + std::vector res; + while (head < str.size()) { + while (head < str.size() && !isdigit(str[head])) head++; + if (head >= str.size()) break; + int cur = 0; + while (head < str.size() && isdigit(str[head])) cur = cur * 10 + str[head++] - '0'; + res.push_back(cur); + } + return res; + }; + auto new_version_seq = version_str_to_vector(result_json["tag_name"].string_value()); + auto cur_version_seq = version_str_to_vector(DEF_CURRENT_APP_VER); + bool update_available = cur_version_seq < new_version_seq; + if (update_available) update_state = UpdateState::UPDATES_AVAILABLE, next_version_str = result_json["tag_name"].string_value(); + else update_state = UpdateState::UP_TO_DATE; + check_success = true; + } + } + } else new_error_message = "http returned " + std::to_string(result.status_code); + if (!check_success) update_state = UpdateState::FAILED_CHECKING; + if (new_error_message != "") { + resource_lock.lock(); + update_error_message = new_error_message; + resource_lock.unlock(); + } + } + if (update_state == UpdateState::INSTALLING) { + std::string error = install_update(session_list); + if (error == "") update_state = UpdateState::SUCCEEDED_INSTALLING; + else { + resource_lock.lock(); + update_error_message = error; + resource_lock.unlock(); + update_state = UpdateState::FAILED_INSTALLING; + } + } + usleep(100000); + } + + logger.info("updater", "Thread exit."); + threadExit(0); +} + + + +void Sem_init(void) { + logger.info("settings/init", "Initializing..."); + Result_with_string result; + + load_settings(); + load_string_resources(var_lang); + + popup_view = new OverlayDialogView(0, 0, 320, 240); + popup_view->set_is_visible(false); + toast_view = new TextView((320 - 150) / 2, 190, 150, DEFAULT_FONT_INTERVAL + SMALL_MARGIN); + toast_view->set_is_visible(false); + + main_tab_view = (new TabView(0, 0, 320, CONTENT_Y_HIGH - TOP_HEIGHT)) + ->set_stretch_subview(true) + ->set_views({ + // Tab #1 : UI/Display + (new ScrollView(0, 0, 320, 0)) + ->set_views({ + // UI language + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(LANG_EN); }, + (std::function) []() { return LOCALIZED(LANG_JA); }, + (std::function) []() { return LOCALIZED(LANG_FR); } + }, var_lang == "ja" ? 1 : 0) + ->set_title([](const SelectorView &) { return LOCALIZED(UI_LANGUAGE); }) + ->set_on_change([](const SelectorView &view) { + auto next_lang = std::vector{"en", "ja", "fr"}[view.selected_button]; + if (var_lang != next_lang) { + var_lang = next_lang; + misc_tasks_request(TASK_RELOAD_STRING_RESOURCE); + misc_tasks_request(TASK_SAVE_SETTINGS); + } + }), + // Content language + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(LANG_EN); }, + (std::function) []() { return LOCALIZED(LANG_JA); }, + (std::function) []() { return LOCALIZED(LANG_FR); } + }, var_lang_content == "ja" ? 1 : 0) + ->set_title([](const SelectorView &) { return LOCALIZED(CONTENT_LANGUAGE); }) + ->set_on_change([](const SelectorView &view) { + auto next_lang = std::vector{"en", "ja", "fr"}[view.selected_button]; + if (var_lang_content != next_lang) { + var_lang_content = next_lang; + misc_tasks_request(TASK_SAVE_SETTINGS); + youtube_change_content_language(var_lang_content); + } + }), + // LCD Brightness + (new BarView(0, 0, 320, 40)) + ->set_values_sync(15, 163, &var_lcd_brightness) + ->set_title([] (const BarView &view) { return LOCALIZED(LCD_BRIGHTNESS); }) + ->set_while_holding([] (const BarView &view) { misc_tasks_request(TASK_CHANGE_BRIGHTNESS); }) + ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), + // Time to turn off LCD + (new BarView(0, 0, 320, 40)) + ->set_values(10, 310, var_time_to_turn_off_lcd <= 309 ? var_time_to_turn_off_lcd : 310) + ->set_title([] (const BarView &view) { return LOCALIZED(TIME_TO_TURN_OFF_LCD) + " : " + + (view.get_value() <= 309 ? std::to_string((int) view.get_value()) + " " + LOCALIZED(SECONDS) : LOCALIZED(NEVER_TURN_OFF)); }) + ->set_on_release([] (const BarView &view) { + var_time_to_turn_off_lcd = view.get_value() <= 309 ? view.get_value() : 1000000000; + misc_tasks_request(TASK_SAVE_SETTINGS); + }), + // full screen mode + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(OFF); }, + (std::function) []() { return LOCALIZED(ON); } + }, var_full_screen_mode) + ->set_title([](const SelectorView &) { return LOCALIZED(FULL_SCREEN_MODE); }) + ->set_on_change([](const SelectorView &view) { + if (var_full_screen_mode != view.selected_button) { + var_full_screen_mode = view.selected_button; + misc_tasks_request(TASK_SAVE_SETTINGS); + } + }), + // Dark theme (plus flash) + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(OFF); }, + (std::function) []() { return LOCALIZED(ON); }, + (std::function) []() { return LOCALIZED(FLASH); } + }, var_flash_mode ? 2 : var_night_mode) + ->set_title([](const SelectorView &) { return LOCALIZED(DARK_THEME); }) + ->set_on_change([](const SelectorView &view) { + if (var_flash_mode != (view.selected_button == 2)) { + var_flash_mode = (view.selected_button == 2); + misc_tasks_request(TASK_SAVE_SETTINGS); + } + if (!var_flash_mode && var_night_mode != view.selected_button) { + var_night_mode = view.selected_button; + misc_tasks_request(TASK_SAVE_SETTINGS); + } + }), + // Scroll speed 0 + (new BarView(0, 0, 320, 35)) + ->set_values_sync(DPAD_SCROLL_SPEED_MIN, DPAD_SCROLL_SPEED_MAX, &var_dpad_scroll_speed0) + ->set_title([] (const BarView &view) { return LOCALIZED(SCROLL_SPEED0) + " : " + double2str(var_dpad_scroll_speed0, 1); }) + ->set_while_holding([] (const BarView &view) { + var_dpad_scroll_speed1 = std::max(var_dpad_scroll_speed1, var_dpad_scroll_speed0); + }) + ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), + // Scroll speed 1 + (new BarView(0, 0, 320, 35)) + ->set_values_sync(DPAD_SCROLL_SPEED_MIN, DPAD_SCROLL_SPEED_MAX, &var_dpad_scroll_speed1) + ->set_title([] (const BarView &view) { return LOCALIZED(SCROLL_SPEED1) + " : " + double2str(var_dpad_scroll_speed1, 1); }) + ->set_while_holding([] (const BarView &view) { + var_dpad_scroll_speed0 = std::min(var_dpad_scroll_speed0, var_dpad_scroll_speed1); + }) + ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), + // Scroll speed change threashold + (new BarView(0, 0, 320, 40)) + ->set_values_sync(DPAD_SCROLL_THREASHOLD_MIN, DPAD_SCROLL_THREASHOLD_MAX, &var_dpad_scroll_speed1_threashold) + ->set_title([] (const BarView &view) { return LOCALIZED(SCROLL_SPEED_THREASHOLD) + " : " + double2str(var_dpad_scroll_speed1_threashold, 1); }) + ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), + // Size of images in community posts + (new BarView(0, 0, 320, 40)) + ->set_values_sync(COMMUNITY_IMAGE_SIZE_MIN, COMMUNITY_IMAGE_SIZE_MAX, &var_community_image_size) + ->set_title([] (const BarView &view) { return LOCALIZED(COMMUNITY_POST_IMAGE_SIZE) + " : " + std::to_string(var_community_image_size) + " px"; }) + ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }), + (new EmptyView(0, 0, 320, 10)) + }), + // Tab #2 : Playback + (new ScrollView(0, 0, 320, 0)) + ->set_views({ + // Autoplay + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(OFF); }, + (std::function) []() { return LOCALIZED(ONLY_IN_PLAYLIST); }, + (std::function) []() { return LOCALIZED(ON); } + }, var_autoplay_level) + ->set_title([](const SelectorView &) { return LOCALIZED(AUTOPLAY); }) + ->set_on_change([](const SelectorView &view) { + if (var_autoplay_level != view.selected_button) { + var_autoplay_level = view.selected_button; + misc_tasks_request(TASK_CHANGE_BRIGHTNESS); + } + }), + // Forward buffer ratio + (new BarView(0, 0, 320, 40)) + ->set_values_sync(0.1, 1.0, &var_forward_buffer_ratio) + ->set_title([] (const BarView &view) { + char ratio_str[16]; + snprintf(ratio_str, 16, "%.2f", var_forward_buffer_ratio); + return LOCALIZED(FORWARD_BUFFER_RATIO) + " : " + ratio_str; + }) + ->set_on_release([] (const BarView &view) { misc_tasks_request(TASK_SAVE_SETTINGS); }) + }), + // Tab #3 : Data + (new ScrollView(0, 0, 320, 0)) + ->set_views({ + // History recording + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(DISABLED); }, + (std::function) []() { return LOCALIZED(ENABLED); } + }, var_history_enabled) + ->set_title([](const SelectorView &) { return LOCALIZED(WATCH_HISTORY); }) + ->set_on_change([](const SelectorView &view) { + if (var_history_enabled != view.selected_button) { + var_history_enabled = view.selected_button; + misc_tasks_request(TASK_SAVE_SETTINGS); + } + }), + (new EmptyView(0, 0, 320, 10)), + // Erase history + (new TextView(10, 0, 120, DEFAULT_FONT_INTERVAL + SMALL_MARGIN * 2)) + ->set_text((std::function) [] () { return LOCALIZED(REMOVE_ALL_HISTORY); }) + ->set_x_alignment(TextView::XAlign::CENTER) + ->set_text_offset(0, -2) + ->set_get_background_color([] (const View &view) { + int red = std::min(0xFF, 0xD0 + 0x30 * view.touch_darkness); + int other = 0x30 * (1 - view.touch_darkness); + return 0xFF000000 | other << 8 | other << 16 | red; + }) + ->set_on_view_released([] (View &view) { + popup_view->get_message_view()->set_text_lines(split_string(LOCALIZED(REMOVE_ALL_HISTORY_CONFIRM), '\n'))->update_y_range(0, 30); + popup_view->set_buttons >({ + [] () { return LOCALIZED(CANCEL); }, + [] () { return LOCALIZED(OK); } + }, + [] (OverlayDialogView &, int button_pressed) { + if (button_pressed == 1) { + history_erase_all(); + misc_tasks_request(TASK_SAVE_HISTORY); + + float tabbed_content_y_high = CONTENT_Y_HIGH - main_tab_view->tab_selector_height; + toast_view + ->set_text((std::function) [] () { return LOCALIZED(ALL_HISTORY_REMOVED); }) + ->set_x_alignment(TextView::XAlign::CENTER) + ->set_text_offset(0, -1) + ->set_get_text_color([] () { return (u32) -1; }) + ->update_y_range(tabbed_content_y_high - 20, tabbed_content_y_high - 5) + ->set_get_background_color([] (const View &) { return 0x50000000; }) + ->set_is_visible(true); + toast_frames_left = 120; + } + return true; // close the dialog + }); + popup_view->set_is_visible(true); + var_need_reflesh = true; + }), + (new EmptyView(0, 0, 320, 10)) + }), + // Tab #4 : Update + (new ScrollView(0, 0, 320, 0)) + ->set_views({ + (new TextView(0, 0, 320, DEFAULT_FONT_INTERVAL + SMALL_MARGIN * 2)) + ->set_text((std::function) [] () { return LOCALIZED(UPDATE); }) + ->set_font_size(0.6, DEFAULT_FONT_INTERVAL) + ->set_text_offset(0, -2), + (new TextView(0, 0, 320, DEFAULT_FONT_INTERVAL + SMALL_MARGIN)) + ->set_text((std::function) [] () -> std::string { + if (update_state == UpdateState::CHECKING_UPDATES) return LOCALIZED(CHECKING_FOR_UPDATES); + if (update_state == UpdateState::FAILED_CHECKING) return LOCALIZED(FAILED_CHECKING_UPDATES) + " : " + update_error_message; + if (update_state == UpdateState::UP_TO_DATE) return LOCALIZED(APP_UP_TO_DATE); + if (update_state == UpdateState::UPDATES_AVAILABLE) return LOCALIZED(UPDATES_AVAILABLE) + " : " + next_version_str; + if (update_state == UpdateState::INSTALLING) return install_progress_str; + if (update_state == UpdateState::FAILED_INSTALLING) return LOCALIZED(UPDATE_FAIL) + " : " + update_error_message; + if (update_state == UpdateState::SUCCEEDED_INSTALLING) return LOCALIZED(UPDATE_SUCCESS); + return ""; + }), + (new EmptyView(0, 0, 320, SMALL_MARGIN)), + (update_progress_bar_view = (new ProgressBarView(10, 0, 300, 5))) + ->set_get_color([] () { return DEF_DRAW_BLUE; }) + ->set_is_visible(false), + (new EmptyView(0, 0, 320, SMALL_MARGIN)), + (new TextView(10, 0, 100, DEFAULT_FONT_INTERVAL + SMALL_MARGIN * 2)) + ->set_text((std::function) [] () -> std::string { + if (update_state == UpdateState::FAILED_CHECKING || update_state == UpdateState::UP_TO_DATE) return LOCALIZED(RETRY); + if (update_state == UpdateState::UPDATES_AVAILABLE) return LOCALIZED(UPDATE); + if (update_state == UpdateState::FAILED_INSTALLING) return LOCALIZED(RETRY); + return ""; + }) + ->set_x_alignment(TextView::XAlign::CENTER) + ->set_text_offset(0, -1) + ->set_on_view_released([] (const View &) { + if (update_state == UpdateState::FAILED_CHECKING || update_state == UpdateState::UP_TO_DATE) { + update_state = UpdateState::CHECKING_UPDATES; + var_need_reflesh = true; + } + if (update_state == UpdateState::UPDATES_AVAILABLE || update_state == UpdateState::FAILED_INSTALLING) { + std::vector confirm_lines; + if (is_3dsx) confirm_lines = truncate_str(std::regex_replace(LOCALIZED(OVERWRITE_3DSX_CONFIRM), std::regex("%0"), path_3dsx), DIALOG_WIDTH, 3, 0.5, 0.5); + else confirm_lines = {LOCALIZED(INSTALL_CIA_CONFIRM)}; + + popup_view->get_message_view()->set_text_lines(confirm_lines)->update_y_range(0, 45); + popup_view->set_buttons >({ + [] () { return LOCALIZED(CANCEL); }, + [] () { return LOCALIZED(OK); } + }, + [] (OverlayDialogView &, int button_pressed) { + if (button_pressed == 1) update_state = UpdateState::INSTALLING; + return true; // close the dialog + }); + popup_view->set_is_visible(true); + var_need_reflesh = true; + } + }) + ->set_get_background_color([] (const View &view) -> u32 { + if (update_state == UpdateState::FAILED_CHECKING || update_state == UpdateState::UPDATES_AVAILABLE || update_state == UpdateState::UP_TO_DATE) { + int blue = std::min(0xFF, 0xB0 + 0x30 * view.touch_darkness); + int other = 0x50 + 0x20 * (1 - view.touch_darkness); + return 0xFF000000 | blue << 16 | other << 8 | other; + } + return DEFAULT_BACK_COLOR; + }) + }), + // Tab #5 : Advanced + (new ScrollView(0, 0, 320, 0)) + ->set_views({ + // Eco mode + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(OFF); }, + (std::function) []() { return LOCALIZED(ON); } + }, var_eco_mode) + ->set_title([](const SelectorView &) { return LOCALIZED(ECO_MODE); }) + ->set_on_change([](const SelectorView &view) { + if (var_eco_mode != view.selected_button) { + var_eco_mode = view.selected_button; + misc_tasks_request(TASK_SAVE_SETTINGS); + } + }), + // Use linear filter + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(OFF); }, + (std::function) []() { return LOCALIZED(ON); } + }, var_video_linear_filter) + ->set_title([](const SelectorView &) { return LOCALIZED(LINEAR_FILTER); }) + ->set_on_change([](const SelectorView &view) { + if (var_video_linear_filter != view.selected_button) { + var_video_linear_filter = view.selected_button; + video_set_linear_filter_enabled(var_video_linear_filter); + misc_tasks_request(TASK_SAVE_SETTINGS); + } + }), + (new EmptyView(0, 0, 320, 10)), + // Debug info in the control tab + (new SelectorView(0, 0, 320, 35)) + ->set_texts({ + (std::function) []() { return LOCALIZED(OFF); }, + (std::function) []() { return LOCALIZED(ON); } + }, var_video_show_debug_info) + ->set_title([](const SelectorView &view) { return LOCALIZED(VIDEO_SHOW_DEBUG_INFO); }) + ->set_on_change([](const SelectorView &view) { + if (var_video_show_debug_info != view.selected_button) { + var_video_show_debug_info = view.selected_button; + video_set_show_debug_info(var_video_show_debug_info); + misc_tasks_request(TASK_SAVE_SETTINGS); + } + }), + (new EmptyView(0, 0, 320, 10)) + }) + }, 0) + ->set_tab_texts >({ + [] () { return LOCALIZED(SETTINGS_DISPLAY_UI); }, + [] () { return LOCALIZED(PLAYBACK); }, + [] () { return LOCALIZED(SETTINGS_DATA); }, + [] () { return LOCALIZED(UPDATE); }, + [] () { return LOCALIZED(SETTINGS_ADVANCED); } + }); + main_view = (new VerticalListView(0, 0, 320)) + ->set_views({ + // 'Settings' + (new TextView(0, 0, 320, MIDDLE_FONT_INTERVAL)) + ->set_text((std::function) [] () { return LOCALIZED(SETTINGS); }) + ->set_font_size(MIDDLE_FONT_SIZE, MIDDLE_FONT_INTERVAL) + ->set_get_background_color([] (const View &) { return DEFAULT_BACK_COLOR; }), + // --------------------- + (new RuleView(0, 0, 320, SMALL_MARGIN * 2)) + ->set_get_background_color([] (const View &) { return DEFAULT_BACK_COLOR; }), + main_tab_view + }) + ->set_draw_order({2, 1, 0}); + + + is_3dsx = envIsHomebrew(); + if (is_3dsx) { + const char *arglist = envGetSystemArgList(); + int argc = *(u32 *) arglist; + if (argc) { + arglist += 4; + path_3dsx = arglist; + if (path_3dsx.substr(0, 6) == "sdmc:/") path_3dsx = path_3dsx.substr(5, path_3dsx.size() - 5); + } + } + + update_worker_thread = threadCreate(update_worker_thread_func, (void*)(""), DEF_STACKSIZE, DEF_THREAD_PRIORITY_LOW, 1, false); + + Sem_resume(""); + already_init = true; +} +void Sem_exit(void) { + already_init = false; + thread_suspend = false; + exiting = true; + + save_settings(); + + u64 time_out = 10000000000; + logger.info(DEF_MENU_EXIT_STR, "threadJoin()...", threadJoin(update_worker_thread, time_out)); + threadFree(update_worker_thread); + + main_view->recursive_delete_subviews(); + delete main_view; + main_view = NULL; + main_tab_view = NULL; + + logger.info("settings/exit", "Exited."); +} +void Sem_suspend(void) { + thread_suspend = true; +} +void Sem_resume(std::string arg) { + overlay_menu_on_resume(); + thread_suspend = false; + var_need_reflesh = true; +} + + +void Sem_draw(void) +{ + Hid_info key; + Util_hid_query_key_state(&key); + + thumbnail_set_active_scene(SceneType::SETTINGS); + + bool video_playing_bar_show = video_is_playing(); + CONTENT_Y_HIGH = 240; + if (video_playing_bar_show) CONTENT_Y_HIGH -= VIDEO_PLAYING_BAR_HEIGHT; + main_tab_view->update_y_range(0, CONTENT_Y_HIGH - TOP_HEIGHT); + + if(var_need_reflesh || !var_eco_mode) + { + var_need_reflesh = false; + Draw_frame_ready(); + video_draw_top_screen(); + + Draw_screen_ready(1, DEFAULT_BACK_COLOR); + + resource_lock.lock(); + main_view->draw(); + popup_view->draw(); + toast_view->draw(); + resource_lock.unlock(); + + if (video_playing_bar_show) video_draw_playing_bar(); + draw_overlay_menu(CONTENT_Y_HIGH - main_tab_view->tab_selector_height - OVERLAY_MENU_ICON_SIZE); + + if(Util_expl_query_show_flag()) + Util_expl_draw(); + + if(Util_err_query_error_show_flag()) + Util_err_draw(); + + Draw_touch_pos(); + + Draw_apply_draw(); + } + else + gspWaitForVBlank(); + + if (--toast_frames_left <= 0) toast_view->set_is_visible(false); + + if (Util_err_query_error_show_flag()) { + Util_err_main(key); + } else if(Util_expl_query_show_flag()) { + Util_expl_main(key); + } else { + update_overlay_menu(&key); + + // toast_view is never 'updated' + resource_lock.lock(); + if (popup_view->is_visible) popup_view->update(key); + else main_view->update(key); + resource_lock.unlock(); + + if (video_playing_bar_show) video_update_playing_bar(key); + + if (key.p_b) global_intent.next_scene = SceneType::BACK; + } +} From 664eafc9165e122697f34e6e5add49b23c7327cf Mon Sep 17 00:00:00 2001 From: cooolgamer <64099608+cooolgamer@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:29:08 +0100 Subject: [PATCH 2/6] added french in settings --- source/data_io/settings.cpp | 188 ++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/source/data_io/settings.cpp b/source/data_io/settings.cpp index d156ee38..067e3f98 100644 --- a/source/data_io/settings.cpp +++ b/source/data_io/settings.cpp @@ -1,94 +1,94 @@ -#include "headers.hpp" -#include "settings.hpp" -#include "youtube_parser/parser.hpp" -#include "scenes/video_player.hpp" - -#define SETTINGS_FILE_PATH (DEF_MAIN_DIR + "settings.txt") - -void load_settings() { - char buf[0x1001] = { 0 }; - u32 read_size; - Result_with_string result = Path(SETTINGS_FILE_PATH).read_file((u8 *) buf, 0x1000, read_size); - logger.info(DEF_SEM_INIT_STR , "read_file()..." + result.string + result.error_description, result.code); - auto settings = parse_xml_like_text(buf); - - auto load_int = [&] (std::string key, int default_value) { - if (!settings.count(key)) return default_value; - char *end; - long res = strtol(settings[key].c_str(), &end, 10); - if (*end) return default_value; - res = std::min(res, std::numeric_limits::max()); - res = std::max(res, std::numeric_limits::min()); - return (int) res; - }; - auto load_double = [&] (std::string key, double default_value) { - if (!settings.count(key)) return default_value; - char *end; - double res = strtod(settings[key].c_str(), &end); - if (*end) return default_value; - return res; - }; - auto load_string = [&] (std::string key, std::string default_value) { - return settings.count(key) ? settings[key] : default_value; - }; - var_lang = load_string("lang_ui", "en"); - if (var_lang != "en" && var_lang != "ja") var_lang = "en"; - var_lang_content = load_string("lang_content", "en"); - if (var_lang_content != "en" && var_lang_content != "ja") var_lang_content = "en"; - var_lcd_brightness = load_int("lcd_brightness", 100); - if (var_lcd_brightness < 15 || var_lcd_brightness > 163) var_lcd_brightness = 100; - var_time_to_turn_off_lcd = load_int("time_to_turn_off_lcd", 150); - if (var_time_to_turn_off_lcd < 10) var_time_to_turn_off_lcd = 150; - var_eco_mode = load_int("eco_mode", 1); - var_full_screen_mode = load_int("full_screen_mode", 0); - var_night_mode = load_int("dark_theme", 0); - var_flash_mode = load_int("dark_theme_flash", 0); - var_community_image_size = std::min(COMMUNITY_IMAGE_SIZE_MAX, std::max(COMMUNITY_IMAGE_SIZE_MIN, load_int("community_image_size", COMMUNITY_IMAGE_SIZE_DEFAULT))); - var_autoplay_level = std::min(2, std::max(0, load_int("autoplay_level", 2))); - var_forward_buffer_ratio = std::max(0.1, std::min(1.0, load_double("forward_buffer_ratio", 0.8))); - var_history_enabled = load_int("history_enabled", 1); - var_video_show_debug_info = load_int("video_show_debug_info", 0); - var_video_linear_filter = load_int("linear_filter", 1); - var_dpad_scroll_speed0 = std::max(1.0, std::min(12.0, load_double("dpad_scroll_speed0", 6.0))); - var_dpad_scroll_speed1 = std::max(var_dpad_scroll_speed0, std::min(12.0, load_double("dpad_scroll_speed1", 9.0))); - var_dpad_scroll_speed1_threashold = std::max(0.3, std::min(5.0, load_double("dpad_scroll_speed1_threashold", 2.0))); - - Util_cset_set_wifi_state(true); - Util_cset_set_screen_brightness(true, true, var_lcd_brightness); - youtube_change_content_language(var_lang_content); - video_set_linear_filter_enabled(var_video_linear_filter); - video_set_show_debug_info(var_video_show_debug_info); -} -void save_settings() { - std::string data; - auto add_str = [&] (const std::string &key, const std::string &val) { - data += "<" + key + ">" + val + "\n"; - }; - auto add_int = [&] (const std::string &key, int val) { - data += "<" + key + ">" + std::to_string(val) + "\n"; - }; - auto add_double = [&] (const std::string &key, double val) { - data += "<" + key + ">" + std::to_string(val) + "\n"; - }; - - add_str("lang_ui", var_lang); - add_str("lang_content", var_lang_content); - add_int("lcd_brightness", var_lcd_brightness); - add_int("time_to_turn_off_lcd", var_time_to_turn_off_lcd); - add_int("eco_mode", var_eco_mode); - add_int("full_screen_mode", var_full_screen_mode); - add_int("dark_theme", var_night_mode); - add_int("dark_theme_flash", var_flash_mode); - add_int("community_image_size", var_community_image_size); - add_int("autoplay_level", var_autoplay_level); - add_double("forward_buffer_ratio", var_forward_buffer_ratio); - add_int("history_enabled", var_history_enabled); - add_int("video_show_debug_info", var_video_show_debug_info); - add_int("linear_filter", var_video_linear_filter); - add_double("dpad_scroll_speed0", var_dpad_scroll_speed0); - add_double("dpad_scroll_speed1", var_dpad_scroll_speed1); - add_double("dpad_scroll_speed1_threashold", var_dpad_scroll_speed1_threashold); - - Result_with_string result = Path(SETTINGS_FILE_PATH).write_file((u8 *) data.c_str(), data.size()); - logger.info("settings/save", "write_file()..." + result.string + result.error_description, result.code); -} +#include "headers.hpp" +#include "settings.hpp" +#include "youtube_parser/parser.hpp" +#include "scenes/video_player.hpp" + +#define SETTINGS_FILE_PATH (DEF_MAIN_DIR + "settings.txt") + +void load_settings() { + char buf[0x1001] = { 0 }; + u32 read_size; + Result_with_string result = Path(SETTINGS_FILE_PATH).read_file((u8 *) buf, 0x1000, read_size); + logger.info(DEF_SEM_INIT_STR , "read_file()..." + result.string + result.error_description, result.code); + auto settings = parse_xml_like_text(buf); + + auto load_int = [&] (std::string key, int default_value) { + if (!settings.count(key)) return default_value; + char *end; + long res = strtol(settings[key].c_str(), &end, 10); + if (*end) return default_value; + res = std::min(res, std::numeric_limits::max()); + res = std::max(res, std::numeric_limits::min()); + return (int) res; + }; + auto load_double = [&] (std::string key, double default_value) { + if (!settings.count(key)) return default_value; + char *end; + double res = strtod(settings[key].c_str(), &end); + if (*end) return default_value; + return res; + }; + auto load_string = [&] (std::string key, std::string default_value) { + return settings.count(key) ? settings[key] : default_value; + }; + var_lang = load_string("lang_ui", "en"); + if (var_lang != "en" && var_lang != "ja" && var_lang != "fr") var_lang = "en"; + var_lang_content = load_string("lang_content", "en"); + if (var_lang_content != "en" && var_lang_content != "ja" && var_lang_content != "fr") var_lang_content = "en"; + var_lcd_brightness = load_int("lcd_brightness", 100); + if (var_lcd_brightness < 15 || var_lcd_brightness > 163) var_lcd_brightness = 100; + var_time_to_turn_off_lcd = load_int("time_to_turn_off_lcd", 150); + if (var_time_to_turn_off_lcd < 10) var_time_to_turn_off_lcd = 150; + var_eco_mode = load_int("eco_mode", 1); + var_full_screen_mode = load_int("full_screen_mode", 0); + var_night_mode = load_int("dark_theme", 0); + var_flash_mode = load_int("dark_theme_flash", 0); + var_community_image_size = std::min(COMMUNITY_IMAGE_SIZE_MAX, std::max(COMMUNITY_IMAGE_SIZE_MIN, load_int("community_image_size", COMMUNITY_IMAGE_SIZE_DEFAULT))); + var_autoplay_level = std::min(2, std::max(0, load_int("autoplay_level", 2))); + var_forward_buffer_ratio = std::max(0.1, std::min(1.0, load_double("forward_buffer_ratio", 0.8))); + var_history_enabled = load_int("history_enabled", 1); + var_video_show_debug_info = load_int("video_show_debug_info", 0); + var_video_linear_filter = load_int("linear_filter", 1); + var_dpad_scroll_speed0 = std::max(1.0, std::min(12.0, load_double("dpad_scroll_speed0", 6.0))); + var_dpad_scroll_speed1 = std::max(var_dpad_scroll_speed0, std::min(12.0, load_double("dpad_scroll_speed1", 9.0))); + var_dpad_scroll_speed1_threashold = std::max(0.3, std::min(5.0, load_double("dpad_scroll_speed1_threashold", 2.0))); + + Util_cset_set_wifi_state(true); + Util_cset_set_screen_brightness(true, true, var_lcd_brightness); + youtube_change_content_language(var_lang_content); + video_set_linear_filter_enabled(var_video_linear_filter); + video_set_show_debug_info(var_video_show_debug_info); +} +void save_settings() { + std::string data; + auto add_str = [&] (const std::string &key, const std::string &val) { + data += "<" + key + ">" + val + "\n"; + }; + auto add_int = [&] (const std::string &key, int val) { + data += "<" + key + ">" + std::to_string(val) + "\n"; + }; + auto add_double = [&] (const std::string &key, double val) { + data += "<" + key + ">" + std::to_string(val) + "\n"; + }; + + add_str("lang_ui", var_lang); + add_str("lang_content", var_lang_content); + add_int("lcd_brightness", var_lcd_brightness); + add_int("time_to_turn_off_lcd", var_time_to_turn_off_lcd); + add_int("eco_mode", var_eco_mode); + add_int("full_screen_mode", var_full_screen_mode); + add_int("dark_theme", var_night_mode); + add_int("dark_theme_flash", var_flash_mode); + add_int("community_image_size", var_community_image_size); + add_int("autoplay_level", var_autoplay_level); + add_double("forward_buffer_ratio", var_forward_buffer_ratio); + add_int("history_enabled", var_history_enabled); + add_int("video_show_debug_info", var_video_show_debug_info); + add_int("linear_filter", var_video_linear_filter); + add_double("dpad_scroll_speed0", var_dpad_scroll_speed0); + add_double("dpad_scroll_speed1", var_dpad_scroll_speed1); + add_double("dpad_scroll_speed1_threashold", var_dpad_scroll_speed1_threashold); + + Result_with_string result = Path(SETTINGS_FILE_PATH).write_file((u8 *) data.c_str(), data.size()); + logger.info("settings/save", "write_file()..." + result.string + result.error_description, result.code); +} From 39710121f3468ec73d7ac45fbe954281cb7e10b7 Mon Sep 17 00:00:00 2001 From: cooolgamer <64099608+cooolgamer@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:29:36 +0100 Subject: [PATCH 3/6] added french translated strings --- romfs/gfx/msg/string_resources_fr.txt | 128 ++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 romfs/gfx/msg/string_resources_fr.txt diff --git a/romfs/gfx/msg/string_resources_fr.txt b/romfs/gfx/msg/string_resources_fr.txt new file mode 100644 index 00000000..e95de526 --- /dev/null +++ b/romfs/gfx/msg/string_resources_fr.txt @@ -0,0 +1,128 @@ +test +On +Off +Activé +Désactivé +Annuler +OK +Lire +Lecture... +URL +Paramètres +Historique +Supprimer de l'historique +Effacer l'historique +Êtes-vous sûr d'effacer tout l'historique? +Historique effacé +s +English +日本語 +Français +Général +Suggestions +Comms +Sous-titres +Lecteur +Playlist +Playlists +Actualiser +Réessayer +Fermer +Par défaut + +Communauté +En cours: +Mémoire tempon: +Amplificateur +Égaliseur +Vitesse +Pitch + +----UNUSED---- +Reading Stream +Seeking +Seeking(Reiniting) +----UNUSED---- + +Chargement... +Vide +Format d'image non supporté +Les commentaires sont désactivés +Aucun commentaire +Lire la suite +Afficher les réponses +Afficher plus de réponses +Cacher les réponses +Langue +Traduction auto +Langue +Aucun sous-titres +Decoder type +HW Decoder +Multithread(Slice) +Multithread(Frame) +Single Thread +Waiting Status +CPU Limit +Forward Buffer +Mémoire tampon d'avance +Raw frame buffer +Vidéos +Info +Description de la chaîne +Like +Dislike +S'abonner +Abonné +%0 Subscribers +Se désabonner --- UNUSED ---- +Abonnements +Abonnement +Nouveau +Accueil +Aucune vidéos +Aucun résultat +Appuyez ici ou sur A pour rechercher +Rechercher +Quitter +A propos +MAJ +Recherche de mises à jour... +Impossible de rechercher les mises à jour +L'application est à jour +Mise à jour disponible +Note : %0 va être écrasé +Ceci va installer un .cia +Accessing... +Téléchargement... +Installation... +LA MAJ a été correctement installé +Erreur de mise à jour +Voulez-vous quitter? +Ceci n'est pas une URL YouTube +%0 vue(s) +Par date +Par vues +Liste +Interface +Données +Avancé +Langue +Langue du contenu +Luminosité +Eteindre les écrans +Jamais +Mode éco +Plein écran +Thème sombre +Flash +Lecture auto +Playlist seulement +Vitesse de défilement +Vitesse de défilement rapide +Accélération de la vitesse de défilement +Taille des images des posts commus +Filtre linéaire sur les vidéos +Network framework +Redémarrer pour appliquer +Afficher les infos debug sur le lecteur vidéo From 90d24ee1baa8f352f9539c0b2adb353eb2365e4e Mon Sep 17 00:00:00 2001 From: cooolgamer <64099608+cooolgamer@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:59:49 +0100 Subject: [PATCH 4/6] I forgor the subscribers strings lol --- romfs/gfx/msg/string_resources_fr.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/romfs/gfx/msg/string_resources_fr.txt b/romfs/gfx/msg/string_resources_fr.txt index e95de526..eafc7dc0 100644 --- a/romfs/gfx/msg/string_resources_fr.txt +++ b/romfs/gfx/msg/string_resources_fr.txt @@ -74,7 +74,7 @@ Dislike S'abonner Abonné -%0 Subscribers +%0 Abonnés Se désabonner --- UNUSED ---- Abonnements Abonnement From 656a92f85499bc7619f0d81825e3a5822f2b46c0 Mon Sep 17 00:00:00 2001 From: cooolgamer <64099608+cooolgamer@users.noreply.github.com> Date: Fri, 27 Jan 2023 20:20:58 +0100 Subject: [PATCH 5/6] =?UTF-8?q?fix=20"fran=C3=A7ais"=20string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- romfs/gfx/msg/string_resources_en.txt | 255 +++++++++++++------------- romfs/gfx/msg/string_resources_ja.txt | 255 +++++++++++++------------- 2 files changed, 256 insertions(+), 254 deletions(-) diff --git a/romfs/gfx/msg/string_resources_en.txt b/romfs/gfx/msg/string_resources_en.txt index f9128235..2bccbcac 100644 --- a/romfs/gfx/msg/string_resources_en.txt +++ b/romfs/gfx/msg/string_resources_en.txt @@ -1,127 +1,128 @@ -test -On -Off -Enabled -Disabled -Cancel -OK -Play -Playing -URL -Settings -Watch History -Remove from the history -Remove history -Are you sure you want to\nremove your watch history? -History cleared -s -English -日本語 -General -Suggestions -Comments -Subtitles -Playback -Playlist -Playlists -Reload -Retry -Close -Reset - -Community -Currently playing: -Buffering progress -Preamp -Open Equalizer -Speed -Pitch - -----UNUSED---- -Reading Stream -Seeking -Seeking(Reiniting) -----UNUSED---- - -Loading... -Empty -Unsupported image format -Comments are disabled -No comments -Show more -Show replies -Show more replies -Hide replies -Base language -Auto translation -Select language -No caption -Decoder type -HW Decoder -Multithread(Slice) -Multithread(Frame) -Single Thread -Waiting Status -CPU Limit -Forward Buffer -Forward buffer ratio -Raw frame buffer -Videos -Info -Channel description -Like -Dislike -Subscribe -Subscribed -%0 Subscribers -Unsubscribe --- UNUSED ---- -Subscribed -Subscription -New -Home -No videos -No results -Tap here or press A to search -Search -Exit the app -About -Update -Checking for updates... -Failed checking for updates -The app is up to date -Update available -Note : %0 will be overwritten -The operation would install .cia -Accessing... -Downloading... -Installing... -Update is successfully installed -Failed to update -Are you sure you want to exit? -Not a YouTube URL -%0 view(s) -By date -By views -List -Display/UI -Data -Advanced -UI Language -Content Language -LCD Brightness -Time to turn off the LCD -Never turn off -Eco mode -Full screen mode -Dark theme -Flash -Autoplay -Playlist only -Scroll speed -Scroll speed(fast) -Scroll speedup threashold -Size of images in community posts -Linear video filter -Network framework -Restart to apply -Show debug info in the video player +test +On +Off +Enabled +Disabled +Cancel +OK +Play +Playing +URL +Settings +Watch History +Remove from the history +Remove history +Are you sure you want to\nremove your watch history? +History cleared +s +English +日本語 +Français +General +Suggestions +Comments +Subtitles +Playback +Playlist +Playlists +Reload +Retry +Close +Reset + +Community +Currently playing: +Buffering progress +Preamp +Open Equalizer +Speed +Pitch + +----UNUSED---- +Reading Stream +Seeking +Seeking(Reiniting) +----UNUSED---- + +Loading... +Empty +Unsupported image format +Comments are disabled +No comments +Show more +Show replies +Show more replies +Hide replies +Base language +Auto translation +Select language +No caption +Decoder type +HW Decoder +Multithread(Slice) +Multithread(Frame) +Single Thread +Waiting Status +CPU Limit +Forward Buffer +Forward buffer ratio +Raw frame buffer +Videos +Info +Channel description +Like +Dislike +Subscribe +Subscribed +%0 Subscribers +Unsubscribe --- UNUSED ---- +Subscribed +Subscription +New +Home +No videos +No results +Tap here or press A to search +Search +Exit the app +About +Update +Checking for updates... +Failed checking for updates +The app is up to date +Update available +Note : %0 will be overwritten +The operation would install .cia +Accessing... +Downloading... +Installing... +Update is successfully installed +Failed to update +Are you sure you want to exit? +Not a YouTube URL +%0 view(s) +By date +By views +List +Display/UI +Data +Advanced +UI Language +Content Language +LCD Brightness +Time to turn off the LCD +Never turn off +Eco mode +Full screen mode +Dark theme +Flash +Autoplay +Playlist only +Scroll speed +Scroll speed(fast) +Scroll speedup threashold +Size of images in community posts +Linear video filter +Network framework +Restart to apply +Show debug info in the video player diff --git a/romfs/gfx/msg/string_resources_ja.txt b/romfs/gfx/msg/string_resources_ja.txt index 72e477d8..9c39cc33 100644 --- a/romfs/gfx/msg/string_resources_ja.txt +++ b/romfs/gfx/msg/string_resources_ja.txt @@ -1,127 +1,128 @@ -テスト -オン -オフ -有効 -無効 -キャンセル -OK -再生 -再生中 -URL -設定 -履歴 -履歴から削除 -履歴を削除 -本当に履歴を削除しますか ? -履歴を削除しました - -English -日本語 -概要 -おすすめ -コメント -字幕 -再生 -再生リスト -再生リスト -再読み込み -再試行 -閉じる -リセット - -コミュニティ -再生中の動画 : -バッファリングの進捗 -プリアンプ -イコライザ -スピード -ピッチ - -----UNUSED---- -ストリームの読み込み中 -シーク中 -シーク(再初期化)中 -----UNUSED---- - -読み込み中... -アイテムがありません -サポートされていない画像形式 -コメントは無効です -コメントがありません -続きを読む -返信を表示 -さらに返信を表示 -返信を非表示 -ベースの言語 -自動翻訳 -言語を選択 -字幕がありません -デコーダタイプ -ハードウェアデコーダ -マルチスレッド(スライス) -マルチスレッド(フレーム) -シングルスレッド -読み込み状態 -CPU制限 -前方バッファ -前方バッファの割合 -フレームバッファ -動画 -情報 -チャンネル説明 -高評価 -低評価 -チャンネル登録 -登録済み -登録解除 ---- UNUSED ---- -登録済みチャンネル -登録チャンネル -チャンネル登録者数 %0人 -新着 -ホーム -動画がありません -検索結果がありません -ここをタップまたはAボタンで検索 -検索画面へ -アプリを終了 -このアプリについて -アップデート -アップデートの確認中... -アップデートの確認に失敗しました -最新バージョンです -更新があります -注意 : %0 は上書きされます。 -.ciaバージョンをインストールします。 -アクセス中... -ダウンロード中... -インストール中... -正常にアップデートされました -アップデートに失敗しました -本当にアプリを終了しますか ? -無効なURLです -再生回数: %0回 -日付順 -視聴回数順 -リスト -画面/UI -データ -高度な設定 -UIの言語 -コンテンツの言語 -画面の明るさ -画面自動オフまでの時間 -自動オフしない -エコモード -フルスクリーンモード -ダークモード -点滅 -自動再生 -リスト中でのみ -スクロール速度 -スクロール速度(高速) -スクロール高速化のしきい値 -コミュニティ投稿の添付画像の大きさ -動画の線形フィルタ -通信フレームワーク -適用にはアプリの再起動が必要です -動画プレーヤーにデバッグ情報を表示 +テスト +オン +オフ +有効 +無効 +キャンセル +OK +再生 +再生中 +URL +設定 +履歴 +履歴から削除 +履歴を削除 +本当に履歴を削除しますか ? +履歴を削除しました + +English +日本語 +Français +概要 +おすすめ +コメント +字幕 +再生 +再生リスト +再生リスト +再読み込み +再試行 +閉じる +リセット + +コミュニティ +再生中の動画 : +バッファリングの進捗 +プリアンプ +イコライザ +スピード +ピッチ + +----UNUSED---- +ストリームの読み込み中 +シーク中 +シーク(再初期化)中 +----UNUSED---- + +読み込み中... +アイテムがありません +サポートされていない画像形式 +コメントは無効です +コメントがありません +続きを読む +返信を表示 +さらに返信を表示 +返信を非表示 +ベースの言語 +自動翻訳 +言語を選択 +字幕がありません +デコーダタイプ +ハードウェアデコーダ +マルチスレッド(スライス) +マルチスレッド(フレーム) +シングルスレッド +読み込み状態 +CPU制限 +前方バッファ +前方バッファの割合 +フレームバッファ +動画 +情報 +チャンネル説明 +高評価 +低評価 +チャンネル登録 +登録済み +登録解除 ---- UNUSED ---- +登録済みチャンネル +登録チャンネル +チャンネル登録者数 %0人 +新着 +ホーム +動画がありません +検索結果がありません +ここをタップまたはAボタンで検索 +検索画面へ +アプリを終了 +このアプリについて +アップデート +アップデートの確認中... +アップデートの確認に失敗しました +最新バージョンです +更新があります +注意 : %0 は上書きされます。 +.ciaバージョンをインストールします。 +アクセス中... +ダウンロード中... +インストール中... +正常にアップデートされました +アップデートに失敗しました +本当にアプリを終了しますか ? +無効なURLです +再生回数: %0回 +日付順 +視聴回数順 +リスト +画面/UI +データ +高度な設定 +UIの言語 +コンテンツの言語 +画面の明るさ +画面自動オフまでの時間 +自動オフしない +エコモード +フルスクリーンモード +ダークモード +点滅 +自動再生 +リスト中でのみ +スクロール速度 +スクロール速度(高速) +スクロール高速化のしきい値 +コミュニティ投稿の添付画像の大きさ +動画の線形フィルタ +通信フレームワーク +適用にはアプリの再起動が必要です +動画プレーヤーにデバッグ情報を表示 From a52c0f716f764a37005e4dfacd30732334295623 Mon Sep 17 00:00:00 2001 From: cooolgamer <64099608+cooolgamer@users.noreply.github.com> Date: Sat, 25 Jan 2025 16:33:51 +0100 Subject: [PATCH 6/6] Archival notice --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2fa0e048..13c53e20 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +## Important +This project is now archived, please use [FourthTube](https://github.com/erievs/FourthTube/), the translations are here and updated! + +# + # ThirdTube A work-in-progress homebrew YouTube client for the 3DS