add: logout button on drawer menu

This commit is contained in:
hyb1996
2017-12-31 17:56:35 +08:00
parent 002a11149e
commit 5ed6e2bea8
21 changed files with 839 additions and 607 deletions

View File

@@ -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"}}]

View File

@@ -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"

View File

@@ -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;
} }

View File

@@ -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));
}
} }

View File

@@ -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);
} }

View File

@@ -1,9 +1,11 @@
package com.stardust.scriptdroid.network.entity.user; package com.stardust.scriptdroid.network.entity.user;
import java.util.List; import java.util.List;
import com.google.gson.annotations.SerializedName;
public class User{ import com.google.gson.annotations.SerializedName;
import com.stardust.util.Objects;
public class User {
@SerializedName("websiteLink") @SerializedName("websiteLink")
private String websiteLink; private String websiteLink;
@@ -188,496 +190,496 @@ public class User{
@SerializedName("username") @SerializedName("username")
private String username; private String username;
public void setWebsiteLink(String websiteLink){ public void setWebsiteLink(String websiteLink) {
this.websiteLink = websiteLink; this.websiteLink = websiteLink;
} }
public String getWebsiteLink(){ public String getWebsiteLink() {
return websiteLink; return websiteLink;
} }
public void setReputation(String reputation){ public void setReputation(String reputation) {
this.reputation = reputation; this.reputation = reputation;
} }
public String getReputation(){ public String getReputation() {
return reputation; return reputation;
} }
public void setSso(List<Object> sso){ public void setSso(List<Object> sso) {
this.sso = sso; this.sso = sso;
} }
public List<Object> getSso(){ public List<Object> getSso() {
return sso; return sso;
} }
public void setIconText(String iconText){ public void setIconText(String iconText) {
this.iconText = iconText; this.iconText = iconText;
} }
public String getIconText(){ public String getIconText() {
return iconText; return iconText;
} }
public void setIsGlobalModerator(boolean isGlobalModerator){ public void setIsGlobalModerator(boolean isGlobalModerator) {
this.isGlobalModerator = isGlobalModerator; this.isGlobalModerator = isGlobalModerator;
} }
public boolean isIsGlobalModerator(){ public boolean isIsGlobalModerator() {
return isGlobalModerator; return isGlobalModerator;
} }
public void setJoindate(String joindate){ public void setJoindate(String joindate) {
this.joindate = joindate; this.joindate = joindate;
} }
public String getJoindate(){ public String getJoindate() {
return joindate; return joindate;
} }
public void setProfileLinks(List<Object> profileLinks){ public void setProfileLinks(List<Object> profileLinks) {
this.profileLinks = profileLinks; this.profileLinks = profileLinks;
} }
public List<Object> getProfileLinks(){ public List<Object> getProfileLinks() {
return profileLinks; return profileLinks;
} }
public void setReputationDisabled(boolean reputationDisabled){ public void setReputationDisabled(boolean reputationDisabled) {
this.reputationDisabled = reputationDisabled; this.reputationDisabled = reputationDisabled;
} }
public boolean isReputationDisabled(){ public boolean isReputationDisabled() {
return reputationDisabled; return reputationDisabled;
} }
public void setIsAdmin(boolean isAdmin){ public void setIsAdmin(boolean isAdmin) {
this.isAdmin = isAdmin; this.isAdmin = isAdmin;
} }
public boolean isIsAdmin(){ public boolean isIsAdmin() {
return isAdmin; return isAdmin;
} }
public void setModerationNote(String moderationNote){ public void setModerationNote(String moderationNote) {
this.moderationNote = moderationNote; this.moderationNote = moderationNote;
} }
public String getModerationNote(){ public String getModerationNote() {
return moderationNote; return moderationNote;
} }
public void setIps(List<String> ips){ public void setIps(List<String> ips) {
this.ips = ips; this.ips = ips;
} }
public List<String> getIps(){ public List<String> getIps() {
return ips; return ips;
} }
public void setAboutme(String aboutme){ public void setAboutme(String aboutme) {
this.aboutme = aboutme; this.aboutme = aboutme;
} }
public String getAboutme(){ public String getAboutme() {
return aboutme; return aboutme;
} }
public void setIsTargetAdmin(boolean isTargetAdmin){ public void setIsTargetAdmin(boolean isTargetAdmin) {
this.isTargetAdmin = isTargetAdmin; this.isTargetAdmin = isTargetAdmin;
} }
public boolean isIsTargetAdmin(){ public boolean isIsTargetAdmin() {
return isTargetAdmin; return isTargetAdmin;
} }
public void setEmailConfirmed(boolean emailConfirmed){ public void setEmailConfirmed(boolean emailConfirmed) {
this.emailConfirmed = emailConfirmed; this.emailConfirmed = emailConfirmed;
} }
public boolean isEmailConfirmed(){ public boolean isEmailConfirmed() {
return emailConfirmed; return emailConfirmed;
} }
public void setIsAdminOrGlobalModerator(boolean isAdminOrGlobalModerator){ public void setIsAdminOrGlobalModerator(boolean isAdminOrGlobalModerator) {
this.isAdminOrGlobalModerator = isAdminOrGlobalModerator; this.isAdminOrGlobalModerator = isAdminOrGlobalModerator;
} }
public boolean isIsAdminOrGlobalModerator(){ public boolean isIsAdminOrGlobalModerator() {
return isAdminOrGlobalModerator; return isAdminOrGlobalModerator;
} }
public void setEmailClass(String emailClass){ public void setEmailClass(String emailClass) {
this.emailClass = emailClass; this.emailClass = emailClass;
} }
public String getEmailClass(){ public String getEmailClass() {
return emailClass; return emailClass;
} }
public void setDownvoteDisabled(boolean downvoteDisabled){ public void setDownvoteDisabled(boolean downvoteDisabled) {
this.downvoteDisabled = downvoteDisabled; this.downvoteDisabled = downvoteDisabled;
} }
public boolean isDownvoteDisabled(){ public boolean isDownvoteDisabled() {
return downvoteDisabled; return downvoteDisabled;
} }
public void setTopiccount(String topiccount){ public void setTopiccount(String topiccount) {
this.topiccount = topiccount; this.topiccount = topiccount;
} }
public String getTopiccount(){ public String getTopiccount() {
return topiccount; return topiccount;
} }
public void setIsSelf(boolean isSelf){ public void setIsSelf(boolean isSelf) {
this.isSelf = isSelf; this.isSelf = isSelf;
} }
public boolean isIsSelf(){ public boolean isIsSelf() {
return isSelf; return isSelf;
} }
public void setStatus(String status){ public void setStatus(String status) {
this.status = status; this.status = status;
} }
public String getStatus(){ public String getStatus() {
return status; return status;
} }
public void setBirthday(String birthday){ public void setBirthday(String birthday) {
this.birthday = birthday; this.birthday = birthday;
} }
public String getBirthday(){ public String getBirthday() {
return birthday; return birthday;
} }
public void setShowHidden(boolean showHidden){ public void setShowHidden(boolean showHidden) {
this.showHidden = showHidden; this.showHidden = showHidden;
} }
public boolean isShowHidden(){ public boolean isShowHidden() {
return showHidden; return showHidden;
} }
public void setYourid(int yourid){ public void setYourid(int yourid) {
this.yourid = yourid; this.yourid = yourid;
} }
public int getYourid(){ public int getYourid() {
return yourid; return yourid;
} }
public void setLastposttime(String lastposttime){ public void setLastposttime(String lastposttime) {
this.lastposttime = lastposttime; this.lastposttime = lastposttime;
} }
public String getLastposttime(){ public String getLastposttime() {
return lastposttime; return lastposttime;
} }
public void setIsModerator(boolean isModerator){ public void setIsModerator(boolean isModerator) {
this.isModerator = isModerator; this.isModerator = isModerator;
} }
public boolean isIsModerator(){ public boolean isIsModerator() {
return isModerator; return isModerator;
} }
public void setSignature(String signature){ public void setSignature(String signature) {
this.signature = signature; this.signature = signature;
} }
public String getSignature(){ public String getSignature() {
return signature; return signature;
} }
public void setIconBgColor(String iconBgColor){ public void setIconBgColor(String iconBgColor) {
this.iconBgColor = iconBgColor; this.iconBgColor = iconBgColor;
} }
public String getIconBgColor(){ public String getIconBgColor() {
return iconBgColor; return iconBgColor;
} }
public void setCanEdit(boolean canEdit){ public void setCanEdit(boolean canEdit) {
this.canEdit = canEdit; this.canEdit = canEdit;
} }
public boolean isCanEdit(){ public boolean isCanEdit() {
return canEdit; return canEdit;
} }
public void setGroupTitle(String groupTitle){ public void setGroupTitle(String groupTitle) {
this.groupTitle = groupTitle; this.groupTitle = groupTitle;
} }
public String getGroupTitle(){ public String getGroupTitle() {
return groupTitle; return groupTitle;
} }
public void setFollowingCount(int followingCount){ public void setFollowingCount(int followingCount) {
this.followingCount = followingCount; this.followingCount = followingCount;
} }
public int getFollowingCount(){ public int getFollowingCount() {
return followingCount; return followingCount;
} }
public void setLastonlineISO(String lastonlineISO){ public void setLastonlineISO(String lastonlineISO) {
this.lastonlineISO = lastonlineISO; this.lastonlineISO = lastonlineISO;
} }
public String getLastonlineISO(){ public String getLastonlineISO() {
return lastonlineISO; return lastonlineISO;
} }
public void setEmailDisableEdit(boolean emailDisableEdit){ public void setEmailDisableEdit(boolean emailDisableEdit) {
this.emailDisableEdit = emailDisableEdit; this.emailDisableEdit = emailDisableEdit;
} }
public boolean isEmailDisableEdit(){ public boolean isEmailDisableEdit() {
return emailDisableEdit; return emailDisableEdit;
} }
public void setUid(String uid){ public void setUid(String uid) {
this.uid = uid; this.uid = uid;
} }
public String getUid(){ public String getUid() {
return uid; return uid;
} }
public void setCanChangePassword(boolean canChangePassword){ public void setCanChangePassword(boolean canChangePassword) {
this.canChangePassword = canChangePassword; this.canChangePassword = canChangePassword;
} }
public boolean isCanChangePassword(){ public boolean isCanChangePassword() {
return canChangePassword; return canChangePassword;
} }
public void setProfileviews(String profileviews){ public void setProfileviews(String profileviews) {
this.profileviews = profileviews; this.profileviews = profileviews;
} }
public String getProfileviews(){ public String getProfileviews() {
return profileviews; return profileviews;
} }
public void setCoverUrl(String coverUrl){ public void setCoverUrl(String coverUrl) {
this.coverUrl = coverUrl; this.coverUrl = coverUrl;
} }
public String getCoverUrl(){ public String getCoverUrl() {
return coverUrl; return coverUrl;
} }
public void setBanned(boolean banned){ public void setBanned(boolean banned) {
this.banned = banned; this.banned = banned;
} }
public boolean isBanned(){ public boolean isBanned() {
return banned; return banned;
} }
public void setUserslug(String userslug){ public void setUserslug(String userslug) {
this.userslug = userslug; this.userslug = userslug;
} }
public String getUserslug(){ public String getUserslug() {
return userslug; return userslug;
} }
public void setFollowerCount(int followerCount){ public void setFollowerCount(int followerCount) {
this.followerCount = followerCount; this.followerCount = followerCount;
} }
public int getFollowerCount(){ public int getFollowerCount() {
return followerCount; return followerCount;
} }
public void setEmail(String email){ public void setEmail(String email) {
this.email = email; this.email = email;
} }
public String getEmail(){ public String getEmail() {
return email; return email;
} }
public void setWebsite(String website){ public void setWebsite(String website) {
this.website = website; this.website = website;
} }
public String getWebsite(){ public String getWebsite() {
return website; return website;
} }
public void setIsFollowing(boolean isFollowing){ public void setIsFollowing(boolean isFollowing) {
this.isFollowing = isFollowing; this.isFollowing = isFollowing;
} }
public boolean isIsFollowing(){ public boolean isIsFollowing() {
return isFollowing; return isFollowing;
} }
public void setUploadedpicture(String uploadedpicture){ public void setUploadedpicture(String uploadedpicture) {
this.uploadedpicture = uploadedpicture; this.uploadedpicture = uploadedpicture;
} }
public String getUploadedpicture(){ public String getUploadedpicture() {
return uploadedpicture; return uploadedpicture;
} }
public void setPasswordExpiry(String passwordExpiry){ public void setPasswordExpiry(String passwordExpiry) {
this.passwordExpiry = passwordExpiry; this.passwordExpiry = passwordExpiry;
} }
public String getPasswordExpiry(){ public String getPasswordExpiry() {
return passwordExpiry; return passwordExpiry;
} }
public void setCanBan(boolean canBan){ public void setCanBan(boolean canBan) {
this.canBan = canBan; this.canBan = canBan;
} }
public boolean isCanBan(){ public boolean isCanBan() {
return canBan; return canBan;
} }
public void setLastonline(String lastonline){ public void setLastonline(String lastonline) {
this.lastonline = lastonline; this.lastonline = lastonline;
} }
public String getLastonline(){ public String getLastonline() {
return lastonline; return lastonline;
} }
public void setDisableSignatures(boolean disableSignatures){ public void setDisableSignatures(boolean disableSignatures) {
this.disableSignatures = disableSignatures; this.disableSignatures = disableSignatures;
} }
public boolean isDisableSignatures(){ public boolean isDisableSignatures() {
return disableSignatures; return disableSignatures;
} }
public void setGroups(List<GroupsItem> groups){ public void setGroups(List<GroupsItem> groups) {
this.groups = groups; this.groups = groups;
} }
public List<GroupsItem> getGroups(){ public List<GroupsItem> getGroups() {
return groups; return groups;
} }
public void setUsernameDisableEdit(boolean usernameDisableEdit){ public void setUsernameDisableEdit(boolean usernameDisableEdit) {
this.usernameDisableEdit = usernameDisableEdit; this.usernameDisableEdit = usernameDisableEdit;
} }
public boolean isUsernameDisableEdit(){ public boolean isUsernameDisableEdit() {
return usernameDisableEdit; return usernameDisableEdit;
} }
public void setPicture(String picture){ public void setPicture(String picture) {
this.picture = picture; this.picture = picture;
} }
public String getPicture(){ public String getPicture() {
return picture; return picture;
} }
public void setJoindateISO(String joindateISO){ public void setJoindateISO(String joindateISO) {
this.joindateISO = joindateISO; this.joindateISO = joindateISO;
} }
public String getJoindateISO(){ public String getJoindateISO() {
return joindateISO; return joindateISO;
} }
public void setIsSelfOrAdminOrGlobalModerator(boolean isSelfOrAdminOrGlobalModerator){ public void setIsSelfOrAdminOrGlobalModerator(boolean isSelfOrAdminOrGlobalModerator) {
this.isSelfOrAdminOrGlobalModerator = isSelfOrAdminOrGlobalModerator; this.isSelfOrAdminOrGlobalModerator = isSelfOrAdminOrGlobalModerator;
} }
public boolean isIsSelfOrAdminOrGlobalModerator(){ public boolean isIsSelfOrAdminOrGlobalModerator() {
return isSelfOrAdminOrGlobalModerator; return isSelfOrAdminOrGlobalModerator;
} }
public void setWebsiteName(String websiteName){ public void setWebsiteName(String websiteName) {
this.websiteName = websiteName; this.websiteName = websiteName;
} }
public String getWebsiteName(){ public String getWebsiteName() {
return websiteName; return websiteName;
} }
public void setIsAdminOrGlobalModeratorOrModerator(boolean isAdminOrGlobalModeratorOrModerator){ public void setIsAdminOrGlobalModeratorOrModerator(boolean isAdminOrGlobalModeratorOrModerator) {
this.isAdminOrGlobalModeratorOrModerator = isAdminOrGlobalModeratorOrModerator; this.isAdminOrGlobalModeratorOrModerator = isAdminOrGlobalModeratorOrModerator;
} }
public boolean isIsAdminOrGlobalModeratorOrModerator(){ public boolean isIsAdminOrGlobalModeratorOrModerator() {
return isAdminOrGlobalModeratorOrModerator; return isAdminOrGlobalModeratorOrModerator;
} }
public void setCoverPosition(String coverPosition){ public void setCoverPosition(String coverPosition) {
this.coverPosition = coverPosition; this.coverPosition = coverPosition;
} }
public String getCoverPosition(){ public String getCoverPosition() {
return coverPosition; return coverPosition;
} }
public void setPostcount(String postcount){ public void setPostcount(String postcount) {
this.postcount = postcount; this.postcount = postcount;
} }
public String getPostcount(){ public String getPostcount() {
return postcount; return postcount;
} }
public void setLocation(String location){ public void setLocation(String location) {
this.location = location; this.location = location;
} }
public String getLocation(){ public String getLocation() {
return location; return location;
} }
public void setFullname(String fullname){ public void setFullname(String fullname) {
this.fullname = fullname; this.fullname = fullname;
} }
public String getFullname(){ public String getFullname() {
return fullname; return fullname;
} }
public void setAge(int age){ public void setAge(int age) {
this.age = age; this.age = age;
} }
public int getAge(){ public int getAge() {
return age; return age;
} }
public void setTheirid(String theirid){ public void setTheirid(String theirid) {
this.theirid = theirid; this.theirid = theirid;
} }
public String getTheirid(){ public String getTheirid() {
return theirid; return theirid;
} }
public void setUsername(String username){ public void setUsername(String username) {
this.username = username; this.username = username;
} }
public String getUsername(){ public String getUsername() {
return username; return username;
} }
@Override @Override
public String toString(){ public String toString() {
return return
"User{" + "User{" +
"websiteLink = '" + websiteLink + '\'' + "websiteLink = '" + websiteLink + '\'' +
@@ -743,4 +745,12 @@ public class User{
",username = '" + username + '\'' + ",username = '" + username + '\'' +
"}"; "}";
} }
@Override
public boolean equals(Object obj) {
if (!(obj instanceof User))
return false;
User user = (User) obj;
return Objects.equals(user.uid, this.uid);
}
} }

View File

@@ -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;
}
} }

View File

@@ -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() {

View File

@@ -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);
} }
} }

View File

@@ -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;
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View 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));
}
}