Skip to content

Commit 55c6e55

Browse files
feat(js): notification apis
1 parent 0b370e8 commit 55c6e55

5 files changed

Lines changed: 159 additions & 6 deletions

File tree

src/shell/script/binding_qjs.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,32 @@ template<> struct js_bind<mb_shell::js::win32> {
922922

923923
};
924924

925+
template <> struct qjs::js_traits<mb_shell::js::notification> {
926+
static mb_shell::js::notification unwrap(JSContext *ctx, JSValueConst v) {
927+
mb_shell::js::notification obj;
928+
929+
return obj;
930+
}
931+
932+
static JSValue wrap(JSContext *ctx, const mb_shell::js::notification &val) noexcept {
933+
JSValue obj = JS_NewObject(ctx);
934+
935+
return obj;
936+
}
937+
};
938+
template<> struct js_bind<mb_shell::js::notification> {
939+
static void bind(qjs::Context::Module &mod) {
940+
mod.class_<mb_shell::js::notification>("notification")
941+
.constructor<>()
942+
.static_fun<&mb_shell::js::notification::send_basic>("send_basic")
943+
.static_fun<&mb_shell::js::notification::send_with_image>("send_with_image")
944+
.static_fun<&mb_shell::js::notification::send_title_text>("send_title_text")
945+
.static_fun<&mb_shell::js::notification::send_with_buttons>("send_with_buttons")
946+
;
947+
}
948+
949+
};
950+
925951
template <> struct qjs::js_traits<mb_shell::js::infra> {
926952
static mb_shell::js::infra unwrap(JSContext *ctx, JSValueConst v) {
927953
mb_shell::js::infra obj;
@@ -996,6 +1022,8 @@ inline void bindAll(qjs::Context::Module &mod) {
9961022

9971023
js_bind<mb_shell::js::win32>::bind(mod);
9981024

1025+
js_bind<mb_shell::js::notification>::bind(mod);
1026+
9991027
js_bind<mb_shell::js::infra>::bind(mod);
10001028

10011029
}

src/shell/script/binding_types.cc

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
#include "FileWatch.hpp"
2626

27+
#include "wintoastlib.h"
28+
using namespace WinToastLib;
29+
2730
std::unordered_set<
2831
std::shared_ptr<std::function<void(mb_shell::js::menu_info_basic_js)>>>
2932
mb_shell::menu_callbacks_js;
@@ -1265,15 +1268,91 @@ bool win32::is_key_down(std::string key) {
12651268
{"y", 'Y'},
12661269
{"z", 'Z'}});
12671270

1268-
auto keycode = std::ranges::find_if(
1269-
key_map, [key_lower](const auto &pair) {
1270-
return key_lower == pair.first;
1271-
});
1271+
auto keycode = std::ranges::find_if(key_map, [key_lower](const auto &pair) {
1272+
return key_lower == pair.first;
1273+
});
12721274

12731275
if (keycode != key_map.end()) {
12741276
return GetAsyncKeyState(keycode->second) & 0x8000;
12751277
}
12761278

12771279
return false;
12781280
}
1281+
1282+
struct WinToastEventHandler : public IWinToastHandler {
1283+
std::function<void(int)> on_activate = [](int) {};
1284+
std::function<void(WinToastDismissalReason)> on_dismiss =
1285+
[](WinToastDismissalReason) {};
1286+
void toastActivated() const override {}
1287+
void toastActivated(int actionIndex) const override {
1288+
on_activate(actionIndex);
1289+
}
1290+
void toastActivated(const char *) const override {}
1291+
1292+
void toastDismissed(WinToastDismissalReason state) const override {
1293+
on_dismiss(state);
1294+
}
1295+
1296+
void toastFailed() const override {}
1297+
} winToastEventHandler;
1298+
1299+
static void wintoast_init() {
1300+
static bool initialized = false;
1301+
if (initialized)
1302+
return;
1303+
initialized = true;
1304+
WinToast::instance()->setAppName(L"Breeze");
1305+
WinToast::instance()->setAppUserModelId(L"breeze-shell");
1306+
WinToast::instance()->initialize();
1307+
}
1308+
1309+
void notification::send_basic(std::string message) {
1310+
wintoast_init();
1311+
1312+
WinToastTemplate templ(WinToastTemplate::ImageAndText02);
1313+
templ.setTextField(utf8_to_wstring(message), WinToastTemplate::FirstLine);
1314+
WinToast::instance()->showToast(templ, &winToastEventHandler);
1315+
}
1316+
void notification::send_with_image(std::string message, std::string icon_path) {
1317+
wintoast_init();
1318+
1319+
WinToastTemplate templ(WinToastTemplate::ImageAndText02);
1320+
templ.setTextField(utf8_to_wstring(message), WinToastTemplate::FirstLine);
1321+
templ.setImagePath(utf8_to_wstring(icon_path));
1322+
WinToast::instance()->showToast(templ, &winToastEventHandler);
1323+
}
1324+
void notification::send_title_text(std::string title, std::string message,
1325+
std::string image_path) {
1326+
wintoast_init();
1327+
WinToastTemplate templ(WinToastTemplate::ImageAndText02);
1328+
templ.setTextField(utf8_to_wstring(title), WinToastTemplate::FirstLine);
1329+
templ.setTextField(utf8_to_wstring(message), WinToastTemplate::SecondLine);
1330+
if (!image_path.empty())
1331+
templ.setImagePath(utf8_to_wstring(image_path));
1332+
WinToast::instance()->showToast(templ, &winToastEventHandler);
1333+
}
1334+
void notification::send_with_buttons(
1335+
std::string title, std::string message,
1336+
std::vector<std::pair<std::string, std::function<void()>>> buttons) {
1337+
wintoast_init();
1338+
WinToastTemplate templ(WinToastTemplate::Text02);
1339+
templ.setTextField(utf8_to_wstring(title), WinToastTemplate::FirstLine);
1340+
templ.setTextField(utf8_to_wstring(message), WinToastTemplate::SecondLine);
1341+
1342+
for (const auto &[button_text, callback] : buttons) {
1343+
templ.addAction(utf8_to_wstring(button_text));
1344+
}
1345+
1346+
auto* handler = new WinToastEventHandler();
1347+
handler->on_activate = [buttons, handler](int actionIndex) {
1348+
if (actionIndex >= 0 && actionIndex < buttons.size()) {
1349+
buttons[actionIndex].second();
1350+
}
1351+
delete handler;
1352+
};
1353+
handler->on_dismiss = [=](WinToastEventHandler::WinToastDismissalReason) {
1354+
};
1355+
1356+
WinToast::instance()->showToast(templ, handler);
1357+
}
12791358
} // namespace mb_shell::js

src/shell/script/binding_types.d.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,42 @@ export class win32 {
13471347

13481348
}
13491349

1350+
export class notification {
1351+
1352+
1353+
/**
1354+
*
1355+
* @param message: string
1356+
* @returns void
1357+
*/
1358+
static send_basic: ((arg1: string) => void)
1359+
1360+
1361+
/**
1362+
*
1363+
* @param message: string, path: string
1364+
* @returns void
1365+
*/
1366+
static send_with_image: ((arg1: string, arg2: string) => void)
1367+
1368+
1369+
/**
1370+
*
1371+
* @param title: string, message: string, image_path: string
1372+
* @returns void
1373+
*/
1374+
static send_title_text: ((arg1: string, arg2: string, arg3: string) => void)
1375+
1376+
1377+
/**
1378+
*
1379+
* @param title: string, message: string, buttons: Array<pair<string, (() => void)>>
1380+
* @returns void
1381+
*/
1382+
static send_with_buttons: ((arg1: string, arg2: string, arg3: Array<pair<string, (() => void)>>) => void)
1383+
1384+
}
1385+
13501386
export class infra {
13511387

13521388

src/shell/script/binding_types.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,16 @@ struct win32 {
642642
static bool is_key_down(std::string key);
643643
};
644644

645+
struct notification {
646+
static void send_basic(std::string message);
647+
static void send_with_image(std::string message, std::string path);
648+
static void send_title_text(std::string title, std::string message,
649+
std::string image_path);
650+
static void send_with_buttons(
651+
std::string title, std::string message,
652+
std::vector<std::pair<std::string, std::function<void()>>> buttons);
653+
};
654+
645655
struct infra {
646656
static int setTimeout(std::function<void()> callback, int delay);
647657
static void clearTimeout(int id);

xmake.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ includes("dependencies/quickjs-ng.lua")
1515

1616
set_runtimes("MT")
1717
add_requires("breeze-glfw", {alias = "glfw"})
18-
add_requires("blook", "nanovg", "glad", "quickjs-ng", "nanosvg", "reflect-cpp")
18+
add_requires("blook", "nanovg", "glad", "quickjs-ng", "nanosvg", "reflect-cpp", "wintoast")
1919

2020
target("ui")
2121
set_kind("static")
@@ -40,7 +40,7 @@ target("ui_test")
4040

4141
target("shell")
4242
set_kind("shared")
43-
add_packages("blook", "quickjs-ng", "reflect-cpp")
43+
add_packages("blook", "quickjs-ng", "reflect-cpp", "wintoast")
4444
add_deps("ui")
4545
add_syslinks("oleacc", "ole32", "oleaut32", "uuid", "comctl32", "comdlg32", "gdi32", "user32", "shell32", "kernel32", "advapi32", "psapi", "Winhttp", "dbghelp")
4646
add_rules("utils.bin2c", {

0 commit comments

Comments
 (0)