Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: return Promises for Ti.Window open()/close() methods #12407

Merged
merged 12 commits into from
Feb 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.view.TiUIActivityWindow;
import org.appcelerator.titanium.view.TiUIView;

Expand Down Expand Up @@ -40,7 +41,7 @@ protected void handleClose(@NonNull KrollDict options)
{
Log.d(TAG, "handleClose", Log.DEBUG_MODE);
opened = false;
fireEvent("close", null);
fireEvent(TiC.EVENT_CLOSE, null);

if (view != null) {
((TiUIActivityWindow) view).close();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2018 by Axway, Inc. All Rights Reserved.
* Copyright (c) 2018-2021 by Axway, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package ti.modules.titanium.ui;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollPromise;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.proxy.TiWindowProxy;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;

@Kroll.proxy(creatableInModule = UIModule.class)
public class NavigationWindowProxy extends WindowProxy
{
Expand All @@ -27,7 +31,7 @@ public NavigationWindowProxy()

@Override
@Kroll.method
public void open(@Kroll.argument(optional = true) Object arg)
public KrollPromise<Void> open(@Kroll.argument(optional = true) Object arg)
{
// FIXME: Shouldn't this complain/blow up if window isn't specified?
if (!opened && getProperties().containsKeyAndNotNull(TiC.PROPERTY_WINDOW)) {
Expand All @@ -37,9 +41,11 @@ public void open(@Kroll.argument(optional = true) Object arg)
openWindow(rootView, arg);
fireEvent(TiC.EVENT_OPEN, null);
}
return;
return KrollPromise.create((promise) -> {
promise.resolve(null);
});
}
super.open(arg);
return super.open(arg);
}

@Kroll.method
Expand All @@ -52,17 +58,19 @@ public void popToRootWindow(@Kroll.argument(optional = true) Object arg)
}
}

@Override
@Kroll.method
public void close(@Kroll.argument(optional = true) Object arg)
protected void handleClose(@NonNull KrollDict options)
{
if (opened) {
opened = false;
popToRootWindow(arg);
closeWindow(windows.get(0), arg); // close the root window
popToRootWindow(options);
closeWindow(windows.get(0), options); // close the root window
fireEvent(TiC.EVENT_CLOSE, null);
if (closePromise != null) {
closePromise.resolve(null);
closePromise = null;
}
}
super.close(arg);
super.handleClose(options);
}

@Kroll.method
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2013 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2013-2021 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
Expand All @@ -11,6 +11,7 @@
import java.util.HashMap;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollPromise;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.TiActivity;
Expand Down Expand Up @@ -105,7 +106,7 @@ public TiUIView createView(Activity activity)
}

@Override
public void open(@Kroll.argument(optional = true) Object arg)
public KrollPromise<Void> open(@Kroll.argument(optional = true) Object arg)
{
HashMap<String, Object> option = null;
if (arg instanceof HashMap) {
Expand All @@ -127,16 +128,7 @@ public void open(@Kroll.argument(optional = true) Object arg)
properties.remove(TiC.PROPERTY_BOTTOM);
properties.remove(TiC.PROPERTY_LEFT);
properties.remove(TiC.PROPERTY_RIGHT);
super.open(arg);
}

@Override
public void close(@Kroll.argument(optional = true) Object arg)
{
if (!(opened || opening)) {
return;
}
super.close(arg);
return super.open(arg);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2013 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2009-2021 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
Expand All @@ -12,6 +12,7 @@
import java.util.List;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollPromise;
import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
Expand Down Expand Up @@ -72,6 +73,8 @@ public abstract class TiWindowProxy extends TiViewProxy
protected boolean windowActivityCreated = false;
protected List<Pair<View, String>> sharedElementPairs;
public TiWindowProxy navigationWindow;
protected KrollPromise openPromise;
protected KrollPromise closePromise;

public interface PostOpenListener {
void onPostOpen(TiWindowProxy window);
Expand All @@ -98,34 +101,39 @@ public TiUIView createView(Activity activity)

@Kroll.method
@SuppressWarnings("unchecked")
public void open(@Kroll.argument(optional = true) Object arg)
public KrollPromise<Void> open(@Kroll.argument(optional = true) Object arg)
{
if (opened || opening) {
return;
return KrollPromise.create((promise) -> {
promise.reject(new Throwable("Window is already opened or opening."));
});
}

waitingForOpen = new WeakReference<TiWindowProxy>(this);
opening = true;
KrollDict options = null;
TiAnimation animation = null;
waitingForOpen = new WeakReference<TiWindowProxy>(this);

openPromise = KrollPromise.create((promise) -> {
KrollDict options = null;
TiAnimation animation = null;

if (arg != null) {
if (arg instanceof KrollDict) {
options = (KrollDict) arg;
if (arg != null) {
if (arg instanceof KrollDict) {
options = (KrollDict) arg;

} else if (arg instanceof HashMap<?, ?>) {
options = new KrollDict((HashMap<String, Object>) arg);
} else if (arg instanceof HashMap<?, ?>) {
options = new KrollDict((HashMap<String, Object>) arg);

} else if (arg instanceof TiAnimation) {
} else if (arg instanceof TiAnimation) {
options = new KrollDict();
options.put("_anim", animation);
}

} else {
options = new KrollDict();
options.put("_anim", animation);
}

} else {
options = new KrollDict();
}

handleOpen(options);
handleOpen(options);
});
return openPromise;
}

@Kroll.getProperty(name = "closed")
Expand All @@ -142,27 +150,36 @@ public boolean isFocused()

@SuppressWarnings("unchecked")
@Kroll.method
public void close(@Kroll.argument(optional = true) Object arg)
public KrollPromise<Void> close(@Kroll.argument(optional = true) Object arg)
{
// TODO: if not opened, ignore? We do this in WindowProxy subclass, but not the other two...
KrollDict options = null;
TiAnimation animation = null;
if (!(opened || opening)) {
return KrollPromise.create((promise) -> {
promise.reject(new Throwable("Window is not open or opening, so cannot be closed."));
});
}

// FIXME: Can we "cancel" the open() promise if it's not finished?
closePromise = KrollPromise.create((promise) -> {
KrollDict options = null;
TiAnimation animation = null;

if (arg != null) {
if (arg instanceof HashMap<?, ?>) {
options = new KrollDict((HashMap<String, Object>) arg);
if (arg != null) {
if (arg instanceof HashMap<?, ?>) {
options = new KrollDict((HashMap<String, Object>) arg);

} else if (arg instanceof TiAnimation) {
} else if (arg instanceof TiAnimation) {
options = new KrollDict();
options.put("_anim", animation);
}

} else {
options = new KrollDict();
options.put("_anim", animation);
}

} else {
options = new KrollDict();
}

handleClose(options);
// FIXME: Maybe fire the close event here and set opened to false as well, rather than leaving to subclasses?
handleClose(options);
// FIXME: Maybe fire the close event here and set opened to false as well, rather than leaving to subclasses?
});
return closePromise;
}

public void closeFromActivity(boolean activityIsFinishing)
Expand All @@ -189,6 +206,10 @@ public void closeFromActivity(boolean activityIsFinishing)
// And it will dispose the handler of the window in the JS if the activity
// is not forced to destroy.
fireSyncEvent(TiC.EVENT_CLOSE, data);
if (closePromise != null) {
closePromise.resolve(null);
closePromise = null; // FIXME: call release() first?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this cleanup could be moved to release()

@Override
public void release()
{
	if (openPromise != null) {
		openPromise = null;
	}
	if (closePromise != null) {
		closePromise = null;
	}

	super.release();
}

}
}

public void addProxyWaitingForActivity(KrollProxy waitingProxy)
Expand Down Expand Up @@ -505,6 +526,11 @@ public void run()
if (nativeView != null) {
nativeView.postInvalidate();
}

if (openPromise != null) {
openPromise.resolve(null);
openPromise = null;
}
}

protected void fillIntent(Activity activity, Intent intent)
Expand Down
12 changes: 12 additions & 0 deletions apidoc/Titanium/UI/Window.yml
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,12 @@ methods:
summary: Animation or display properties to use when closing the window.
type: [Titanium.UI.Animation, Dictionary<Titanium.UI.Animation>, closeWindowParams]
optional: true
returns:
type: Promise<any>
summary: |
Starting in SDK 10.0.0, this method returns a `Promise` that will be resolved once the window is closed,
akin to adding a one-time listener for the `close` event. If the window fails to close (for example, because
it was not yet open) the `Promise` will be rejected.

- name: hideNavBar
summary: Hides the navigation bar.
Expand Down Expand Up @@ -509,6 +515,12 @@ methods:
summary: Animation or display properties to use when opening the window.
type: openWindowParams
optional: true
returns:
type: Promise<any>
summary: |
Starting in SDK 10.0.0, this method returns a `Promise` that will be resolved once the window is opened,
akin to adding a one-time listener for the `open` event. If the window fails to open (for example, because
it is already opened or opening) the `Promise` will be rejected.

- name: removeAllSharedElements
summary: Clears all added shared elements.
Expand Down
5 changes: 3 additions & 2 deletions common/Resources/ti.internal/extensions/ti/ui/tabgroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ if (OS_ANDROID) {
TabGroup.prototype.open = function (options) {

if (this.currentState === this.state.opened) {
return;
return Promise.reject(new Error('Window is already opened or opening.'));
}

this.currentState = this.state.opening;
Expand Down Expand Up @@ -104,9 +104,10 @@ if (OS_ANDROID) {
if (this._activeTab !== -1) {
this.setActiveTab(this._activeTab);
}
_open.call(this, options);
const result = _open.call(this, options);

this.currentState = this.state.opened;
return result;
};

const _addTab = TabGroup.prototype.addTab;
Expand Down
2 changes: 1 addition & 1 deletion common/Resources/ti.internal/extensions/ti/ui/window.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ if (OS_ANDROID) {
}
});

_open.call(this, options);
return _open.call(this, options);
};

const _add = Window.prototype.add;
Expand Down