feat: add file size in dialog on sing-box download

This commit is contained in:
Ixniy Evonniy 2026-07-01 12:40:06 +03:00
parent 0f7d119edf
commit a0d9c0779c
4 changed files with 102 additions and 15 deletions

View File

@ -493,6 +493,8 @@ Download_Dialog_State :: struct {
thread: Thread;
thread_data: Download_Thread_Data;
static_hwnd: HWND;
file_size: u64;
is_update: bool;
}
download_dialog_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #c_call {
@ -508,12 +510,15 @@ download_dialog_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -
hFont := GetStockObject(DEFAULT_GUI_FONT);
operation := ifx state.is_update then "update" else "installation";
size_text := format_file_size(state.file_size);
status_text := tprint("Downloading Sing-box core %...\nDownload size: %\nThis may take a moment, please wait.", operation, size_text);
state.static_hwnd = CreateWindowExW(
0,
utf8_to_wide("STATIC"),
utf8_to_wide("Downloading Sing-box core executable...\nThis may take a moment, please wait."),
utf8_to_wide(status_text),
WS_CHILD | WS_VISIBLE | SS_LEFT,
30, 30, 400, 50,
30, 25, 400, 65,
hwnd,
null,
null,
@ -566,7 +571,7 @@ download_dialog_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -
}
}
show_download_progress_dialog :: (parent_hwnd: HWND, url: string, dest_path: string) -> bool, string {
show_download_progress_dialog :: (parent_hwnd: HWND, url: string, dest_path: string, file_size: u64, is_update: bool) -> bool, string {
hInstance := GetModuleHandleW(null);
class_name := utf8_to_wide("Sing-boxDownloadDialogClass");
@ -592,11 +597,15 @@ show_download_progress_dialog :: (parent_hwnd: HWND, url: string, dest_path: str
state: Download_Dialog_State;
state.thread_data.url = copy_string(url);
state.thread_data.dest_path = copy_string(dest_path);
state.file_size = file_size;
state.is_update = is_update;
dialog_title := ifx is_update then "Updating Sing-box Core" else "Installing Sing-box Core";
dialog_hwnd := CreateWindowExW(
WS_EX_DLGMODALFRAME,
class_name,
utf8_to_wide("Downloading Sing-box Core"),
utf8_to_wide(dialog_title),
WS_POPUP | WS_CAPTION,
dialog_x, dialog_y, dialog_w, dialog_h,
parent_hwnd,
@ -638,4 +647,3 @@ show_download_progress_dialog :: (parent_hwnd: HWND, url: string, dest_path: str
return state.thread_data.success, state.thread_data.error_msg;
}

View File

@ -727,8 +727,23 @@ install_or_update_singbox_core :: (app: *App_State, is_update: bool) -> bool {
prompt_title := ifx is_update then "Update Sing-box" else "Sing-box Core Installation";
success_msg := tprint("Sing-box core % successfully!", ifx is_update then "updated" else "installed");
file_size, size_ok, size_err := get_remote_file_size(download_url);
if !size_ok {
msg := tprint("Could not determine the Sing-box download size.\nError: %\n\nPlease ensure you have an active internet connection.", size_err);
MessageBoxW(app.hwnd, utf8_to_wide(msg), utf8_to_wide(prompt_title), MB_ICONERROR);
return false;
}
size_text := format_file_size(file_size);
action := ifx is_update then "update Sing-box" else "download and install Sing-box";
prompt := tprint("Version: %\nDownload size: %\n\nWould you like to % now?", version_to_download, size_text, action);
response := MessageBoxW(app.hwnd, utf8_to_wide(prompt), utf8_to_wide(prompt_title), MB_YESNO | MB_ICONQUESTION);
if response != IDYES {
return false;
}
// 1. Download while VPN is still active
success, err_msg := show_download_progress_dialog(app.hwnd, download_url, temp_zip);
success, err_msg := show_download_progress_dialog(app.hwnd, download_url, temp_zip, file_size, is_update);
if !success {
msg := tprint("Failed to download Sing-box core.\nError: %\n\nPlease ensure you have an active internet connection.", err_msg);
MessageBoxW(app.hwnd, utf8_to_wide(msg), utf8_to_wide("Sing-box Tray"), MB_ICONERROR);
@ -926,13 +941,8 @@ start_singbox :: (app: *App_State) -> bool {
exe_path := tprint("%\\sing-box.exe", global_userspace_dir);
if !file_exists(exe_path) {
response := MessageBoxW(app.hwnd, utf8_to_wide("Sing-box core executable (sing-box.exe) was not found in your userspace folder.\n\nWould you like to download and install it now?"), utf8_to_wide("Sing-box Tray"), MB_YESNO | MB_ICONQUESTION);
if response == IDYES {
installed := install_or_update_singbox_core(app, false);
return installed; // install_or_update_singbox_core handles starting sing-box
} else {
return false;
}
installed := install_or_update_singbox_core(app, false);
return installed; // install_or_update_singbox_core handles prompting and starting sing-box
}

View File

@ -12,6 +12,76 @@ Updater_Thread_Data :: struct {
is_test_mode: bool;
}
get_remote_file_size :: (url: string) -> u64, bool, string {
hInternet := InternetOpenW(
utf8_to_wide("Sing-boxTrayDownloader"),
INTERNET_OPEN_TYPE_PRECONFIG,
null,
null,
0
);
if !hInternet {
return 0, false, "Failed to initialize WinINet session";
}
defer InternetCloseHandle(hInternet);
flags: DWORD = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE;
if starts_with(url, "https") {
flags |= INTERNET_FLAG_SECURE;
}
headers := "User-Agent: Sing-boxTray\r\n";
hUrl := InternetOpenUrlW(
hInternet,
utf8_to_wide(url),
utf8_to_wide(headers),
cast(u32) headers.count,
flags,
0
);
if !hUrl {
err := GetLastError();
return 0, false, tprint("Failed to open URL (Win32 Error: %)", err);
}
defer InternetCloseHandle(hUrl);
response_code: DWORD;
response_code_size: DWORD = size_of(type_of(response_code));
if !HttpQueryInfoW(hUrl, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, *response_code, *response_code_size, null) {
err := GetLastError();
return 0, false, tprint("Failed to query HTTP status code (Win32 Error: %)", err);
}
if response_code != 200 {
return 0, false, tprint("HTTP request failed with status code %", response_code);
}
content_length: DWORD;
content_length_size: DWORD = size_of(type_of(content_length));
if !HttpQueryInfoW(hUrl, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, *content_length, *content_length_size, null) {
err := GetLastError();
return 0, false, tprint("Failed to query download size (Win32 Error: %)", err);
}
return cast(u64) content_length, true, "";
}
format_file_size :: (bytes: u64) -> string {
mib: u64 = 1024 * 1024;
kib: u64 = 1024;
if bytes >= mib {
whole := bytes / mib;
tenths := (bytes % mib) * 10 / mib;
return tprint("%.% MiB", whole, tenths);
}
if bytes >= kib {
whole := bytes / kib;
tenths := (bytes % kib) * 10 / kib;
return tprint("%.% KiB", whole, tenths);
}
return tprint("% bytes", bytes);
}
download_url :: (url: string) -> string, bool, string {
log_info("Downloading config from URL: %\n", url);
@ -432,4 +502,3 @@ download_file :: (url: string, dest_path: string) -> bool, string {
return true, "";
}

View File

@ -259,6 +259,7 @@ INTERNET_FLAG_SECURE :: 0x00800000;
INTERNET_FLAG_NO_CACHE_WRITE :: 0x04000000;
HTTP_QUERY_STATUS_CODE :: 19;
HTTP_QUERY_CONTENT_LENGTH :: 5;
HTTP_QUERY_FLAG_NUMBER :: 0x20000000;
InternetOpenW :: (
@ -376,4 +377,3 @@ RGB :: (r: u32, g: u32, b: u32) -> u32 {