Skip to content

Commit 02ca716

Browse files
committed
Phase 3 (part 2): Modernize Applet UI with professional box-drawing layout
1 parent 034bf33 commit 02ca716

File tree

1 file changed

+68
-42
lines changed

1 file changed

+68
-42
lines changed

switch_app/main.cpp

Lines changed: 68 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ std::vector<std::string> g_app_logs;
5555
void add_app_log(const std::string& msg) {
5656
if (g_app_logs.size() > 15) g_app_logs.erase(g_app_logs.begin());
5757
g_app_logs.push_back(msg);
58+
59+
if (g_dev_mode) {
60+
int sock = socket(AF_INET, SOCK_DGRAM, 0);
61+
if (sock >= 0) {
62+
int opt = 1;
63+
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&opt, sizeof(opt));
64+
struct sockaddr_in addr;
65+
memset(&addr, 0, sizeof(addr));
66+
addr.sin_family = AF_INET;
67+
addr.sin_port = htons(2828);
68+
addr.sin_addr.s_addr = INADDR_BROADCAST;
69+
sendto(sock, msg.c_str(), msg.length(), 0, (struct sockaddr*)&addr, sizeof(addr));
70+
close(sock);
71+
}
72+
}
5873
}
5974

6075
std::string get_latest_version(std::string& date) {
@@ -83,6 +98,10 @@ std::string get_latest_version(std::string& date) {
8398
if (!date.empty() && date.length() > 10) date = date.substr(0, 10);
8499
if (!version.empty() && version[0] == 'v') version = version.substr(1);
85100
} else {
101+
std::string errMsg = j.value("message", "API Limit or Missing Release");
102+
char errLog[256];
103+
snprintf(errLog, sizeof(errLog), "\x1b[31m[ERROR] Update check: %s\x1b[0m", errMsg.substr(0, 50).c_str());
104+
add_app_log(errLog);
86105
version = "none";
87106
}
88107
} else {
@@ -154,7 +173,7 @@ std::string get_sysmodule_ip() {
154173
u32 cur_ip = 0;
155174
if (R_SUCCEEDED(nifmGetCurrentIpAddress(&cur_ip)) && cur_ip != 0) {
156175
struct in_addr addr; addr.s_addr = cur_ip;
157-
if (strcmp(inet_ntoa(addr), "192.168.1.35") == 0) return "192.168.1.35";
176+
return std::string(inet_ntoa(addr));
158177
}
159178
return "127.0.0.1";
160179
}
@@ -180,12 +199,6 @@ bool try_connect(const std::string& ip, int port) {
180199
res = (v == 0) ? 0 : -1;
181200
} else res = -1;
182201
}
183-
184-
if (res != 0 && g_dev_mode) {
185-
char err[128];
186-
snprintf(err, sizeof(err), "\x1b[2m[DEBUG] Connect %s:%d failed (%d)\x1b[0m", ip.c_str(), port, errno);
187-
add_app_log(err);
188-
}
189202

190203
fcntl(sock, F_SETFL, flags);
191204
close(sock);
@@ -236,55 +249,68 @@ void fetch_offline_boot_logs() {
236249
add_app_log(entry);
237250
}
238251
fclose(f);
239-
// Do NOT remove file yet, keep for diagnostics if needed
252+
remove("sdmc:/ha_sysmodule_boot.log");
240253
}
241254
}
242255

243256
void draw_ui(const std::string& latest_ver, bool checking_update, bool sysmodule_active, u64 loop_count) {
244-
printf("\x1b[1;1H");
245-
printf("\x1b[41m\x1b[1;37m HOME ASSISTANT SWITCH v%s \x1b[0m\x1b[K\n", APP_VERSION);
246-
printf("\x1b[2m (c) 2026 FaserF | https://github.com/FaserF/ha-NintendoSwitchCFW\x1b[0m\x1b[K\n\n");
257+
printf("\x1b[H"); // Home
258+
printf("\x1b[36m┌──────────────────────────────────────────────────────────────────────────┐\x1b[0m\x1b[K\n");
259+
printf("\x1b[36m│\x1b[0m\x1b[1;37m HOME ASSISTANT SWITCH v%-10s \x1b[0m\x1b[36m│\x1b[0m\x1b[K\n", APP_VERSION);
260+
printf("\x1b[36m├───────────────────────────────┬──────────────────────────────────────────┤\x1b[0m\x1b[K\n");
261+
262+
// Left Pane: System Status
263+
printf("\x1b[36m│\x1b[0m \x1b[1;34m[ SYSTEM STATUS ]\x1b[0m \x1b[36m│\x1b[0m \x1b[1;34m[ UPDATES & CONFIG ]\x1b[0m \x1b[36m│\x1b[0m\x1b[K\n");
264+
265+
printf("\x1b[36m│\x1b[0m Status: %-18s \x1b[36m│\x1b[0m ", sysmodule_active ? "\x1b[1;32mACTIVE\x1b[0m" : "\x1b[1;31mINACTIVE\x1b[0m");
266+
if (checking_update) printf("\x1b[5;33mChecking for updates...\x1b[0m ");
267+
else if (latest_ver == "") printf("\x1b[2mUpdate check pending... (X) \x1b[0m ");
268+
else if (latest_ver != "none" && latest_ver != "error") {
269+
if (latest_ver != APP_VERSION) printf("\x1b[1;42m\x1b[37m NEW v%-6s AVAILABLE! (Y) \x1b[0m ", latest_ver.c_str());
270+
else printf("\x1b[2mLatest version active (v%-6s) \x1b[0m", latest_ver.c_str());
271+
} else printf("\x1b[31mUpdate check failed \x1b[0m ");
272+
printf("\x1b[36m│\x1b[0m\x1b[K\n");
247273

248-
printf("\x1b[1;36m[ SYSTEM STATUS ]\x1b[0m\x1b[K\n");
249-
printf(" Status: %s\x1b[K\n", sysmodule_active ? "\x1b[1;32mACTIVE\x1b[0m" : "\x1b[1;31mINACTIVE\x1b[0m");
250274
u32 ip = 0;
275+
struct in_addr addr;
251276
if (R_SUCCEEDED(nifmGetCurrentIpAddress(&ip)) && ip != 0) {
252-
struct in_addr addr; addr.s_addr = ip;
253-
printf(" IP Address: \x1b[1;32m%s\x1b[0m\x1b[K\n", inet_ntoa(addr));
254-
} else printf(" IP Address: \x1b[1;31mDisconnected\x1b[0m\x1b[K\n");
277+
addr.s_addr = ip;
278+
printf("\x1b[36m│\x1b[0m IP: \x1b[1;32m%-15s\x1b[0m \x1b[36m│\x1b[0m ", inet_ntoa(addr));
279+
} else {
280+
printf("\x1b[36m│\x1b[0m IP: \x1b[1;31mDisconnected\x1b[0m \x1b[36m│\x1b[0m ");
281+
}
282+
printf("Port: \x1b[1m%-5d\x1b[0m \x1b[36m│\x1b[0m\x1b[K\n", ConfigManager::getInstance().getPort());
255283

256284
NifmInternetConnectionStatus net_status;
285+
const char* net_s = "Unknown";
257286
if (R_SUCCEEDED(nifmGetInternetConnectionStatus(NULL, NULL, &net_status))) {
258-
const char* s = (net_status == NifmInternetConnectionStatus_Connected) ? "Online" : "Limited/Off";
259-
printf(" Net Status: \x1b[1m%s\x1b[0m\x1b[K\n", s);
287+
net_s = (net_status == NifmInternetConnectionStatus_Connected) ? "\x1b[1;32mOnline\x1b[0m" : "\x1b[1;31mOffline\x1b[0m";
260288
}
261-
printf("\x1b[K\n");
262-
263-
printf("\x1b[1;36m[ CONFIGURATION ]\x1b[0m\x1b[K\n");
264-
printf(" Port: \x1b[1m%d\x1b[0m | Token: \x1b[1;33m%s\x1b[0m\x1b[K\n\n",
265-
ConfigManager::getInstance().getPort(), ConfigManager::getInstance().getApiToken()[0] ? ConfigManager::getInstance().getApiToken() : "NONE");
289+
printf("\x1b[36m│\x1b[0m Network: %-25s \x1b[36m│\x1b[0m ", net_s);
290+
printf("Token: \x1b[1;33m%-15s\x1b[0m \x1b[36m│\x1b[0m\x1b[K\n", ConfigManager::getInstance().getApiToken()[0] ? ConfigManager::getInstance().getApiToken() : "MISSING");
266291

267-
printf("\x1b[1;36m[ UPDATES ]\x1b[0m\x1b[K\n");
268-
if (checking_update) printf(" \x1b[5;33mChecking...\x1b[0m\x1b[K\n");
269-
else if (latest_ver == "") printf(" \x1b[2mUpdate check pending... (X) to Check\x1b[0m\x1b[K\n");
270-
else if (latest_ver != "none" && latest_ver != "error") {
271-
if (latest_ver != APP_VERSION) {
272-
if (APP_VERSION > latest_ver) printf(" \x1b[1;32mDEV VERSION (Ahead of GitHub v%s)\x1b[0m\x1b[K\n", latest_ver.c_str());
273-
else printf(" \x1b[1;42m\x1b[37m NEW v%s AVAILABLE! \x1b[0m (Y)\x1b[K\n", latest_ver.c_str());
274-
} else printf(" \x1b[2mLatest version active.\x1b[0m\x1b[K\n");
275-
} else printf(" \x1b[2mUpdate check failed/skipped.\x1b[0m\x1b[K\n");
276-
printf("\x1b[K\n");
277-
278-
printf("\x1b[1;36m[ SYSTEM LOGS ]\x1b[0m\x1b[K\n");
279-
if (g_app_logs.empty()) printf(" Waiting for bridge...\x1b[K\n");
280-
else {
292+
printf("\x1b[36m├───────────────────────────────┴──────────────────────────────────────────┤\x1b[0m\x1b[K\n");
293+
printf("\x1b[36m│\x1b[0m \x1b[1;34m[ SYSTEM LOGS ]\x1b[0m \x1b[36m│\x1b[0m\x1b[K\n");
294+
295+
if (g_app_logs.empty()) {
296+
for(int i=0; i<10; i++) printf("\x1b[36m│\x1b[0m %-72s \x1b[36m│\x1b[0m\x1b[K\n", i == 0 ? "Waiting for sysmodule bridge..." : "");
297+
} else {
281298
size_t start = (g_app_logs.size() > 10) ? g_app_logs.size() - 10 : 0;
282-
for (size_t i = start; i < g_app_logs.size(); i++) printf(" %s\x1b[K\n", g_app_logs[i].c_str());
299+
for (size_t i = 0; i < 10; i++) {
300+
printf("\x1b[36m│\x1b[0m ");
301+
if (start + i < g_app_logs.size()) {
302+
printf("%s", g_app_logs[start + i].c_str());
303+
printf("\x1b[75G\x1b[36m│\x1b[0m\x1b[K\n");
304+
} else {
305+
printf("%-72s \x1b[36m│\x1b[0m\x1b[K\n", "");
306+
}
307+
}
283308
}
284-
for (int i=0; i<3; i++) printf("\x1b[K\n");
285-
printf("\x1b[1;34m----------------------------------------------------\x1b[0m\x1b[K\n");
286-
printf(" (ZL)Reload (ZR)Reset (X)Update (Y)Install (+)Exit (-)Dev\x1b[K\n");
287-
printf("\x1b[1;34m----------------------------------------------------\x1b[0m\x1b[K\n");
309+
310+
printf("\x1b[36m└──────────────────────────────────────────────────────────────────────────┘\x1b[0m\x1b[K\n");
311+
printf(" \x1b[1;37m(X)Check (Y)Update/Install (ZR)Reset (-)DevMode (+)Exit\x1b[0m\x1b[K\n");
312+
if (g_dev_mode) printf(" \x1b[45m\x1b[1;37m DEV MODE ACTIVE \x1b[0m UDP Broadcast on Port 2828\x1b[K\n");
313+
else printf("\x1b[K\n");
288314
}
289315

290316
int main(int argc, char **argv) {

0 commit comments

Comments
 (0)