diff --git a/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java b/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java
index 2122f284..f18e86d7 100644
--- a/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java
+++ b/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java
@@ -15,10 +15,18 @@
*/
package pub.doric.plugin;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.text.TextUtils;
import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
import android.widget.Toast;
import pub.doric.DoricContext;
+import pub.doric.R;
import pub.doric.extension.bridge.DoricPlugin;
import pub.doric.extension.bridge.DoricMethod;
import pub.doric.extension.bridge.DoricPromise;
@@ -29,6 +37,7 @@ import com.github.pengfeizhou.jscore.ArchiveException;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
+import com.github.pengfeizhou.jscore.JavaValue;
/**
* @Description: Doric
@@ -68,4 +77,151 @@ public class ModalPlugin extends DoricJavaPlugin {
e.printStackTrace();
}
}
+
+ @DoricMethod(name = "alert", thread = ThreadMode.UI)
+ public void alert(JSDecoder decoder, final DoricPromise promise) {
+ try {
+ JSObject jsObject = decoder.decode().asObject();
+ JSValue titleVal = jsObject.getProperty("title");
+ JSValue msgVal = jsObject.getProperty("msg");
+ JSValue okBtn = jsObject.getProperty("okLabel");
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getDoricContext().getContext(), R.style.Theme_Doric_Modal_Alert);
+ if (titleVal.isString()) {
+ builder.setTitle(titleVal.asString().value());
+ }
+ String btnTitle = getDoricContext().getContext().getString(android.R.string.ok);
+ if (okBtn.isString()) {
+ btnTitle = okBtn.asString().value();
+ }
+ builder.setMessage(msgVal.asString().value())
+ .setPositiveButton(btnTitle, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ promise.resolve();
+ }
+ });
+ builder.setCancelable(false);
+ try {
+ builder.show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } catch (ArchiveException e) {
+ e.printStackTrace();
+ promise.reject(new JavaValue(e.getLocalizedMessage()));
+ }
+ }
+
+
+ @DoricMethod(name = "confirm", thread = ThreadMode.UI)
+ public void confirm(JSDecoder decoder, final DoricPromise promise) {
+ try {
+ JSObject jsObject = decoder.decode().asObject();
+ JSValue titleVal = jsObject.getProperty("title");
+ JSValue msgVal = jsObject.getProperty("msg");
+ JSValue okBtn = jsObject.getProperty("okLabel");
+ JSValue cancelBtn = jsObject.getProperty("cancelLabel");
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getDoricContext().getContext(), R.style.Theme_Doric_Modal_Confirm);
+ if (titleVal.isString()) {
+ builder.setTitle(titleVal.asString().value());
+ }
+ String okLabel = getDoricContext().getContext().getString(android.R.string.ok);
+ if (okBtn.isString()) {
+ okLabel = okBtn.asString().value();
+ }
+ String cancelLabel = getDoricContext().getContext().getString(android.R.string.cancel);
+ if (cancelBtn.isString()) {
+ cancelLabel = cancelBtn.asString().value();
+ }
+ builder.setMessage(msgVal.asString().value())
+ .setPositiveButton(okLabel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ promise.resolve();
+ }
+ })
+ .setNegativeButton(cancelLabel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ promise.reject();
+ }
+ });
+ builder.setCancelable(false);
+ try {
+ builder.show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } catch (ArchiveException e) {
+ e.printStackTrace();
+ promise.reject(new JavaValue(e.getLocalizedMessage()));
+ }
+ }
+
+
+ @DoricMethod(name = "prompt", thread = ThreadMode.UI)
+ public void prompt(JSDecoder decoder, final DoricPromise promise) {
+ try {
+ JSObject jsObject = decoder.decode().asObject();
+ JSValue titleVal = jsObject.getProperty("title");
+ JSValue msgVal = jsObject.getProperty("msg");
+ JSValue okBtn = jsObject.getProperty("okLabel");
+ JSValue cancelBtn = jsObject.getProperty("cancelLabel");
+ JSValue defaultVal = jsObject.getProperty("defaultText");
+ JSValue text = jsObject.getProperty("text");
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getDoricContext().getContext(), R.style.Theme_Doric_Modal_Prompt);
+ if (titleVal.isString()) {
+ builder.setTitle(titleVal.asString().value());
+ }
+ String okLabel = getDoricContext().getContext().getString(android.R.string.ok);
+ if (okBtn.isString()) {
+ okLabel = okBtn.asString().value();
+ }
+ String cancelLabel = getDoricContext().getContext().getString(android.R.string.cancel);
+ if (cancelBtn.isString()) {
+ cancelLabel = cancelBtn.asString().value();
+ }
+
+
+ View v = LayoutInflater.from(getDoricContext().getContext()).inflate(R.layout.doric_modal_prompt, null);
+ TextView tvMsg = v.findViewById(R.id.tv_msg);
+ tvMsg.setText(msgVal.asString().value());
+ final EditText editText = v.findViewById(R.id.edit_input);
+ if (defaultVal.isString()) {
+ editText.setHint(defaultVal.asString().value());
+ }
+ if (text.isString()) {
+ editText.setText(text.asString().value());
+ editText.setSelection(text.asString().value().length());
+ }
+ builder.setView(v);
+ builder
+ .setPositiveButton(okLabel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ promise.resolve(new JavaValue(editText.getText().toString()));
+ }
+ })
+ .setNegativeButton(cancelLabel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ promise.reject(new JavaValue(editText.getText().toString()));
+ }
+ });
+ builder.setCancelable(false);
+ try {
+ builder.show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } catch (ArchiveException e) {
+ e.printStackTrace();
+ promise.reject(new JavaValue(e.getLocalizedMessage()));
+ }
+
+
+ }
}
diff --git a/Android/doric/src/main/res/layout/doric_modal_prompt.xml b/Android/doric/src/main/res/layout/doric_modal_prompt.xml
new file mode 100644
index 00000000..1e0c88f0
--- /dev/null
+++ b/Android/doric/src/main/res/layout/doric_modal_prompt.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Android/doric/src/main/res/values-v21/styles.xml b/Android/doric/src/main/res/values-v21/styles.xml
new file mode 100644
index 00000000..5c99d8c1
--- /dev/null
+++ b/Android/doric/src/main/res/values-v21/styles.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Android/doric/src/main/res/values/styles.xml b/Android/doric/src/main/res/values/styles.xml
new file mode 100644
index 00000000..9ba3f2f0
--- /dev/null
+++ b/Android/doric/src/main/res/values/styles.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/src/ModalDemo.ts b/demo/src/ModalDemo.ts
index 2ffb536f..9fccd7e6 100644
--- a/demo/src/ModalDemo.ts
+++ b/demo/src/ModalDemo.ts
@@ -51,6 +51,94 @@ class ModalDemo extends Panel {
modal(context).toast('This is a toast.', Gravity.Center)
}
} as IText),
+ text({
+ text: "Alert",
+ layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST),
+ textSize: 30,
+ textColor: Color.WHITE,
+ bgColor: colors[2],
+ textAlignment: Gravity.Center,
+ height: 50,
+ }),
+ label('Click me').apply({
+ width: 200,
+ height: 50,
+ bgColor: colors[0],
+ textSize: 30,
+ textColor: Color.WHITE,
+ layoutConfig: layoutConfig().exactly(),
+ onClick: () => {
+ modal(context).alert({
+ msg: 'This is alert.',
+ title: 'Alert title',
+ okLabel: "OkLabel"
+ }).then(e => {
+ modal(context).toast('Clicked OK.')
+ })
+ }
+ } as IText),
+ text({
+ text: "Confirm",
+ layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST),
+ textSize: 30,
+ textColor: Color.WHITE,
+ bgColor: colors[3],
+ textAlignment: Gravity.Center,
+ height: 50,
+ }),
+ label('Click me').apply({
+ width: 200,
+ height: 50,
+ bgColor: colors[0],
+ textSize: 30,
+ textColor: Color.WHITE,
+ layoutConfig: layoutConfig().exactly(),
+ onClick: () => {
+ modal(context).confirm({
+ msg: 'This is Confirm.',
+ title: 'Confirm title',
+ okLabel: "OkLabel",
+ cancelLabel: 'CancelLabel',
+ }).then(
+ () => {
+ modal(context).toast('Clicked OK.')
+ },
+ () => {
+ modal(context).toast('Clicked Cancel.')
+ })
+ }
+ } as IText),
+ text({
+ text: "Prompt",
+ layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST),
+ textSize: 30,
+ textColor: Color.WHITE,
+ bgColor: colors[4],
+ textAlignment: Gravity.Center,
+ height: 50,
+ }),
+ label('Click me').apply({
+ width: 200,
+ height: 50,
+ bgColor: colors[0],
+ textSize: 30,
+ textColor: Color.WHITE,
+ layoutConfig: layoutConfig().exactly(),
+ onClick: () => {
+ modal(context).prompt({
+ msg: 'This is Prompt.',
+ title: 'Prompt title',
+ okLabel: "OkLabel",
+ cancelLabel: 'CancelLabel',
+ }).then(
+ e => {
+ modal(context).toast(`Clicked OK.Input:${e}`)
+ },
+ e => {
+ modal(context).toast(`Clicked Cancel.Input:${e}`)
+ })
+ }
+ } as IText),
]).apply({
layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT),
gravity: Gravity.Center,
diff --git a/iOS/Pod/Classes/Plugin/DoricModalPlugin.m b/iOS/Pod/Classes/Plugin/DoricModalPlugin.m
index b13f2734..e9925e34 100644
--- a/iOS/Pod/Classes/Plugin/DoricModalPlugin.m
+++ b/iOS/Pod/Classes/Plugin/DoricModalPlugin.m
@@ -36,4 +36,80 @@ - (void)toast:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
});
}
+- (void)alert:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"]
+ message:dic[@"msg"]
+ preferredStyle:UIAlertControllerStyleAlert];
+ UIAlertAction *action = [UIAlertAction actionWithTitle:dic[@"okLabel"] ?: NSLocalizedString(@"OK", nil)
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction *action) {
+ [promise resolve:nil];
+ }];
+ [alert addAction:action];
+ UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
+ [vc presentViewController:alert animated:YES completion:nil];
+ });
+}
+
+- (void)confirm:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"]
+ message:dic[@"msg"]
+ preferredStyle:UIAlertControllerStyleAlert];
+ UIAlertAction *okAction = [UIAlertAction actionWithTitle:dic[@"okLabel"] ?: NSLocalizedString(@"Ok", nil)
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction *action) {
+ [promise resolve:nil];
+ }];
+ [alert addAction:okAction];
+
+ UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:dic[@"cancelLabel"] ?: NSLocalizedString(@"Cancel", nil)
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction *action) {
+ [promise reject:nil];
+ }];
+ [alert addAction:cancelAction];
+ UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
+ [vc presentViewController:alert animated:YES completion:nil];
+ });
+}
+
+- (void)prompt:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"]
+ message:dic[@"msg"]
+ preferredStyle:UIAlertControllerStyleAlert];
+ NSString *placeholder = dic[@"defaultText"];
+ NSString *preText = dic[@"text"];
+ [alert addTextFieldWithConfigurationHandler:^(UITextField *_Nonnull textField) {
+ if (placeholder.length > 0) {
+ textField.placeholder = placeholder;
+ }
+ if (preText.length > 0) {
+ textField.text = preText;
+ }
+ }];
+ __weak typeof(alert) _alert = alert;
+ UIAlertAction *okAction = [UIAlertAction actionWithTitle:dic[@"okLabel"] ?: NSLocalizedString(@"Ok", nil)
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction *action) {
+ __strong typeof(_alert) alert = _alert;
+ [promise resolve:alert.textFields.lastObject.text];
+ }];
+ [alert addAction:okAction];
+
+ UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:dic[@"cancelLabel"] ?: NSLocalizedString(@"Cancel", nil)
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction *action) {
+ __strong typeof(_alert) alert = _alert;
+ [promise reject:alert.textFields.lastObject.text];
+ }];
+ [alert addAction:cancelAction];
+
+
+ UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
+ [vc presentViewController:alert animated:YES completion:nil];
+ });
+}
@end
diff --git a/iOS/Pod/Classes/Plugin/DoricPromise.h b/iOS/Pod/Classes/Plugin/DoricPromise.h
index 4f0bd10c..26807d07 100644
--- a/iOS/Pod/Classes/Plugin/DoricPromise.h
+++ b/iOS/Pod/Classes/Plugin/DoricPromise.h
@@ -23,8 +23,6 @@
#import
#import "DoricContext.h"
-NS_ASSUME_NONNULL_BEGIN
-
@interface DoricPromise : NSObject
- (instancetype)initWithContext:(DoricContext *)context callbackId:(NSString *)callbackId;
@@ -32,5 +30,3 @@ NS_ASSUME_NONNULL_BEGIN
- (void)reject:(id)result;
@end
-
-NS_ASSUME_NONNULL_END
diff --git a/js-framework/src/util/modal.ts b/js-framework/src/util/modal.ts
index dd44af54..ec27dfdd 100644
--- a/js-framework/src/util/modal.ts
+++ b/js-framework/src/util/modal.ts
@@ -1,8 +1,21 @@
+/*
+ * Copyright [2019] [Doric.Pub]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
import { BridgeContext } from "../runtime/global";
import { Gravity } from "./gravity";
-
-
export function modal(context: BridgeContext) {
return {
toast: (msg: string, gravity: Gravity = Gravity.Bottom) => {
@@ -11,5 +24,38 @@ export function modal(context: BridgeContext) {
gravity: gravity.toModel(),
})
},
+ alert: (arg: string | {
+ title: string,
+ msg: string,
+ okLabel?: string,
+ }) => {
+ if (typeof arg === 'string') {
+ return context.modal.alert({ msg: arg })
+ } else {
+ return context.modal.alert(arg)
+ }
+ },
+ confirm: (arg: string | {
+ title: string,
+ msg: string,
+ okLabel?: string,
+ cancelLabel?: string,
+ }) => {
+ if (typeof arg === 'string') {
+ return context.modal.confirm({ msg: arg })
+ } else {
+ return context.modal.confirm(arg)
+ }
+ },
+ prompt: (arg: {
+ title?: string,
+ msg?: string,
+ okLabel?: string,
+ cancelLabel?: string,
+ text?: string,
+ defaultText?: string,
+ }) => {
+ return context.modal.prompt(arg)
+ },
}
}
\ No newline at end of file