add: logout button on drawer menu
This commit is contained in:
@@ -1 +1 @@
|
|||||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":34},"path":"inrt-release.apk","properties":{"packageId":"com.stardust.auojs.inrt","split":"","minSdkVersion":"17"}}]
|
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":239},"path":"release-3.0.0 Alpha39.apk","properties":{"packageId":"com.stardust.scriptdroid","split":"","minSdkVersion":"17"}}]
|
||||||
@@ -95,11 +95,6 @@
|
|||||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name="com.stardust.autojs.core.image.ScreenCaptureRequestActivity"
|
|
||||||
android:excludeFromRecents="true"
|
|
||||||
android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
|
|
||||||
android:theme="@style/AppTheme.Transparent"/>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.error.IssueReporterActivity"
|
android:name=".ui.error.IssueReporterActivity"
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ public class NodeBB {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void invalidateConfig() {
|
||||||
|
mConfig = null;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getErrorMessage(Throwable e, Context context, String defaultMsg) {
|
public static String getErrorMessage(Throwable e, Context context, String defaultMsg) {
|
||||||
if (!(e instanceof HttpException)) {
|
if (!(e instanceof HttpException)) {
|
||||||
return defaultMsg;
|
return defaultMsg;
|
||||||
@@ -75,7 +79,7 @@ public class NodeBB {
|
|||||||
if (body == null)
|
if (body == null)
|
||||||
return defaultMsg;
|
return defaultMsg;
|
||||||
try {
|
try {
|
||||||
String errorMessage = getErrorMessage(context, e, body.string());
|
String errorMessage = getErrorMessage(context, httpException, body.string());
|
||||||
return errorMessage == null ? defaultMsg : errorMessage;
|
return errorMessage == null ? defaultMsg : errorMessage;
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
@@ -83,7 +87,7 @@ public class NodeBB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getErrorMessage(Context context, Throwable error, String errorBody) {
|
private static String getErrorMessage(Context context, HttpException error, String errorBody) {
|
||||||
if (errorBody == null)
|
if (errorBody == null)
|
||||||
return null;
|
return null;
|
||||||
if (errorBody.contains("invalid-login-credentials")) {
|
if (errorBody.contains("invalid-login-credentials")) {
|
||||||
@@ -99,6 +103,9 @@ public class NodeBB {
|
|||||||
if (errorBody.contains("email-taken")) {
|
if (errorBody.contains("email-taken")) {
|
||||||
return context.getString(R.string.nodebb_error_email_taken);
|
return context.getString(R.string.nodebb_error_email_taken);
|
||||||
}
|
}
|
||||||
|
if (error.code() == 403) {
|
||||||
|
return context.getString(R.string.nodebb_error_forbidden);
|
||||||
|
}
|
||||||
Log.d(LOG_TAG, "unknown error: " + errorBody, error);
|
Log.d(LOG_TAG, "unknown error: " + errorBody, error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
package com.stardust.scriptdroid.network;
|
package com.stardust.scriptdroid.network;
|
||||||
|
|
||||||
import android.util.Log;
|
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
|
||||||
|
|
||||||
import com.stardust.scriptdroid.network.api.ConfigApi;
|
|
||||||
import com.stardust.scriptdroid.network.api.UserApi;
|
import com.stardust.scriptdroid.network.api.UserApi;
|
||||||
|
import com.stardust.scriptdroid.network.entity.user.User;
|
||||||
|
import com.stardust.util.Objects;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import io.reactivex.subjects.PublishSubject;
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
import retrofit2.Retrofit;
|
import retrofit2.Retrofit;
|
||||||
|
|
||||||
@@ -17,8 +22,22 @@ import retrofit2.Retrofit;
|
|||||||
|
|
||||||
public class UserService {
|
public class UserService {
|
||||||
|
|
||||||
|
|
||||||
|
public static class LoginStateChange {
|
||||||
|
private final boolean mOnline;
|
||||||
|
|
||||||
|
public LoginStateChange(boolean online) {
|
||||||
|
mOnline = online;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnline() {
|
||||||
|
return mOnline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final UserService sInstance = new UserService();
|
private static final UserService sInstance = new UserService();
|
||||||
private final Retrofit mRetrofit;
|
private final Retrofit mRetrofit;
|
||||||
|
private volatile User mUser;
|
||||||
|
|
||||||
UserService() {
|
UserService() {
|
||||||
mRetrofit = NodeBB.getInstance().getRetrofit();
|
mRetrofit = NodeBB.getInstance().getRetrofit();
|
||||||
@@ -31,14 +50,20 @@ public class UserService {
|
|||||||
public Observable<ResponseBody> login(String userName, final String password) {
|
public Observable<ResponseBody> login(String userName, final String password) {
|
||||||
return NodeBB.getInstance()
|
return NodeBB.getInstance()
|
||||||
.getConfig()
|
.getConfig()
|
||||||
.flatMap(config -> {
|
.flatMap(config ->
|
||||||
return mRetrofit.create(UserApi.class)
|
mRetrofit.create(UserApi.class)
|
||||||
.login(Collections.singletonMap("x-csrf-token", config.getCsrfToken()),
|
.login(Collections.singletonMap("x-csrf-token", config.getCsrfToken()),
|
||||||
userName, password);
|
userName, password)
|
||||||
});
|
.doOnError(error -> {
|
||||||
|
if (error instanceof HttpException && ((HttpException) error).code() == 403) {
|
||||||
|
NodeBB.getInstance().invalidateConfig();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.doOnComplete(this::refreshOnlineStatus);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Observable<ResponseBody> register(String email, String userName, String password) {
|
public Observable<ResponseBody> register(String email, String userName, String password) {
|
||||||
return NodeBB.getInstance()
|
return NodeBB.getInstance()
|
||||||
.getConfig()
|
.getConfig()
|
||||||
@@ -46,4 +71,55 @@ public class UserService {
|
|||||||
.register(Collections.singletonMap("x-csrf-token", config.getCsrfToken()),
|
.register(Collections.singletonMap("x-csrf-token", config.getCsrfToken()),
|
||||||
email, userName, password, password));
|
email, userName, password, password));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOnline() {
|
||||||
|
return mUser != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUser(User user) {
|
||||||
|
User old = mUser;
|
||||||
|
mUser = user;
|
||||||
|
if (!Objects.equals(old, mUser)) {
|
||||||
|
if (user == null) {
|
||||||
|
NodeBB.getInstance().invalidateConfig();
|
||||||
|
}
|
||||||
|
EventBus.getDefault().post(new LoginStateChange(user != null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Boolean> refreshOnlineStatus() {
|
||||||
|
PublishSubject<Boolean> online = PublishSubject.create();
|
||||||
|
mRetrofit.create(UserApi.class)
|
||||||
|
.me()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.subscribe(user -> {
|
||||||
|
setUser(user);
|
||||||
|
online.onNext(true);
|
||||||
|
online.onComplete();
|
||||||
|
}, error -> {
|
||||||
|
setUser(null);
|
||||||
|
online.onNext(false);
|
||||||
|
online.onComplete();
|
||||||
|
});
|
||||||
|
return online;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<ResponseBody> logout() {
|
||||||
|
return NodeBB.getInstance()
|
||||||
|
.getConfig()
|
||||||
|
.flatMap(config ->
|
||||||
|
mRetrofit.create(UserApi.class)
|
||||||
|
.logout(Collections.singletonMap("x-csrf-token", config.getCsrfToken()))
|
||||||
|
)
|
||||||
|
.doOnError(Throwable::printStackTrace)
|
||||||
|
.doOnComplete(this::refreshOnlineStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<User> me() {
|
||||||
|
return NodeBB.getInstance().getRetrofit()
|
||||||
|
.create(UserApi.class)
|
||||||
|
.me()
|
||||||
|
.doOnNext(this::setUser)
|
||||||
|
.doOnError(error -> setUser(null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,4 +31,6 @@ public interface UserApi {
|
|||||||
@Field("username") String userName, @Field("password") String password, @Field("password-confirm") String repeatPassword);
|
@Field("username") String userName, @Field("password") String password, @Field("password-confirm") String repeatPassword);
|
||||||
|
|
||||||
|
|
||||||
|
@POST("/logout")
|
||||||
|
Observable<ResponseBody> logout(@HeaderMap Map<String, String> csrfToken);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
|||||||
package com.stardust.scriptdroid.ui.main.drawer;
|
package com.stardust.scriptdroid.ui.main.drawer;
|
||||||
|
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
|
import com.stardust.scriptdroid.network.UserService;
|
||||||
import com.stardust.scriptdroid.ui.main.community.CommunityFragment;
|
import com.stardust.scriptdroid.ui.main.community.CommunityFragment;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
@@ -9,46 +10,105 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/12/10.
|
* Created by Stardust on 2017/12/10.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class CommunityDrawerMenu {
|
public class CommunityDrawerMenu {
|
||||||
|
|
||||||
|
private DrawerMenuItem mUnreadItem = new DrawerMenuItem(R.drawable.community_inbox, R.string.text_community_unread, this::showUnread);
|
||||||
|
private DrawerMenuItem mLogoutItem = new DrawerMenuItem(R.drawable.ic_exit_to_app_black_24dp, R.string.text_logout, this::logout);
|
||||||
|
|
||||||
|
|
||||||
private List<DrawerMenuItem> mDrawerMenuItems = new ArrayList<>(Arrays.asList(
|
private List<DrawerMenuItem> mDrawerMenuItems = new ArrayList<>(Arrays.asList(
|
||||||
new DrawerMenuGroup(R.string.text_community),
|
new DrawerMenuGroup(R.string.text_community),
|
||||||
new DrawerMenuItem(R.drawable.community_list, R.string.text_community_category, this::showCategories),
|
new DrawerMenuItem(R.drawable.community_list, R.string.text_community_category, this::showCategories),
|
||||||
new DrawerMenuItem(R.drawable.community_inbox, R.string.text_community_unread, this::showUnread),
|
mUnreadItem,
|
||||||
new DrawerMenuItem(R.drawable.community_time, R.string.text_community_recent, this::showRecent),
|
new DrawerMenuItem(R.drawable.community_time, R.string.text_community_recent, this::showRecent),
|
||||||
new DrawerMenuItem(R.drawable.community_fire, R.string.text_community_popular, this::showPopular),
|
new DrawerMenuItem(R.drawable.community_fire, R.string.text_community_popular, this::showPopular),
|
||||||
new DrawerMenuItem(R.drawable.community_tags, R.string.text_community_tags, this::showTags)
|
new DrawerMenuItem(R.drawable.community_tags, R.string.text_community_tags, this::showTags),
|
||||||
|
mLogoutItem
|
||||||
));
|
));
|
||||||
|
|
||||||
private boolean mShown = false;
|
private boolean mShown = false;
|
||||||
|
|
||||||
public List<DrawerMenuItem> getItems() {
|
|
||||||
return mDrawerMenuItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showCommunityMenu(DrawerMenuAdapter adapter) {
|
public void showCommunityMenu(DrawerMenuAdapter adapter) {
|
||||||
|
mShown = true;
|
||||||
List<DrawerMenuItem> items = adapter.getDrawerMenuItems();
|
List<DrawerMenuItem> items = adapter.getDrawerMenuItems();
|
||||||
if (items.get(0) == mDrawerMenuItems.get(0)) {
|
if (items.get(0) == mDrawerMenuItems.get(0)) {
|
||||||
|
refreshUserStatus(adapter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
items.addAll(0, mDrawerMenuItems);
|
items.addAll(0, mDrawerMenuItems);
|
||||||
adapter.notifyItemRangeInserted(0, mDrawerMenuItems.size());
|
adapter.notifyItemRangeInserted(0, mDrawerMenuItems.size());
|
||||||
adapter.notifyItemChanged(mDrawerMenuItems.size());
|
adapter.notifyItemChanged(mDrawerMenuItems.size());
|
||||||
|
refreshUserStatus(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshUserStatus(DrawerMenuAdapter adapter) {
|
||||||
|
UserService.getInstance().refreshOnlineStatus()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(online -> setUserOnlineStatus(adapter, online));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserOnlineStatus(DrawerMenuAdapter adapter, boolean online) {
|
||||||
|
if (online) {
|
||||||
|
addItem(adapter, R.string.text_community_category, mUnreadItem);
|
||||||
|
addItem(adapter, R.string.text_community_tags, mLogoutItem);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
removeItem(adapter, R.string.text_community_unread);
|
||||||
|
removeItem(adapter, R.string.text_logout);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addItem(DrawerMenuAdapter adapter, int title, DrawerMenuItem itemToAdd) {
|
||||||
|
List<DrawerMenuItem> items = adapter.getDrawerMenuItems();
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
DrawerMenuItem item = items.get(i);
|
||||||
|
if (item.getTitle() == title) {
|
||||||
|
if (i >= items.size() || items.get(i + 1) != itemToAdd) {
|
||||||
|
items.add(i + 1, itemToAdd);
|
||||||
|
adapter.notifyItemInserted(i + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeItem(DrawerMenuAdapter adapter, int title) {
|
||||||
|
List<DrawerMenuItem> items = adapter.getDrawerMenuItems();
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
DrawerMenuItem item = items.get(i);
|
||||||
|
if (item.getTitle() == title) {
|
||||||
|
items.remove(i);
|
||||||
|
adapter.notifyItemRemoved(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideCommunityMenu(DrawerMenuAdapter adapter) {
|
public void hideCommunityMenu(DrawerMenuAdapter adapter) {
|
||||||
List<DrawerMenuItem> items = adapter.getDrawerMenuItems();
|
List<DrawerMenuItem> items = adapter.getDrawerMenuItems();
|
||||||
|
mShown = false;
|
||||||
if (items.isEmpty() || items.get(0) != mDrawerMenuItems.get(0)) {
|
if (items.isEmpty() || items.get(0) != mDrawerMenuItems.get(0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
items.subList(0, mDrawerMenuItems.size()).clear();
|
for (int i = 1; i < items.size(); i++) {
|
||||||
adapter.notifyItemChanged(mDrawerMenuItems.size());
|
DrawerMenuItem item = items.get(i);
|
||||||
adapter.notifyItemRangeRemoved(0, mDrawerMenuItems.size());
|
if (item instanceof DrawerMenuGroup) {
|
||||||
|
items.subList(0, i).clear();
|
||||||
|
adapter.notifyItemRangeRemoved(0, i);
|
||||||
|
adapter.notifyItemChanged(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showCategories(DrawerMenuItemViewHolder holder) {
|
private void showCategories(DrawerMenuItemViewHolder holder) {
|
||||||
@@ -76,4 +136,14 @@ public class CommunityDrawerMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void logout(DrawerMenuItemViewHolder holder) {
|
||||||
|
UserService.getInstance().logout()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.subscribe();
|
||||||
|
EventBus.getDefault().post(new CommunityFragment.LoadUrl("/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShown() {
|
||||||
|
return mShown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.stardust.scriptdroid.App;
|
|||||||
import com.stardust.scriptdroid.Pref;
|
import com.stardust.scriptdroid.Pref;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.network.GlideApp;
|
import com.stardust.scriptdroid.network.GlideApp;
|
||||||
|
import com.stardust.scriptdroid.network.UserService;
|
||||||
import com.stardust.scriptdroid.pluginclient.DevPluginClient;
|
import com.stardust.scriptdroid.pluginclient.DevPluginClient;
|
||||||
import com.stardust.scriptdroid.ui.floating.CircularMenu;
|
import com.stardust.scriptdroid.ui.floating.CircularMenu;
|
||||||
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;
|
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;
|
||||||
@@ -52,6 +53,7 @@ import org.androidannotations.annotations.EFragment;
|
|||||||
import org.androidannotations.annotations.ViewById;
|
import org.androidannotations.annotations.ViewById;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -147,8 +149,7 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
|
|||||||
|
|
||||||
@Click(R.id.avatar)
|
@Click(R.id.avatar)
|
||||||
void loginOrShowUserInfo() {
|
void loginOrShowUserInfo() {
|
||||||
NodeBB.getInstance().getRetrofit()
|
UserService.getInstance()
|
||||||
.create(UserApi.class)
|
|
||||||
.me()
|
.me()
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
@@ -368,6 +369,13 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
|
|||||||
mDrawerMenu.scrollToPosition(0);
|
mDrawerMenu.scrollToPosition(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
public void onLoginStateChange(UserService.LoginStateChange change) {
|
||||||
|
syncUserInfo();
|
||||||
|
if (mCommunityDrawerMenu.isShown()) {
|
||||||
|
mCommunityDrawerMenu.setUserOnlineStatus(mDrawerMenuAdapter, change.isOnline());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ package com.stardust.scriptdroid.ui.main.drawer;
|
|||||||
|
|
||||||
public class DrawerMenuGroup extends DrawerMenuItem {
|
public class DrawerMenuGroup extends DrawerMenuItem {
|
||||||
|
|
||||||
|
|
||||||
public DrawerMenuGroup(int title) {
|
public DrawerMenuGroup(int title) {
|
||||||
super(0, title, null);
|
super(0, title, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,4 +77,19 @@ public class DrawerMenuItem {
|
|||||||
if (mAction != null)
|
if (mAction != null)
|
||||||
mAction.onClick(holder);
|
mAction.onClick(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
DrawerMenuItem that = (DrawerMenuItem) o;
|
||||||
|
|
||||||
|
return mTitle == that.mTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return mTitle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
app/src/main/res/drawable-hdpi/ic_exit_to_app_black_24dp.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_exit_to_app_black_24dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 251 B |
BIN
app/src/main/res/drawable-mdpi/ic_exit_to_app_black_24dp.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_exit_to_app_black_24dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 171 B |
BIN
app/src/main/res/drawable-xhdpi/ic_exit_to_app_black_24dp.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_exit_to_app_black_24dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 246 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_exit_to_app_black_24dp.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_exit_to_app_black_24dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 354 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_black_24dp.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_black_24dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 432 B |
@@ -336,4 +336,6 @@
|
|||||||
<string name="nodebb_error_change_password_error_length">密码太短</string>
|
<string name="nodebb_error_change_password_error_length">密码太短</string>
|
||||||
<string name="nodebb_error_email_taken">邮箱已被占用</string>
|
<string name="nodebb_error_email_taken">邮箱已被占用</string>
|
||||||
<string name="nodebb_error_change_password_error_match">两次输入的密码不一致</string>
|
<string name="nodebb_error_change_password_error_match">两次输入的密码不一致</string>
|
||||||
|
<string name="text_logout">退出登录</string>
|
||||||
|
<string name="nodebb_error_forbidden">操作失败,请稍后重试</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,6 +15,12 @@
|
|||||||
android:name=".execution.ScriptExecuteActivity"
|
android:name=".execution.ScriptExecuteActivity"
|
||||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.stardust.autojs.core.image.ScreenCaptureRequestActivity"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
|
||||||
|
android:theme="@style/AppTheme.Transparent"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import android.graphics.Bitmap;
|
|||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.ImageFormat;
|
import android.graphics.ImageFormat;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.Xfermode;
|
||||||
import android.media.Image;
|
import android.media.Image;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.annotation.RequiresApi;
|
import android.support.annotation.RequiresApi;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.app.Activity;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.media.Image;
|
import android.media.Image;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|||||||
@@ -13,6 +13,16 @@
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<style name="AppTheme.Transparent" parent="AppTheme">
|
||||||
|
<item name="android:windowIsTranslucent">true</item>
|
||||||
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
<item name="android:windowIsFloating">true</item>
|
||||||
|
<item name="android:backgroundDimEnabled">false</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<color name="colorPrimary">#009688</color>
|
<color name="colorPrimary">#009688</color>
|
||||||
<color name="colorPrimaryDark">#009688</color>
|
<color name="colorPrimaryDark">#009688</color>
|
||||||
<color name="colorAccent">#03a9f4</color>
|
<color name="colorAccent">#03a9f4</color>
|
||||||
|
|||||||
27
common/src/main/java/com/stardust/util/Objects.java
Normal file
27
common/src/main/java/com/stardust/util/Objects.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package com.stardust.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/31.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Objects {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if the arguments are equal to each other
|
||||||
|
* and {@code false} otherwise.
|
||||||
|
* Consequently, if both arguments are {@code null}, {@code true}
|
||||||
|
* is returned and if exactly one argument is {@code null}, {@code
|
||||||
|
* false} is returned. Otherwise, equality is determined by using
|
||||||
|
* the {@link Object#equals equals} method of the first
|
||||||
|
* argument.
|
||||||
|
*
|
||||||
|
* @param a an object
|
||||||
|
* @param b an object to be compared with {@code a} for equality
|
||||||
|
* @return {@code true} if the arguments are equal to each other
|
||||||
|
* and {@code false} otherwise
|
||||||
|
* @see Object#equals(Object)
|
||||||
|
*/
|
||||||
|
public static boolean equals(Object a, Object b) {
|
||||||
|
return (a == b) || (a != null && a.equals(b));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user