mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
ohos: Add toast prompt (#33621)
* ohos: Add toast prompt Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com> * ohos: Add toast on `load_ended` Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com> * Apply review feedback Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com> --------- Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com> Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
parent
f2f5614ad6
commit
9fcfe09e51
2 changed files with 70 additions and 22 deletions
|
@ -103,6 +103,7 @@ enum ServoAction {
|
||||||
// Todo: Need to check if OnceLock is suitable, or if the TS function can be destroyed, e.g.
|
// Todo: Need to check if OnceLock is suitable, or if the TS function can be destroyed, e.g.
|
||||||
// if the activity gets suspended.
|
// if the activity gets suspended.
|
||||||
static SET_URL_BAR_CB: OnceLock<ThreadsafeFunction<String, ErrorStrategy::Fatal>> = OnceLock::new();
|
static SET_URL_BAR_CB: OnceLock<ThreadsafeFunction<String, ErrorStrategy::Fatal>> = OnceLock::new();
|
||||||
|
static PROMPT_TOAST: OnceLock<ThreadsafeFunction<String, ErrorStrategy::Fatal>> = OnceLock::new();
|
||||||
|
|
||||||
impl ServoAction {
|
impl ServoAction {
|
||||||
fn dispatch_touch_event(
|
fn dispatch_touch_event(
|
||||||
|
@ -426,27 +427,48 @@ pub fn go_forward() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[napi(js_name = "registerURLcallback")]
|
#[napi(js_name = "registerURLcallback")]
|
||||||
pub fn register_url_callback(cb: JsFunction) -> napi_ohos::Result<()> {
|
pub fn register_url_callback(callback: JsFunction) -> napi_ohos::Result<()> {
|
||||||
info!("register_url_callback called!");
|
// Currently we call the callback in a blocking fashion, always from the embedder thread,
|
||||||
let tsfn: ThreadsafeFunction<String, ErrorStrategy::Fatal> =
|
// so a queue size of 1 is sufficient.
|
||||||
cb.create_threadsafe_function(1, |ctx| {
|
const UPDATE_URL_QUEUE_SIZE: usize = 1;
|
||||||
debug!(
|
debug!("register_url_callback called!");
|
||||||
"url callback argument transformer called with arg {}",
|
let function = callback.create_threadsafe_function(UPDATE_URL_QUEUE_SIZE, |ctx| {
|
||||||
ctx.value
|
Ok(vec![ctx
|
||||||
);
|
|
||||||
let s = ctx
|
|
||||||
.env
|
.env
|
||||||
.create_string_from_std(ctx.value)
|
.create_string_from_std(ctx.value)
|
||||||
.inspect_err(|e| error!("Failed to create JsString: {e:?}"))?;
|
.inspect_err(|e| {
|
||||||
Ok(vec![s])
|
error!("Failed to create JsString: {e:?}")
|
||||||
|
})?])
|
||||||
})?;
|
})?;
|
||||||
// We ignore any error for now - but probably we should propagate it back to the TS layer.
|
// We ignore any error for now - but probably we should propagate it back to the TS layer.
|
||||||
let _ = SET_URL_BAR_CB
|
let _ = SET_URL_BAR_CB
|
||||||
.set(tsfn)
|
.set(function)
|
||||||
.inspect_err(|_| warn!("Failed to set URL callback - register_url_callback called twice?"));
|
.inspect_err(|_| warn!("Failed to set URL callback - register_url_callback called twice?"));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub fn register_prompt_toast_callback(callback: JsFunction) -> napi_ohos::Result<()> {
|
||||||
|
// We can submit alerts in a non-blocking fashion, but alerts will always come from the
|
||||||
|
// embedder thread. Specifying 4 as a max queue size seems reasonable for now, and can
|
||||||
|
// be adjusted later.
|
||||||
|
const PROMPT_QUEUE_SIZE: usize = 4;
|
||||||
|
debug!("register_prompt_toast_callback called!");
|
||||||
|
let function = callback.create_threadsafe_function(PROMPT_QUEUE_SIZE, |ctx| {
|
||||||
|
Ok(vec![ctx
|
||||||
|
.env
|
||||||
|
.create_string_from_std(ctx.value)
|
||||||
|
.inspect_err(|e| {
|
||||||
|
error!("Failed to create JsString: {e:?}")
|
||||||
|
})?])
|
||||||
|
})?;
|
||||||
|
// We ignore any error for now - but probably we should propagate it back to the TS layer.
|
||||||
|
let _ = PROMPT_TOAST
|
||||||
|
.set(function)
|
||||||
|
.inspect_err(|_| error!("Failed to set prompt toast callback."));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn init_servo(init_opts: InitOpts) -> napi_ohos::Result<()> {
|
pub fn init_servo(init_opts: InitOpts) -> napi_ohos::Result<()> {
|
||||||
info!("Servo is being initialised with the following Options: ");
|
info!("Servo is being initialised with the following Options: ");
|
||||||
|
@ -513,8 +535,18 @@ impl HostCallbacks {
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
impl HostTrait for HostCallbacks {
|
impl HostTrait for HostCallbacks {
|
||||||
fn prompt_alert(&self, msg: String, trusted: bool) {
|
fn prompt_alert(&self, msg: String, _trusted: bool) {
|
||||||
warn!("prompt_alert not implemented. Cancelled. {}", msg);
|
debug!("prompt_alert: {msg}");
|
||||||
|
match PROMPT_TOAST.get() {
|
||||||
|
Some(prompt_fn) => {
|
||||||
|
let status = prompt_fn.call(msg, ThreadsafeFunctionCallMode::NonBlocking);
|
||||||
|
if status != napi_ohos::Status::Ok {
|
||||||
|
// Queue could be full.
|
||||||
|
error!("prompt_alert failed with {status}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => error!("PROMPT_TOAST not set. Dropping msg {msg}"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt_yes_no(&self, msg: String, trusted: bool) -> PromptResult {
|
fn prompt_yes_no(&self, msg: String, trusted: bool) -> PromptResult {
|
||||||
|
@ -541,7 +573,7 @@ impl HostTrait for HostCallbacks {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_load_ended(&self) {
|
fn on_load_ended(&self) {
|
||||||
warn!("on_load_ended not implemented")
|
self.prompt_alert("Page finished loading!".to_string(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_title_changed(&self, title: Option<String>) {
|
fn on_title_changed(&self, title: Option<String>) {
|
||||||
|
@ -554,10 +586,14 @@ impl HostTrait for HostCallbacks {
|
||||||
|
|
||||||
fn on_url_changed(&self, url: String) {
|
fn on_url_changed(&self, url: String) {
|
||||||
debug!("Hosttrait `on_url_changed` called with new url: {url}");
|
debug!("Hosttrait `on_url_changed` called with new url: {url}");
|
||||||
if let Some(cb) = SET_URL_BAR_CB.get() {
|
match SET_URL_BAR_CB.get() {
|
||||||
cb.call(url, ThreadsafeFunctionCallMode::Blocking);
|
Some(update_url_fn) => {
|
||||||
} else {
|
let status = update_url_fn.call(url, ThreadsafeFunctionCallMode::Blocking);
|
||||||
warn!("`on_url_changed` called without a registered callback")
|
if status != napi_ohos::Status::Ok {
|
||||||
|
error!("on_url_changed failed with {status}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => error!("`on_url_changed` called without a registered callback"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,5 +657,7 @@ impl HostTrait for HostCallbacks {
|
||||||
if let Some(bt) = backtrace {
|
if let Some(bt) = backtrace {
|
||||||
error!("Backtrace: {bt:?}")
|
error!("Backtrace: {bt:?}")
|
||||||
}
|
}
|
||||||
|
self.prompt_alert("Servo crashed!".to_string(), true);
|
||||||
|
self.prompt_alert(reason, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import { common } from '@kit.AbilityKit';
|
import { common } from '@kit.AbilityKit';
|
||||||
import display from '@ohos.display';
|
import display from '@ohos.display';
|
||||||
import deviceInfo from '@ohos.deviceInfo';
|
import deviceInfo from '@ohos.deviceInfo';
|
||||||
|
import promptAction from '@ohos.promptAction';
|
||||||
|
|
||||||
interface ServoXComponentInterface {
|
interface ServoXComponentInterface {
|
||||||
loadURL(url: string): void;
|
loadURL(url: string): void;
|
||||||
goBack(): void;
|
goBack(): void;
|
||||||
goForward(): void;
|
goForward(): void;
|
||||||
registerURLcallback(callback: (url: string) => void): void;
|
registerURLcallback(callback: (url: string) => void): void;
|
||||||
|
registerPromptToastCallback(callback: (msg: string) => void): void
|
||||||
initServo(options: InitOpts): void;
|
initServo(options: InitOpts): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +42,13 @@ function get_device_type(): string {
|
||||||
return device_type;
|
return device_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function prompt_toast(msg: string) {
|
||||||
|
promptAction.showToast({
|
||||||
|
message: msg,
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Use the getShared API to obtain the LocalStorage instance shared by stage.
|
// Use the getShared API to obtain the LocalStorage instance shared by stage.
|
||||||
let storage = LocalStorage.getShared()
|
let storage = LocalStorage.getShared()
|
||||||
|
|
||||||
|
@ -107,6 +116,7 @@ struct Index {
|
||||||
console.info('New URL from native: ', new_url)
|
console.info('New URL from native: ', new_url)
|
||||||
this.urlToLoad = new_url
|
this.urlToLoad = new_url
|
||||||
})
|
})
|
||||||
|
this.xComponentContext.registerPromptToastCallback(prompt_toast)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue