This commit is contained in:
hyb1996 2017-10-27 15:05:23 +08:00
commit dab1b2860e
103 changed files with 1975 additions and 1135 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
/.idea/libraries
.DS_Store
/build
/release
/captures
.externalNativeBuild
*.apk

View File

@ -39,17 +39,7 @@
</value>
</option>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@ -1,17 +1,16 @@
apply plugin: 'com.android.application'
apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'me.tatarka.retrolambda'
def AAVersion = '4.2.0'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.stardust.scriptdroid"
minSdkVersion 17
targetSdkVersion 23
versionCode 213
versionName "3.0.0 Alpha14"
versionCode 214
versionName "3.0.0 Alpha15"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
@ -40,9 +39,8 @@ android {
disable 'ExtraTranslation'
}
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def file = output.outputFile
output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
@ -55,6 +53,7 @@ repositories {
flatDir {
dirs 'libs'
}
google()
}
dependencies {
@ -75,10 +74,10 @@ dependencies {
})
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
// Android supports
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:appcompat-v7:25.4.0'
compile 'com.android.support:cardview-v7:25.4.0'
compile 'com.android.support:design:25.4.0'
compile 'com.android.support:multidex:1.0.2'
// Personal libraries
compile 'com.github.hyb1996:MutableTheme:0.2.2'
// Material Dialogs
@ -102,12 +101,12 @@ dependencies {
compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'
compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'
compile 'com.wang.avi:library:2.1.3'
compile 'org.apache.commons:commons-lang3:3.5'
compile 'org.apache.commons:commons-lang3:3.6'
compile 'com.github.hyb1996:FloatingCircularActionMenu:0.0.2'
compile(name: 'apkbuilder-release', ext: 'aar')
// RxJava
compile "io.reactivex.rxjava2:rxjava:2.1.0"
compile "io.reactivex.rxjava2:rxjava:2.1.2"
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
// RxDownload
compile('zlc.season:rxdownload3:1.0.8', {
@ -120,15 +119,18 @@ dependencies {
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//JDeferred
compile 'org.jdeferred:jdeferred-android-aar:1.2.6'
//Picasso
compile 'com.squareup.picasso:picasso:2.5.2'
//Glide
compile('com.github.bumptech.glide:glide:4.2.0', {
exclude group: 'com.android.support'
})
annotationProcessor 'com.github.bumptech.glide:compiler:4.2.0'
// Tasker Plugin
compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:[4.0.2, 5.0['
compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3'
compile 'com.flurry.android:analytics:7.0.0@aar'
compile('com.afollestad.material-dialogs:commons:0.9.2.3', {
exclude group: 'com.android.support'
})
compile 'com.makeramen:roundedimageview:2.2.1'
compile 'com.makeramen:roundedimageview:2.3.0'
compile 'com.rengwuxian.materialedittext:library:2.0.3'
compile 'org.msgpack:msgpack-core:0.8.11'
compile project(':automator')

View File

@ -78,7 +78,13 @@
<activity android:name=".ui.error.ErrorReportActivity"/>
<activity android:name=".external.tasker.TaskerScriptEditActivity_"/>
<activity android:name=".ui.edit.ViewSampleActivity"/>
<activity android:name=".ui.login.LoginActivity_"/>
<activity
android:name=".ui.user.LoginActivity_"
android:windowSoftInputMode="adjustResize"/>
<activity
android:name=".ui.user.RegisterActivity_"
android:windowSoftInputMode="adjustResize"/>
<activity android:name=".ui.user.WebActivity_"/>
<activity android:name=".ui.build.BuildActivity_"/>
<activity android:name=".ui.doc.DocumentationActivity_"/>
<activity android:name=".ui.shortcut.ShortcutIconSelectActivity_"/>

View File

@ -44,10 +44,7 @@ public class RunIntentActivity extends Activity {
InputStream stream = getContentResolver().openInputStream(uri);
Scripts.run(new StringScriptSource(PFiles.read(stream)));
} else {
final String path = intent.getData().getPath();
if (!TextUtils.isEmpty(path)) {
Scripts.run(new ScriptFile(path));
}
CommonUtils.handleIntent(this, intent);
}
}
}

View File

@ -0,0 +1,11 @@
package com.stardust.scriptdroid.network;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
/**
* Created by Stardust on 2017/10/26.
*/
@GlideModule
public class Glides extends AppGlideModule {
}

View File

@ -2,8 +2,12 @@ package com.stardust.scriptdroid.network;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.stardust.scriptdroid.network.api.ConfigApi;
import com.stardust.scriptdroid.network.entity.config.Config;
import com.stardust.scriptdroid.network.util.WebkitCookieManagerProxy;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@ -14,13 +18,16 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class NodeBB {
public static final String BASE_URL = "http://www.autojs.org/";
private static final NodeBB sInstance = new NodeBB();
private Config mConfig;
private Retrofit mRetrofit;
NodeBB() {
mRetrofit = new Retrofit.Builder()
.baseUrl("http://www.autojs.org/")
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder()
.setLenient()
.create()))
@ -38,4 +45,18 @@ public class NodeBB {
public Retrofit getRetrofit() {
return mRetrofit;
}
public Observable<Config> getConfig() {
if (mConfig == null) {
return mRetrofit.create(ConfigApi.class)
.getConfig()
.doOnNext(config -> mConfig = config);
}
return Observable.just(mConfig);
}
public static String url(String relativePath) {
return BASE_URL + relativePath;
}
}

View File

@ -1,19 +1,15 @@
package com.stardust.scriptdroid.network;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import android.util.Log;
import com.stardust.scriptdroid.network.api.ConfigApi;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.TokenResponse;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import java.util.Collections;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Stardust on 2017/9/20.
@ -28,20 +24,30 @@ public class UserService {
mRetrofit = NodeBB.getInstance().getRetrofit();
}
public static UserService getInstance() {
return sInstance;
}
public Observable<TokenResponse> login(String userName, final String password) {
final UserApi userApi = mRetrofit.create(UserApi.class);
return userApi.verify(userName, password)
.subscribeOn(Schedulers.io())
.flatMap(new Function<VerifyResponse, ObservableSource<TokenResponse>>() {
@Override
public ObservableSource<TokenResponse> apply(@NonNull VerifyResponse verifyResponse) throws Exception {
if (verifyResponse.isSuccessful()) {
return userApi.generateToken(verifyResponse.getUid(), password);
} else {
return Observable.error(new Exception(verifyResponse.getMessage()));
}
}
public Observable<ResponseBody> login(String userName, final String password) {
return NodeBB.getInstance()
.getConfig()
.flatMap(config -> {
Log.d("login", config.toString());
return mRetrofit.create(UserApi.class)
.login(Collections.singletonMap("x-csrf-token", config.getCsrfToken()),
userName, password);
});
}
public Observable<ResponseBody> register(String email, String userName, String password) {
return NodeBB.getInstance()
.getConfig()
.flatMap(config -> {
Log.d("login", config.toString());
return mRetrofit.create(UserApi.class)
.register(Collections.singletonMap("x-csrf-token", config.getCsrfToken()),
email, userName, password);
});
}
}

View File

@ -0,0 +1,17 @@
package com.stardust.scriptdroid.network.api;
import com.stardust.scriptdroid.network.entity.config.Config;
import io.reactivex.Observable;
import retrofit2.http.GET;
/**
* Created by Stardust on 2017/10/26.
*/
public interface ConfigApi {
@GET("/api/config")
Observable<Config> getConfig();
}

View File

@ -1,15 +1,16 @@
package com.stardust.scriptdroid.network.api;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import com.stardust.scriptdroid.network.entity.TokenResponse;
import com.stardust.scriptdroid.network.entity.User;
import com.stardust.scriptdroid.network.entity.user.User;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.HeaderMap;
import retrofit2.http.POST;
import retrofit2.http.Path;
/**
* Created by Stardust on 2017/9/20.
@ -21,14 +22,13 @@ public interface UserApi {
Observable<User> me();
@FormUrlEncoded
@POST("/api/ns/login")
Observable<VerifyResponse> verify(@Field("username") String userName, @Field("password") String password);
@POST("/login")
Observable<ResponseBody> login(@HeaderMap Map<String, String> csrfToken, @Field("username") String userName, @Field("password") String password);
@FormUrlEncoded
@POST("/api/v2/{uid}/tokens")
Observable<TokenResponse> generateToken(@Path("uid") String uid, @Field("password") String password);
@POST("/register")
Observable<ResponseBody> register(@HeaderMap Map<String, String> csrfToken, @Field("email") String email,
@Field("username") String userName, @Field("password") String password);
}

View File

@ -1,17 +0,0 @@
package com.stardust.scriptdroid.network.entity;
/**
* Created by Stardust on 2017/9/21.
*/
public class TokenResponse {
public String code;
public static class Payload {
public String token;
}
}

View File

@ -1,376 +0,0 @@
package com.stardust.scriptdroid.network.entity;
import com.google.gson.annotations.SerializedName;
public class VerifyResponse {
@SerializedName("message")
private String message;
@SerializedName("birthday")
private String birthday;
@SerializedName("lastposttime")
private String lastposttime;
@SerializedName("signature")
private String signature;
@SerializedName("icon:bgColor")
private String iconBgColor;
@SerializedName("groupTitle")
private String groupTitle;
@SerializedName("reputation")
private String reputation;
@SerializedName("followingCount")
private String followingCount;
@SerializedName("lastonlineISO")
private String lastonlineISO;
@SerializedName("uid")
private String uid;
@SerializedName("profileviews")
private String profileviews;
@SerializedName("icon:text")
private String iconText;
@SerializedName("banned")
private String banned;
@SerializedName("userslug")
private String userslug;
@SerializedName("followerCount")
private String followerCount;
@SerializedName("email")
private String email;
@SerializedName("joindate")
private String joindate;
@SerializedName("website")
private String website;
@SerializedName("uploadedpicture")
private String uploadedpicture;
@SerializedName("passwordExpiry")
private String passwordExpiry;
@SerializedName("lastonline")
private String lastonline;
@SerializedName("picture")
private String picture;
@SerializedName("joindateISO")
private String joindateISO;
@SerializedName("email:confirmed")
private Object emailConfirmed;
@SerializedName("postcount")
private String postcount;
@SerializedName("location")
private String location;
@SerializedName("fullname")
private String fullname;
@SerializedName("topiccount")
private String topiccount;
@SerializedName("username")
private String username;
@SerializedName("status")
private String status;
public boolean isSuccessful() {
return message == null;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getBirthday() {
return birthday;
}
public void setLastposttime(String lastposttime) {
this.lastposttime = lastposttime;
}
public String getLastposttime() {
return lastposttime;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getSignature() {
return signature;
}
public void setIconBgColor(String iconBgColor) {
this.iconBgColor = iconBgColor;
}
public String getIconBgColor() {
return iconBgColor;
}
public void setGroupTitle(String groupTitle) {
this.groupTitle = groupTitle;
}
public String getGroupTitle() {
return groupTitle;
}
public void setReputation(String reputation) {
this.reputation = reputation;
}
public String getReputation() {
return reputation;
}
public void setFollowingCount(String followingCount) {
this.followingCount = followingCount;
}
public String getFollowingCount() {
return followingCount;
}
public void setLastonlineISO(String lastonlineISO) {
this.lastonlineISO = lastonlineISO;
}
public String getLastonlineISO() {
return lastonlineISO;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return uid;
}
public void setProfileviews(String profileviews) {
this.profileviews = profileviews;
}
public String getProfileviews() {
return profileviews;
}
public void setIconText(String iconText) {
this.iconText = iconText;
}
public String getIconText() {
return iconText;
}
public void setBanned(String banned) {
this.banned = banned;
}
public String getBanned() {
return banned;
}
public void setUserslug(String userslug) {
this.userslug = userslug;
}
public String getUserslug() {
return userslug;
}
public void setFollowerCount(String followerCount) {
this.followerCount = followerCount;
}
public String getFollowerCount() {
return followerCount;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setJoindate(String joindate) {
this.joindate = joindate;
}
public String getJoindate() {
return joindate;
}
public void setWebsite(String website) {
this.website = website;
}
public String getWebsite() {
return website;
}
public void setUploadedpicture(String uploadedpicture) {
this.uploadedpicture = uploadedpicture;
}
public String getUploadedpicture() {
return uploadedpicture;
}
public void setPasswordExpiry(String passwordExpiry) {
this.passwordExpiry = passwordExpiry;
}
public String getPasswordExpiry() {
return passwordExpiry;
}
public void setLastonline(String lastonline) {
this.lastonline = lastonline;
}
public String getLastonline() {
return lastonline;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getPicture() {
return picture;
}
public void setJoindateISO(String joindateISO) {
this.joindateISO = joindateISO;
}
public String getJoindateISO() {
return joindateISO;
}
public void setEmailConfirmed(Object emailConfirmed) {
this.emailConfirmed = emailConfirmed;
}
public Object getEmailConfirmed() {
return emailConfirmed;
}
public void setPostcount(String postcount) {
this.postcount = postcount;
}
public String getPostcount() {
return postcount;
}
public void setLocation(String location) {
this.location = location;
}
public String getLocation() {
return location;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getFullname() {
return fullname;
}
public void setTopiccount(String topiccount) {
this.topiccount = topiccount;
}
public String getTopiccount() {
return topiccount;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
@Override
public String toString() {
return
"VerifyResponse{" +
"birthday = '" + birthday + '\'' +
",lastposttime = '" + lastposttime + '\'' +
",signature = '" + signature + '\'' +
",icon:bgColor = '" + iconBgColor + '\'' +
",groupTitle = '" + groupTitle + '\'' +
",reputation = '" + reputation + '\'' +
",followingCount = '" + followingCount + '\'' +
",lastonlineISO = '" + lastonlineISO + '\'' +
",uid = '" + uid + '\'' +
",profileviews = '" + profileviews + '\'' +
",icon:text = '" + iconText + '\'' +
",banned = '" + banned + '\'' +
",userslug = '" + userslug + '\'' +
",followerCount = '" + followerCount + '\'' +
",email = '" + email + '\'' +
",joindate = '" + joindate + '\'' +
",website = '" + website + '\'' +
",uploadedpicture = '" + uploadedpicture + '\'' +
",passwordExpiry = '" + passwordExpiry + '\'' +
",lastonline = '" + lastonline + '\'' +
",picture = '" + picture + '\'' +
",joindateISO = '" + joindateISO + '\'' +
",email:confirmed = '" + emailConfirmed + '\'' +
",postcount = '" + postcount + '\'' +
",location = '" + location + '\'' +
",fullname = '" + fullname + '\'' +
",topiccount = '" + topiccount + '\'' +
",username = '" + username + '\'' +
",status = '" + status + '\'' +
"}";
}
}

View File

@ -0,0 +1,617 @@
package com.stardust.scriptdroid.network.entity.config;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class Config{
@SerializedName("socketioTransports")
private List<String> socketioTransports;
@SerializedName("allowGuestSearching")
private boolean allowGuestSearching;
@SerializedName("hasImageUploadPlugin")
private boolean hasImageUploadPlugin;
@SerializedName("showSiteTitle")
private boolean showSiteTitle;
@SerializedName("websocketAddress")
private String websocketAddress;
@SerializedName("maximumFileSize")
private String maximumFileSize;
@SerializedName("usePagination")
private boolean usePagination;
@SerializedName("minimumPostLength")
private String minimumPostLength;
@SerializedName("allowGuestUserSearching")
private boolean allowGuestUserSearching;
@SerializedName("allowTopicsThumbnail")
private boolean allowTopicsThumbnail;
@SerializedName("allowGuestHandles")
private boolean allowGuestHandles;
@SerializedName("disableChatMessageEditing")
private boolean disableChatMessageEditing;
@SerializedName("version")
private String version;
@SerializedName("minimumTitleLength")
private String minimumTitleLength;
@SerializedName("maximumTagsPerTopic")
private int maximumTagsPerTopic;
@SerializedName("topicPostSort")
private String topicPostSort;
@SerializedName("defaultBootswatchSkin")
private String defaultBootswatchSkin;
@SerializedName("allowFileUploads")
private boolean allowFileUploads;
@SerializedName("maximumPostLength")
private String maximumPostLength;
@SerializedName("loggedIn")
private boolean loggedIn;
@SerializedName("postsPerPage")
private String postsPerPage;
@SerializedName("relative_path")
private String relativePath;
@SerializedName("requireEmailConfirmation")
private boolean requireEmailConfirmation;
@SerializedName("defaultLang")
private String defaultLang;
@SerializedName("disableChat")
private boolean disableChat;
@SerializedName("userLang")
private String userLang;
@SerializedName("maxReconnectionAttempts")
private int maxReconnectionAttempts;
@SerializedName("timeagoCutoff")
private String timeagoCutoff;
@SerializedName("browserTitle")
private String browserTitle;
@SerializedName("siteTitle")
private String siteTitle;
@SerializedName("csrf_token")
private String csrfToken;
@SerializedName("categoryTopicSort")
private String categoryTopicSort;
@SerializedName("disableMasonry")
private boolean disableMasonry;
@SerializedName("theme:src")
private String themeSrc;
@SerializedName("cookies")
private Cookies cookies;
@SerializedName("markdown")
private Markdown markdown;
@SerializedName("minimumTagLength")
private String minimumTagLength;
@SerializedName("maximumTagLength")
private String maximumTagLength;
@SerializedName("maximumTitleLength")
private String maximumTitleLength;
@SerializedName("topicsPerPage")
private String topicsPerPage;
@SerializedName("useOutgoingLinksPage")
private boolean useOutgoingLinksPage;
@SerializedName("bootswatchSkin")
private String bootswatchSkin;
@SerializedName("minimumTagsPerTopic")
private int minimumTagsPerTopic;
@SerializedName("delayImageLoading")
private boolean delayImageLoading;
@SerializedName("cache-buster")
private String cacheBuster;
@SerializedName("titleLayout")
private String titleLayout;
@SerializedName("theme:id")
private String themeId;
@SerializedName("topicSearchEnabled")
private boolean topicSearchEnabled;
@SerializedName("searchEnabled")
private boolean searchEnabled;
@SerializedName("reconnectionDelay")
private int reconnectionDelay;
public void setSocketioTransports(List<String> socketioTransports){
this.socketioTransports = socketioTransports;
}
public List<String> getSocketioTransports(){
return socketioTransports;
}
public void setAllowGuestSearching(boolean allowGuestSearching){
this.allowGuestSearching = allowGuestSearching;
}
public boolean isAllowGuestSearching(){
return allowGuestSearching;
}
public void setHasImageUploadPlugin(boolean hasImageUploadPlugin){
this.hasImageUploadPlugin = hasImageUploadPlugin;
}
public boolean isHasImageUploadPlugin(){
return hasImageUploadPlugin;
}
public void setShowSiteTitle(boolean showSiteTitle){
this.showSiteTitle = showSiteTitle;
}
public boolean isShowSiteTitle(){
return showSiteTitle;
}
public void setWebsocketAddress(String websocketAddress){
this.websocketAddress = websocketAddress;
}
public String getWebsocketAddress(){
return websocketAddress;
}
public void setMaximumFileSize(String maximumFileSize){
this.maximumFileSize = maximumFileSize;
}
public String getMaximumFileSize(){
return maximumFileSize;
}
public void setUsePagination(boolean usePagination){
this.usePagination = usePagination;
}
public boolean isUsePagination(){
return usePagination;
}
public void setMinimumPostLength(String minimumPostLength){
this.minimumPostLength = minimumPostLength;
}
public String getMinimumPostLength(){
return minimumPostLength;
}
public void setAllowGuestUserSearching(boolean allowGuestUserSearching){
this.allowGuestUserSearching = allowGuestUserSearching;
}
public boolean isAllowGuestUserSearching(){
return allowGuestUserSearching;
}
public void setAllowTopicsThumbnail(boolean allowTopicsThumbnail){
this.allowTopicsThumbnail = allowTopicsThumbnail;
}
public boolean isAllowTopicsThumbnail(){
return allowTopicsThumbnail;
}
public void setAllowGuestHandles(boolean allowGuestHandles){
this.allowGuestHandles = allowGuestHandles;
}
public boolean isAllowGuestHandles(){
return allowGuestHandles;
}
public void setDisableChatMessageEditing(boolean disableChatMessageEditing){
this.disableChatMessageEditing = disableChatMessageEditing;
}
public boolean isDisableChatMessageEditing(){
return disableChatMessageEditing;
}
public void setVersion(String version){
this.version = version;
}
public String getVersion(){
return version;
}
public void setMinimumTitleLength(String minimumTitleLength){
this.minimumTitleLength = minimumTitleLength;
}
public String getMinimumTitleLength(){
return minimumTitleLength;
}
public void setMaximumTagsPerTopic(int maximumTagsPerTopic){
this.maximumTagsPerTopic = maximumTagsPerTopic;
}
public int getMaximumTagsPerTopic(){
return maximumTagsPerTopic;
}
public void setTopicPostSort(String topicPostSort){
this.topicPostSort = topicPostSort;
}
public String getTopicPostSort(){
return topicPostSort;
}
public void setDefaultBootswatchSkin(String defaultBootswatchSkin){
this.defaultBootswatchSkin = defaultBootswatchSkin;
}
public String getDefaultBootswatchSkin(){
return defaultBootswatchSkin;
}
public void setAllowFileUploads(boolean allowFileUploads){
this.allowFileUploads = allowFileUploads;
}
public boolean isAllowFileUploads(){
return allowFileUploads;
}
public void setMaximumPostLength(String maximumPostLength){
this.maximumPostLength = maximumPostLength;
}
public String getMaximumPostLength(){
return maximumPostLength;
}
public void setLoggedIn(boolean loggedIn){
this.loggedIn = loggedIn;
}
public boolean isLoggedIn(){
return loggedIn;
}
public void setPostsPerPage(String postsPerPage){
this.postsPerPage = postsPerPage;
}
public String getPostsPerPage(){
return postsPerPage;
}
public void setRelativePath(String relativePath){
this.relativePath = relativePath;
}
public String getRelativePath(){
return relativePath;
}
public void setRequireEmailConfirmation(boolean requireEmailConfirmation){
this.requireEmailConfirmation = requireEmailConfirmation;
}
public boolean isRequireEmailConfirmation(){
return requireEmailConfirmation;
}
public void setDefaultLang(String defaultLang){
this.defaultLang = defaultLang;
}
public String getDefaultLang(){
return defaultLang;
}
public void setDisableChat(boolean disableChat){
this.disableChat = disableChat;
}
public boolean isDisableChat(){
return disableChat;
}
public void setUserLang(String userLang){
this.userLang = userLang;
}
public String getUserLang(){
return userLang;
}
public void setMaxReconnectionAttempts(int maxReconnectionAttempts){
this.maxReconnectionAttempts = maxReconnectionAttempts;
}
public int getMaxReconnectionAttempts(){
return maxReconnectionAttempts;
}
public void setTimeagoCutoff(String timeagoCutoff){
this.timeagoCutoff = timeagoCutoff;
}
public String getTimeagoCutoff(){
return timeagoCutoff;
}
public void setBrowserTitle(String browserTitle){
this.browserTitle = browserTitle;
}
public String getBrowserTitle(){
return browserTitle;
}
public void setSiteTitle(String siteTitle){
this.siteTitle = siteTitle;
}
public String getSiteTitle(){
return siteTitle;
}
public void setCsrfToken(String csrfToken){
this.csrfToken = csrfToken;
}
public String getCsrfToken(){
return csrfToken;
}
public void setCategoryTopicSort(String categoryTopicSort){
this.categoryTopicSort = categoryTopicSort;
}
public String getCategoryTopicSort(){
return categoryTopicSort;
}
public void setDisableMasonry(boolean disableMasonry){
this.disableMasonry = disableMasonry;
}
public boolean isDisableMasonry(){
return disableMasonry;
}
public void setThemeSrc(String themeSrc){
this.themeSrc = themeSrc;
}
public String getThemeSrc(){
return themeSrc;
}
public void setCookies(Cookies cookies){
this.cookies = cookies;
}
public Cookies getCookies(){
return cookies;
}
public void setMarkdown(Markdown markdown){
this.markdown = markdown;
}
public Markdown getMarkdown(){
return markdown;
}
public void setMinimumTagLength(String minimumTagLength){
this.minimumTagLength = minimumTagLength;
}
public String getMinimumTagLength(){
return minimumTagLength;
}
public void setMaximumTagLength(String maximumTagLength){
this.maximumTagLength = maximumTagLength;
}
public String getMaximumTagLength(){
return maximumTagLength;
}
public void setMaximumTitleLength(String maximumTitleLength){
this.maximumTitleLength = maximumTitleLength;
}
public String getMaximumTitleLength(){
return maximumTitleLength;
}
public void setTopicsPerPage(String topicsPerPage){
this.topicsPerPage = topicsPerPage;
}
public String getTopicsPerPage(){
return topicsPerPage;
}
public void setUseOutgoingLinksPage(boolean useOutgoingLinksPage){
this.useOutgoingLinksPage = useOutgoingLinksPage;
}
public boolean isUseOutgoingLinksPage(){
return useOutgoingLinksPage;
}
public void setBootswatchSkin(String bootswatchSkin){
this.bootswatchSkin = bootswatchSkin;
}
public String getBootswatchSkin(){
return bootswatchSkin;
}
public void setMinimumTagsPerTopic(int minimumTagsPerTopic){
this.minimumTagsPerTopic = minimumTagsPerTopic;
}
public int getMinimumTagsPerTopic(){
return minimumTagsPerTopic;
}
public void setDelayImageLoading(boolean delayImageLoading){
this.delayImageLoading = delayImageLoading;
}
public boolean isDelayImageLoading(){
return delayImageLoading;
}
public void setCacheBuster(String cacheBuster){
this.cacheBuster = cacheBuster;
}
public String getCacheBuster(){
return cacheBuster;
}
public void setTitleLayout(String titleLayout){
this.titleLayout = titleLayout;
}
public String getTitleLayout(){
return titleLayout;
}
public void setThemeId(String themeId){
this.themeId = themeId;
}
public String getThemeId(){
return themeId;
}
public void setTopicSearchEnabled(boolean topicSearchEnabled){
this.topicSearchEnabled = topicSearchEnabled;
}
public boolean isTopicSearchEnabled(){
return topicSearchEnabled;
}
public void setSearchEnabled(boolean searchEnabled){
this.searchEnabled = searchEnabled;
}
public boolean isSearchEnabled(){
return searchEnabled;
}
public void setReconnectionDelay(int reconnectionDelay){
this.reconnectionDelay = reconnectionDelay;
}
public int getReconnectionDelay(){
return reconnectionDelay;
}
@Override
public String toString(){
return
"Config{" +
",socketioTransports = '" + socketioTransports + '\'' +
",allowGuestSearching = '" + allowGuestSearching + '\'' +
",hasImageUploadPlugin = '" + hasImageUploadPlugin + '\'' +
",showSiteTitle = '" + showSiteTitle + '\'' +
",websocketAddress = '" + websocketAddress + '\'' +
",maximumFileSize = '" + maximumFileSize + '\'' +
",usePagination = '" + usePagination + '\'' +
",minimumPostLength = '" + minimumPostLength + '\'' +
",allowGuestUserSearching = '" + allowGuestUserSearching + '\'' +
",allowTopicsThumbnail = '" + allowTopicsThumbnail + '\'' +
",allowGuestHandles = '" + allowGuestHandles + '\'' +
",disableChatMessageEditing = '" + disableChatMessageEditing + '\'' +
",version = '" + version + '\'' +
",minimumTitleLength = '" + minimumTitleLength + '\'' +
",maximumTagsPerTopic = '" + maximumTagsPerTopic + '\'' +
",topicPostSort = '" + topicPostSort + '\'' +
",defaultBootswatchSkin = '" + defaultBootswatchSkin + '\'' +
",allowFileUploads = '" + allowFileUploads + '\'' +
",maximumPostLength = '" + maximumPostLength + '\'' +
",loggedIn = '" + loggedIn + '\'' +
",postsPerPage = '" + postsPerPage + '\'' +
",relative_path = '" + relativePath + '\'' +
",requireEmailConfirmation = '" + requireEmailConfirmation + '\'' +
",defaultLang = '" + defaultLang + '\'' +
",disableChat = '" + disableChat + '\'' +
",userLang = '" + userLang + '\'' +
",maxReconnectionAttempts = '" + maxReconnectionAttempts + '\'' +
",timeagoCutoff = '" + timeagoCutoff + '\'' +
",browserTitle = '" + browserTitle + '\'' +
",siteTitle = '" + siteTitle + '\'' +
",csrf_token = '" + csrfToken + '\'' +
",categoryTopicSort = '" + categoryTopicSort + '\'' +
",disableMasonry = '" + disableMasonry + '\'' +
",theme:src = '" + themeSrc + '\'' +
",cookies = '" + cookies + '\'' +
",markdown = '" + markdown + '\'' +
",minimumTagLength = '" + minimumTagLength + '\'' +
",maximumTagLength = '" + maximumTagLength + '\'' +
",maximumTitleLength = '" + maximumTitleLength + '\'' +
",topicsPerPage = '" + topicsPerPage + '\'' +
",useOutgoingLinksPage = '" + useOutgoingLinksPage + '\'' +
",bootswatchSkin = '" + bootswatchSkin + '\'' +
",minimumTagsPerTopic = '" + minimumTagsPerTopic + '\'' +
",delayImageLoading = '" + delayImageLoading + '\'' +
",cache-buster = '" + cacheBuster + '\'' +
",titleLayout = '" + titleLayout + '\'' +
",theme:id = '" + themeId + '\'' +
",topicSearchEnabled = '" + topicSearchEnabled + '\'' +
",searchEnabled = '" + searchEnabled + '\'' +
",reconnectionDelay = '" + reconnectionDelay + '\'' +
"}";
}
}

View File

@ -0,0 +1,62 @@
package com.stardust.scriptdroid.network.entity.config;
import com.google.gson.annotations.SerializedName;
public class Cookies {
@SerializedName("link")
private String link;
@SerializedName("dismiss")
private String dismiss;
@SerializedName("message")
private String message;
@SerializedName("enabled")
private boolean enabled;
public void setLink(String link) {
this.link = link;
}
public String getLink() {
return link;
}
public void setDismiss(String dismiss) {
this.dismiss = dismiss;
}
public String getDismiss() {
return dismiss;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isEnabled() {
return enabled;
}
@Override
public String toString() {
return
"Cookies{" +
"link = '" + link + '\'' +
",dismiss = '" + dismiss + '\'' +
",message = '" + message + '\'' +
",enabled = '" + enabled + '\'' +
"}";
}
}

View File

@ -0,0 +1,37 @@
package com.stardust.scriptdroid.network.entity.config;
import com.google.gson.annotations.SerializedName;
public class Markdown{
@SerializedName("highlight")
private int highlight;
@SerializedName("theme")
private String theme;
public void setHighlight(int highlight){
this.highlight = highlight;
}
public int getHighlight(){
return highlight;
}
public void setTheme(String theme){
this.theme = theme;
}
public String getTheme(){
return theme;
}
@Override
public String toString(){
return
"Markdown{" +
"highlight = '" + highlight + '\'' +
",theme = '" + theme + '\'' +
"}";
}
}

View File

@ -1,4 +1,4 @@
package com.stardust.scriptdroid.network.entity;
package com.stardust.scriptdroid.network.entity.user;
import com.google.gson.annotations.SerializedName;

View File

@ -1,4 +1,4 @@
package com.stardust.scriptdroid.network.entity;
package com.stardust.scriptdroid.network.entity.user;
import java.util.List;
import com.google.gson.annotations.SerializedName;

View File

@ -1,140 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.pio.PFiles;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by Stardust on 2017/4/3.
*/
public abstract class DrawableSaver {
private static final String PREFIX = "saved_drawable_";
protected Drawable mOriginalDrawable;
private Context mContext;
private String mName;
public DrawableSaver(Context context, String name, Drawable originalDrawable) {
mContext = context;
mName = PREFIX + name;
mOriginalDrawable = originalDrawable;
readImageAndApply();
}
private void readImageAndApply() {
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream inputStream = mContext.openFileInput(mName);
Drawable drawable = BitmapDrawable.createFromStream(inputStream, mName);
applyDrawableToView(drawable);
} catch (FileNotFoundException e) {
}
}
}).start();
}
public void setDrawable(InputStream inputStream) {
saveDrawable(inputStream, new Runnable() {
@Override
public void run() {
readImageAndApply();
}
});
}
private void saveDrawable(final InputStream inputStream, final Runnable callback) {
new Thread(new Runnable() {
@Override
public void run() {
try {
OutputStream outputStream = mContext.openFileOutput(mName, Context.MODE_PRIVATE);
PFiles.write(inputStream, outputStream);
outputStream.close();
inputStream.close();
callback.run();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public void select(Activity activity, final OnActivityResultDelegate.Mediator mediator) {
new ImageSelector(activity, mediator, new ImageSelector.ImageSelectorCallback() {
@Override
public void onImageSelected(ImageSelector selector, InputStream inputStream) {
if (inputStream != null)
setDrawable(inputStream);
mediator.removeDelegate(selector);
}
}).select();
}
public void reset() {
applyDrawableToView(mOriginalDrawable);
mContext.deleteFile(mName);
}
public static void reset(Context context, String name) {
context.deleteFile(PREFIX + name);
}
protected abstract void applyDrawableToView(Drawable drawable);
public static class ViewBackgroundSaver extends DrawableSaver {
private View mView;
public ViewBackgroundSaver(Context activity, String name, View view) {
super(activity, name, view.getBackground());
mView = view;
}
@Override
protected void applyDrawableToView(final Drawable drawable) {
mView.post(new Runnable() {
@Override
public void run() {
mView.setBackground(drawable);
}
});
}
}
public static class ImageSaver extends DrawableSaver {
private ImageView mView;
public ImageSaver(Context activity, String name, ImageView view) {
super(activity, name, view.getDrawable());
mView = view;
}
@Override
protected void applyDrawableToView(final Drawable drawable) {
mView.post(new Runnable() {
@Override
public void run() {
mView.setImageDrawable(drawable);
}
});
}
}
}

View File

@ -2,6 +2,7 @@ package com.stardust.scriptdroid.tool;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.scriptdroid.R;
@ -16,7 +17,7 @@ import java.io.InputStream;
public class ImageSelector implements OnActivityResultDelegate {
public interface ImageSelectorCallback {
void onImageSelected(ImageSelector selector, InputStream path);
void onImageSelected(ImageSelector selector, Uri uri);
}
private static final String TAG = ImageSelector.class.getSimpleName();
@ -24,11 +25,14 @@ public class ImageSelector implements OnActivityResultDelegate {
private static final int REQUEST_CODE = "LOVE EATING".hashCode() >> 16;
private Activity mActivity;
private ImageSelectorCallback mCallback;
private boolean mDisposable;
private Mediator mMediator;
public ImageSelector(Activity activity, OnActivityResultDelegate.Mediator mediator, ImageSelectorCallback callback) {
mediator.addDelegate(REQUEST_CODE, this);
mActivity = activity;
mCallback = callback;
mMediator = mediator;
}
public void select() {
@ -37,19 +41,21 @@ public class ImageSelector implements OnActivityResultDelegate {
REQUEST_CODE);
}
public ImageSelector disposable() {
mDisposable = true;
return this;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mDisposable) {
mMediator.removeDelegate(this);
}
if (data == null) {
mCallback.onImageSelected(this, null);
return;
}
try {
InputStream inputStream = mActivity.getContentResolver().openInputStream(data.getData());
mCallback.onImageSelected(this, inputStream);
} catch (FileNotFoundException e) {
mCallback.onImageSelected(this, null);
}
mCallback.onImageSelected(this, data.getData());
}

View File

@ -1,13 +1,11 @@
package com.stardust.scriptdroid.ui.doc;
import android.app.Activity;
import android.webkit.WebView;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.util.BackPressedHandler;
import com.stardust.widget.EWebView;
import com.stardust.scriptdroid.ui.widget.EWebView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;

View File

@ -9,7 +9,7 @@ import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.R;
import com.stardust.widget.EWebView;
import com.stardust.scriptdroid.ui.widget.EWebView;
import butterknife.BindView;
import butterknife.ButterKnife;

View File

@ -1,19 +1,15 @@
package com.stardust.scriptdroid.ui.doc;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.webkit.WebView;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
import com.stardust.util.BackPressedHandler;
import com.stardust.widget.EWebView;
import com.stardust.scriptdroid.ui.widget.EWebView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment;

View File

@ -2,20 +2,13 @@ package com.stardust.scriptdroid.ui.edit;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuItem;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.widget.EWebView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;

View File

@ -27,8 +27,8 @@ import com.stardust.scriptdroid.ui.edit.completion.CodeCompletions;
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletionBar;
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhancedBarColors;
import com.stardust.scriptdroid.ui.edit.completion.Symbols;
import com.stardust.widget.EWebView;
import com.stardust.widget.ToolbarMenuItem;
import com.stardust.scriptdroid.ui.widget.EWebView;
import com.stardust.scriptdroid.ui.widget.ToolbarMenuItem;
import com.stardust.widget.ViewSwitcher;
import org.androidannotations.annotations.AfterViews;

View File

@ -23,7 +23,7 @@ import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.theme.ThemeColorManager;
import com.stardust.util.AssetsCache;
import com.stardust.util.SparseArrayEntries;
import com.stardust.widget.ToolbarMenuItem;
import com.stardust.scriptdroid.ui.widget.ToolbarMenuItem;
import butterknife.ButterKnife;
import butterknife.OnClick;

View File

@ -9,7 +9,6 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import com.stardust.pio.PFile;
@ -17,8 +16,8 @@ import com.stardust.pio.PFiles;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.ui.main.scripts.ScriptListView;
import com.stardust.widget.BindableViewHolder;
import com.stardust.widget.CheckBoxCompat;
import com.stardust.scriptdroid.ui.widget.BindableViewHolder;
import com.stardust.scriptdroid.ui.widget.CheckBoxCompat;
import java.util.ArrayList;
import java.util.LinkedHashMap;

View File

@ -80,19 +80,15 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
}
private void setupListeners() {
mWindow.setOnActionViewClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mState == STATE_RECORDING) {
stopRecord();
} else if (mWindow.isExpanded()) {
mWindow.collapse();
} else {
AutoJs.getInstance().getLayoutInspector().captureCurrentWindow();
mWindow.expand();
}
mWindow.setOnActionViewClickListener(v -> {
if (mState == STATE_RECORDING) {
stopRecord();
} else if (mWindow.isExpanded()) {
mWindow.collapse();
} else {
AutoJs.getInstance().getLayoutInspector().captureCurrentWindow();
mWindow.expand();
}
});
}
@ -130,12 +126,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
.customView(listView, false)
.positiveText(R.string.cancel)
.build();
listView.setOnItemOperatedListener(new ScriptListView.OnItemOperatedListener() {
@Override
public void OnItemOperated(ScriptFile file) {
dialog.dismiss();
}
});
listView.setOnItemOperatedListener(file -> dialog.dismiss());
DialogUtils.showDialog(dialog);
}

View File

@ -13,7 +13,7 @@ import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.floating.FullScreenFloatyWindow;
import com.stardust.view.accessibility.NodeInfo;
import com.stardust.widget.BubblePopupMenu;
import com.stardust.scriptdroid.ui.widget.BubblePopupMenu;
import java.util.Arrays;

View File

@ -11,10 +11,9 @@ import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.Theme;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.ui.floating.FullScreenFloatyWindow;
import com.stardust.view.accessibility.NodeInfo;
import com.stardust.widget.BubblePopupMenu;
import com.stardust.scriptdroid.ui.widget.BubblePopupMenu;
import java.util.Arrays;

View File

@ -16,7 +16,7 @@ import android.widget.TextView;
import com.stardust.scriptdroid.R;
import com.stardust.view.accessibility.NodeInfo;
import com.stardust.util.ViewUtil;
import com.stardust.widget.LevelBeamView;
import com.stardust.scriptdroid.ui.widget.LevelBeamView;
import java.util.Collections;
import java.util.HashSet;

View File

@ -1,77 +0,0 @@
package com.stardust.scriptdroid.ui.login;
import android.util.Log;
import android.widget.TextView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.BaseActivity;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Stardust on 2017/9/20.
*/
@EActivity(R.layout.activity_login)
public class LoginActivity extends BaseActivity {
@ViewById(R.id.username)
TextView mUserName;
@ViewById(R.id.password)
TextView mPassword;
@AfterViews
void setUpViews() {
setToolbarAsBack(getString(R.string.text_login));
}
@Click(R.id.login)
void login() {
String userName = mUserName.getText().toString();
String password = mPassword.getText().toString();
if (!checkNotEmpty(userName, password)) {
return;
}
NodeBB.getInstance().getRetrofit()
.create(UserApi.class)
.verify(userName, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<VerifyResponse>() {
@Override
public void onNext(@NonNull VerifyResponse verifyResponse) {
Log.d("Login", verifyResponse.toString());
}
@Override
public void onError(@NonNull Throwable e) {
e.printStackTrace();
}
});
}
private boolean checkNotEmpty(String userName, String password) {
if (userName.isEmpty()) {
mUserName.setError(getString(R.string.text_username_cannot_be_empty));
return false;
}
if (password.isEmpty()) {
mUserName.setError(getString(R.string.text_password_cannot_be_empty));
return false;
}
return true;
}
}

View File

@ -40,9 +40,9 @@ import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.settings.SettingsActivity_;
import com.stardust.scriptdroid.ui.update.VersionGuard;
import com.stardust.util.BackPressedHandler;
import com.stardust.view.DrawerAutoClose;
import com.stardust.widget.CommonMarkdownView;
import com.stardust.widget.SearchViewItem;
import com.stardust.util.DrawerAutoClose;
import com.stardust.scriptdroid.ui.widget.CommonMarkdownView;
import com.stardust.scriptdroid.ui.widget.SearchViewItem;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;

View File

@ -6,12 +6,10 @@ import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.webkit.WebView;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.main.QueryEvent;
import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
import com.stardust.util.BackPressedHandler;
import com.stardust.widget.EWebView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment;
@ -20,7 +18,6 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.net.URLEncoder;
import java.util.regex.Pattern;
/**
* Created by Stardust on 2017/8/22.
@ -92,7 +89,7 @@ public class CommunityFragment extends ViewPagerFragment implements BackPressedH
if (isInPostsPage()) {
mWebView.loadUrl("javascript:$('button[component=\"topic/reply\"]').click()");
} else {
mWebView.loadUrl("javascript:$('.new_topic').click()");
mWebView.loadUrl("javascript:$('#new_topic').click()");
}
}

View File

@ -1,25 +1,21 @@
package com.stardust.scriptdroid.ui.main.community;
import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
import android.support.design.widget.BottomSheetDialog;
import android.support.design.widget.Snackbar;
import android.util.AttributeSet;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.io.StorageFileProvider;
import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.model.script.Scripts;
import com.stardust.scriptdroid.network.download.DownloadManager;
import com.stardust.scriptdroid.ui.common.OptionListView;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.filechooser.FileChooserDialogBuilder;
import com.stardust.widget.EWebView;
import com.stardust.scriptdroid.ui.widget.EWebView;
import java.util.regex.Pattern;
@ -119,19 +115,26 @@ public class CommunityWebView extends EWebView {
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
evalJavaScript("$('#header').hide();$('#content').css({ top: '0', position: 'absolute' });");
}
}
private class MyWebChromeClient extends EWebView.MyWebChromeClient {
@Override
public void openFileChooser(ValueCallback<Uri> callback) {
public boolean openFileChooser(ValueCallback<Uri> callback, String[] acceptType) {
if (super.openFileChooser(callback, acceptType)) {
return true;
}
new FileChooserDialogBuilder(getContext())
.title(R.string.text_select_file_to_upload)
.dir(StorageFileProvider.DEFAULT_DIRECTORY_PATH)
.singleChoice(file -> callback.onReceiveValue(Uri.fromFile(file)))
.cancelListener(dialog -> callback.onReceiveValue(null))
.show();
return true;
}
}
}

View File

@ -1,31 +1,40 @@
package com.stardust.scriptdroid.ui.main.drawer;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.GlideApp;
import com.stardust.scriptdroid.network.UserService;
import com.stardust.scriptdroid.ui.floating.CircularMenu;
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.VersionService;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.User;
import com.stardust.scriptdroid.network.entity.user.User;
import com.stardust.scriptdroid.network.entity.VersionInfo;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.login.LoginActivity_;
import com.stardust.scriptdroid.ui.user.LoginActivity_;
import com.stardust.scriptdroid.ui.settings.SettingsActivity;
import com.stardust.scriptdroid.ui.update.UpdateInfoDialogBuilder;
import com.stardust.scriptdroid.ui.user.WebActivity;
import com.stardust.scriptdroid.ui.user.WebActivity_;
import com.stardust.scriptdroid.ui.widget.AvatarView;
import com.stardust.theme.ThemeColorManager;
import com.stardust.theme.ThemeColorManagerCompat;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.scriptdroid.sublime.SublimePluginService;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
@ -39,12 +48,9 @@ import org.androidannotations.annotations.ViewById;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.concurrent.Callable;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
@ -75,7 +81,13 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
TextView mUserName;
@ViewById(R.id.avatar)
ImageView mAvatar;
AvatarView mAvatar;
@ViewById(R.id.shadow)
View mShadow;
@ViewById(R.id.default_cover)
View mDefaultCover;
private Disposable mConnectionStateDisposable;
@ -114,26 +126,60 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
.me()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<User>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull User user) {
setUpUserInfo(user);
}
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
e.printStackTrace();
}
.subscribe(this::setUpUserInfo, error -> {
error.printStackTrace();
setUpUserInfo(null);
});
}
private void setUpUserInfo(User user) {
mUserName.setText(user.getUsername());
private void setUpUserInfo(@Nullable User user) {
if (user == null) {
mUserName.setText(R.string.not_login);
mAvatar.setIcon(R.drawable.profile_avatar_placeholder);
} else {
mUserName.setText(user.getUsername());
mAvatar.setUser(user);
}
setCoverImage(user);
}
private void setCoverImage(User user) {
if (user == null || TextUtils.isEmpty(user.getCoverUrl()) || user.getCoverUrl().equals("/assets/images/cover-default.png")) {
mDefaultCover.setVisibility(View.VISIBLE);
mShadow.setVisibility(View.GONE);
mHeaderView.setBackgroundColor(ThemeColorManagerCompat.getColorPrimary());
} else {
mDefaultCover.setVisibility(View.GONE);
mShadow.setVisibility(View.VISIBLE);
GlideApp.with(getContext())
.load(NodeBB.BASE_URL + user.getCoverUrl())
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
mHeaderView.setBackground(resource);
}
});
}
}
@Click(R.id.avatar)
void loginOrShowUserInfo() {
LoginActivity_.intent(getActivity()).start();
NodeBB.getInstance().getRetrofit()
.create(UserApi.class)
.me()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe((user -> {
WebActivity_.intent(this)
.extra(WebActivity.EXTRA_URL, NodeBB.url("user/" + user.getUserslug()))
.extra(Intent.EXTRA_TITLE, user.getUsername())
.start();
}), error -> {
LoginActivity_.intent(getActivity()).start();
});
}

View File

@ -7,7 +7,6 @@ import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageView;
@ -15,8 +14,8 @@ import android.widget.TextView;
import android.widget.Toast;
import com.stardust.scriptdroid.R;
import com.stardust.widget.PrefSwitch;
import com.stardust.widget.SwitchCompat;
import com.stardust.scriptdroid.ui.widget.PrefSwitch;
import com.stardust.scriptdroid.ui.widget.SwitchCompat;
import butterknife.BindView;
import butterknife.ButterKnife;

View File

@ -27,7 +27,7 @@ import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.floating.EditorFloaty;
import com.stardust.scriptdroid.ui.viewmodel.ScriptList;
import com.stardust.widget.BindableViewHolder;
import com.stardust.scriptdroid.ui.widget.BindableViewHolder;
import org.greenrobot.eventbus.Subscribe;
@ -307,7 +307,6 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Override
public void onBindViewHolder(BindableViewHolder<?> holder, int position) {
int positionOfCategoryFile = positionOfCategoryFile();
Log.d(LOG_TAG, String.format("view holder = %s, pos = %d, posOfCategory = %d, size = %d", holder.getClass().toString(), position, positionOfCategoryFile, mScriptList.count()));
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
// FIXME: 2017/10/20 java.lang.ClassCastException: java.lang.Boolean cannot be cast to com.stardust.scriptdroid.model.script.ScriptFile
@ -323,17 +322,14 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Override
public int getItemViewType(int position) {
int viewType;
int positionOfCategoryFile = positionOfCategoryFile();
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
viewType = VIEW_TYPE_CATEGORY;
return VIEW_TYPE_CATEGORY;
} else if (position < positionOfCategoryFile) {
viewType = VIEW_TYPE_DIRECTORY;
return VIEW_TYPE_DIRECTORY;
} else {
viewType = VIEW_TYPE_FILE;
return VIEW_TYPE_FILE;
}
Log.d(LOG_TAG, String.format("view type = %d, pos = %d, posOfCategory = %d, size = %d", viewType, position, positionOfCategoryFile, mScriptList.count()));
return viewType;
}
@Override

View File

@ -13,7 +13,7 @@ import com.stardust.autojs.core.console.StardustConsole;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
import com.stardust.widget.SimpleAdapterDataObserver;
import com.stardust.scriptdroid.ui.widget.SimpleAdapterDataObserver;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;

View File

@ -21,7 +21,7 @@ import com.stardust.scriptdroid.io.StorageFileProvider;
import com.stardust.scriptdroid.tool.IntentTool;
import com.stardust.util.DownloadTask;
import com.stardust.util.IntentUtil;
import com.stardust.widget.CommonMarkdownView;
import com.stardust.scriptdroid.ui.widget.CommonMarkdownView;
/**
* Created by Stardust on 2017/4/9.

View File

@ -0,0 +1,104 @@
package com.stardust.scriptdroid.ui.user;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.UserService;
import com.stardust.scriptdroid.ui.BaseActivity;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Stardust on 2017/9/20.
*/
@EActivity(R.layout.activity_login)
public class LoginActivity extends BaseActivity {
@ViewById(R.id.username)
TextView mUserName;
@ViewById(R.id.password)
TextView mPassword;
@AfterViews
void setUpViews() {
setToolbarAsBack(getString(R.string.text_login));
}
@Click(R.id.login)
void login() {
String userName = mUserName.getText().toString();
String password = mPassword.getText().toString();
if (!checkNotEmpty(userName, password)) {
return;
}
MaterialDialog dialog = new MaterialDialog.Builder(this)
.progress(true, 0)
.content(R.string.text_logining)
.cancelable(false)
.show();
UserService.getInstance().login(userName, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> {
dialog.dismiss();
Toast.makeText(getApplicationContext(), R.string.text_login_succeed, Toast.LENGTH_SHORT).show();
finish();
}
, error -> {
dialog.dismiss();
mPassword.setError(getString(R.string.text_login_fail));
error.printStackTrace();
});
}
@Click(R.id.forgot_password)
void forgotPassword() {
WebActivity_.intent(this)
.extra(WebActivity.EXTRA_URL, NodeBB.BASE_URL + "reset")
.extra(Intent.EXTRA_TITLE, getString(R.string.text_reset_password))
.start();
}
private boolean checkNotEmpty(String userName, String password) {
if (userName.isEmpty()) {
mUserName.setError(getString(R.string.text_username_cannot_be_empty));
return false;
}
if (password.isEmpty()) {
mUserName.setError(getString(R.string.text_password_cannot_be_empty));
return false;
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_login, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_register) {
RegisterActivity_.intent(this).start();
finish();
}
return super.onOptionsItemSelected(item);
}
}

View File

@ -0,0 +1,93 @@
package com.stardust.scriptdroid.ui.user;
import android.util.Log;
import android.util.Patterns;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.UserService;
import com.stardust.scriptdroid.ui.BaseActivity;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Stardust on 2017/10/26.
*/
@EActivity(R.layout.activity_register)
public class RegisterActivity extends BaseActivity {
@ViewById(R.id.email)
TextView mEmail;
@ViewById(R.id.username)
TextView mUserName;
@ViewById(R.id.password)
TextView mPassword;
@AfterViews
void setUpViews() {
setToolbarAsBack(getString(R.string.text_register));
}
@Click(R.id.register)
void login() {
String email = mEmail.getText().toString();
String userName = mUserName.getText().toString();
String password = mPassword.getText().toString();
if (!validateInput(email, userName, password)) {
return;
}
MaterialDialog dialog = new MaterialDialog.Builder(this)
.progress(true, 0)
.content(R.string.text_registering)
.cancelable(false)
.show();
UserService.getInstance().register(email, userName, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> {
dialog.dismiss();
onRegisterResponse(response.string());
}
, error -> {
dialog.dismiss();
mPassword.setError(getString(R.string.text_register_fail));
error.printStackTrace();
});
}
private void onRegisterResponse(String res) {
Toast.makeText(this, R.string.text_register_succeed, Toast.LENGTH_SHORT).show();
finish();
}
private boolean validateInput(String email, String userName, String password) {
if (email.isEmpty()) {
mEmail.setError(getString(R.string.text_email_cannot_be_empty));
return false;
}
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
mEmail.setError(getString(R.string.text_email_format_error));
return false;
}
if (userName.isEmpty()) {
mUserName.setError(getString(R.string.text_username_cannot_be_empty));
return false;
}
if (password.isEmpty()) {
mUserName.setError(getString(R.string.text_password_cannot_be_empty));
return false;
}
return true;
}
}

View File

@ -0,0 +1,11 @@
package com.stardust.scriptdroid.ui.user;
import com.stardust.scriptdroid.ui.BaseActivity;
/**
* Created by Stardust on 2017/10/26.
*/
public class UserDetailActivity extends WebActivity {
}

View File

@ -0,0 +1,44 @@
package com.stardust.scriptdroid.ui.user;
import android.content.Intent;
import android.support.annotation.NonNull;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.widget.EWebView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
/**
* Created by Stardust on 2017/10/26.
*/
@EActivity(R.layout.activity_web)
public class WebActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost {
public static final String EXTRA_URL = "url";
private OnActivityResultDelegate.Mediator mMediator = new OnActivityResultDelegate.Mediator();
@ViewById(R.id.eweb_view)
EWebView mEWebView;
@AfterViews
void setupViews() {
setToolbarAsBack(getIntent().getStringExtra(Intent.EXTRA_TITLE));
mEWebView.getWebView().loadUrl(getIntent().getStringExtra(EXTRA_URL));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mMediator.onActivityResult(requestCode, resultCode, data);
}
@NonNull
@Override
public OnActivityResultDelegate.Mediator getOnActivityResultDelegateMediator() {
return mMediator;
}
}

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.app.Activity;
import android.content.Context;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

View File

@ -0,0 +1,92 @@
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.makeramen.roundedimageview.RoundedImageView;
import com.nickandjerry.dynamiclayoutinflator.lib.DynamicLayoutInflator;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.GlideApp;
import com.stardust.scriptdroid.network.Glides;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.entity.user.User;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by on 2017/9/29.
*/
public class AvatarView extends FrameLayout {
@BindView(R.id.icon_text)
TextView mIconText;
@BindView(R.id.icon)
RoundedImageView mIcon;
private GradientDrawable mIconTextBackground;
public AvatarView(@NonNull Context context) {
super(context);
init();
}
public AvatarView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public AvatarView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
inflate(getContext(), R.layout.avatar_view, this);
ButterKnife.bind(this);
mIconTextBackground = (GradientDrawable) mIconText.getBackground();
}
public void setIcon(int resId) {
mIcon.setVisibility(View.VISIBLE);
mIconText.setVisibility(View.GONE);
mIcon.setImageResource(resId);
}
public void setUser(final User user) {
if (TextUtils.isEmpty(user.getPicture())) {
mIcon.setVisibility(View.GONE);
mIconText.setVisibility(View.VISIBLE);
mIconTextBackground.setColor(Color.parseColor(user.getIconBgColor()));
mIconTextBackground.setCornerRadius(getWidth() / 2);
mIconText.setText(user.getIconText());
} else {
mIcon.setVisibility(View.VISIBLE);
mIconText.setVisibility(View.GONE);
mIcon.setCornerRadius(getWidth() / 2);
GlideApp.with(getContext())
.load(NodeBB.BASE_URL + user.getPicture())
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(mIcon);
}
}
}

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;
import android.view.View;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.graphics.Color;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.support.v7.widget.AppCompatCheckBox;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.content.Intent;
@ -12,7 +12,6 @@ import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;

View File

@ -1,6 +1,7 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@ -18,19 +19,35 @@ import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.tool.ImageSelector;
import com.stardust.util.IntentUtil;
import org.androidannotations.annotations.OnActivityResult;
import org.androidannotations.annotations.ViewById;
import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
/**
* Created by Stardust on 2017/8/22.
*/
public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefreshListener {
public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefreshListener, OnActivityResultDelegate {
private static final List<String> IMAGE_TYPES = Arrays.asList("png", "jpg", "bmp");
private static final int CHOOSE_IMAGE = 42222;
private WebView mWebView;
private ProgressBar mProgressBar;
SwipeRefreshLayout mSwipeRefreshLayout;
private SwipeRefreshLayout mSwipeRefreshLayout;
public EWebView(Context context) {
super(context);
@ -46,8 +63,8 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
private void init() {
inflate(getContext(), R.layout.ewebview, this);
mWebView = (WebView) findViewById(R.id.web_view);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mSwipeRefreshLayout.setOnRefreshListener(this);
setUpWebView();
}
@ -69,9 +86,26 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
return mWebView;
}
public void evalJavaScript(String script) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebView.evaluateJavascript(script, null);
} else {
mWebView.loadUrl("javascript:" + script);
}
}
@Override
public void onRefresh() {
mWebView.reload();
Observable.timer(2, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(t -> mSwipeRefreshLayout.setRefreshing(false));
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
protected class MyWebChromeClient extends WebChromeClient {
@ -82,25 +116,28 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
mProgressBar.setProgress(newProgress);
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> valueCallback) {
}
// For Android >= 3.0
@SuppressWarnings("unchecked")
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
openFileChooser(valueCallback);
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback,
String acceptType, String capture) {
openFileChooser(valueCallback);
if (acceptType == null) {
openFileChooser(valueCallback, null);
} else {
openFileChooser(valueCallback, acceptType.split(","));
}
}
public boolean openFileChooser(ValueCallback<Uri> valueCallback,
String[] acceptType) {
if (getContext() instanceof OnActivityResultDelegate.DelegateHost &&
getContext() instanceof Activity && isImageType(acceptType)) {
chooseImage(valueCallback);
return true;
}
return false;
}
// For Android >= 5.0
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback,
@ -111,9 +148,34 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
} else {
filePathCallback.onReceiveValue(new Uri[]{value});
}
});
}, fileChooserParams.getAcceptTypes());
return true;
}
}
private void chooseImage(ValueCallback<Uri> valueCallback) {
DelegateHost delegateHost = ((OnActivityResultDelegate.DelegateHost) getContext());
Mediator mediator = delegateHost.getOnActivityResultDelegateMediator();
Activity activity = (Activity) getContext();
new ImageSelector(activity, mediator, (selector, uri) -> valueCallback.onReceiveValue(uri))
.disposable()
.select();
}
private boolean isImageType(String[] acceptTypes) {
if (acceptTypes == null) {
return false;
}
for (String acceptType : acceptTypes) {
for (String imageType : IMAGE_TYPES) {
if (acceptType.contains(imageType)) {
return true;
}
}
}
return false;
}
protected class MyWebViewClient extends WebViewClient {

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.support.annotation.Nullable;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.graphics.Canvas;

View File

@ -0,0 +1,141 @@
package com.stardust.scriptdroid.ui.widget;/*
* Copyright (C) 2015 takahirom
*
* 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 android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;
public class NestedWebView extends WebView implements NestedScrollingChild {
private int mLastY;
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private int mNestedOffsetY;
private NestedScrollingChildHelper mChildHelper;
public NestedWebView(Context context) {
this(context, null);
}
public NestedWebView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.webViewStyle);
}
public NestedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean returnValue = false;
MotionEvent event = MotionEvent.obtain(ev);
final int action = MotionEventCompat.getActionMasked(event);
if (action == MotionEvent.ACTION_DOWN) {
mNestedOffsetY = 0;
}
int eventY = (int) event.getY();
event.offsetLocation(0, mNestedOffsetY);
switch (action) {
case MotionEvent.ACTION_MOVE:
int deltaY = mLastY - eventY;
// NestedPreScroll
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
deltaY -= mScrollConsumed[1];
mLastY = eventY - mScrollOffset[1];
event.offsetLocation(0, -mScrollOffset[1]);
mNestedOffsetY += mScrollOffset[1];
}
returnValue = super.onTouchEvent(event);
// NestedScroll
if (dispatchNestedScroll(0, mScrollOffset[1], 0, deltaY, mScrollOffset)) {
event.offsetLocation(0, mScrollOffset[1]);
mNestedOffsetY += mScrollOffset[1];
mLastY -= mScrollOffset[1];
}
break;
case MotionEvent.ACTION_DOWN:
returnValue = super.onTouchEvent(event);
mLastY = eventY;
// start NestedScroll
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
returnValue = super.onTouchEvent(event);
// end NestedScroll
stopNestedScroll();
break;
}
return returnValue;
}
// Nested Scroll implements
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return mChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return mChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return mChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,
int[] offsetInWindow) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;
import android.view.View;

View File

@ -1,12 +1,10 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.preference.PreferenceManager;
import android.support.annotation.IntDef;
import android.util.AttributeSet;
import android.view.View;
import com.stardust.scriptdroid.R;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.app.Activity;
import android.app.SearchManager;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.annotation.TargetApi;
import android.content.Context;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.content.Context;
import android.util.AttributeSet;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.annotation.TargetApi;
import android.content.Context;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

View File

@ -1,4 +1,4 @@
package com.stardust.widget;
package com.stardust.scriptdroid.ui.widget;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@ -6,7 +6,6 @@ import android.view.View;
import android.view.ViewGroup;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* Created by Stardust on 2017/4/8.

View File

@ -1,54 +0,0 @@
package com.stardust.view;
import android.view.View;
import java.util.Stack;
/**
* Created by Stardust on 2017/3/11.
*/
public class ViewStack {
public interface CurrentViewSetter {
void setCurrentView(View v);
}
public interface NavigableView {
void goBack();
}
private Stack<View> mStack = new Stack<>();
private CurrentViewSetter mCurrentViewSetter;
public ViewStack(CurrentViewSetter currentViewSetter) {
mCurrentViewSetter = currentViewSetter;
}
public void navigateTo(View v) {
mStack.push(v);
mCurrentViewSetter.setCurrentView(v);
}
public boolean canGoBack() {
return mStack.size() > 1;
}
public void goBack() {
mCurrentViewSetter.setCurrentView(mStack.pop());
}
public void goBackToFirst() {
while (mStack.size() > 1) {
mStack.pop();
}
mCurrentViewSetter.setCurrentView(mStack.peek());
}
public void setRootView(View view) {
mStack.clear();
mStack.push(view);
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="25dp"/>
<size
android:width="50dp"
android:height="50dp"/>
<solid android:color="#d56"/>
</shape>

View File

@ -0,0 +1,10 @@
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<gradient
android:angle="270"
android:endColor="#7d000000"
android:startColor="#27ffffff"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -20,7 +20,7 @@
</android.support.design.widget.AppBarLayout>
<com.stardust.widget.EWebView
<com.stardust.scriptdroid.ui.widget.EWebView
android:id="@+id/eweb_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -1,158 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
android:orientation="vertical">
<com.stardust.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/text_login"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/cv"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="64dp"
app:cardCornerRadius="6dp"
app:cardElevation="3dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginTop="10dp">
<View
android:layout_width="8dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:background="#2fa881"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="50dp"
android:text="@string/text_login"
android:textColor="#FFCC00"
android:textSize="18sp"
android:textStyle="bold"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:paddingEnd="30dp"
android:paddingStart="50dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_username"
android:inputType="textPersonName"
android:textSize="16sp"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingEnd="30dp"
android:paddingStart="50dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_password"
android:inputType="textPassword"
android:textSize="16sp"
/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="25dp"
android:gravity="center">
<Button
android:id="@+id/login"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="150dp"
android:layout_height="50dp"
android:text="@string/text_login"
>
</Button>
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="@string/text_forgot_password"
android:textColor="#9a9a9a"
android:textSize="12sp"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@id/cv"
android:layout_alignTop="@id/cv"
android:layout_marginEnd="-20dp"
android:layout_marginTop="25dp"
android:src="@drawable/ic_add_white_48dp"
android:transitionName="loginFab"
app:fabSize="normal"
/>
</RelativeLayout>
android:theme="@style/AppTheme.AppBarOverlay">
<com.stardust.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/text_login"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
</LinearLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="12dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_username"
android:textColor="#dd000000"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_password"
android:inputType="textPassword"
android:textColor="#dd000000"/>
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:id="@+id/forgot_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="horizontal"
android:padding="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_forgot_password"
android:textColor="#929397"
android:textSize="12sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_reset_password"
android:textColor="@color/colorAccent"
android:textSize="12sp"/>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/colorPrimary"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:padding="12dp"
android:text="@string/text_login"
android:textColor="@android:color/white"
android:textSize="15sp"/>
</FrameLayout>

View File

@ -44,36 +44,29 @@
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<FrameLayout
<com.stardust.theme.widget.ThemeColorFloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end|bottom"
android:layout_margin="16dp"
android:src="@drawable/ic_add_white_48dp"
app:backgroundTint="@color/colorPrimary"
app:layout_anchor="@id/viewpager"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.stardust.scriptdroid.ui.widget.ScrollAwareFABBehavior"/>
<com.stardust.scriptdroid.ui.main.FloatingActionMenu
android:id="@+id/floating_action_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end|bottom"
android:layout_margin="16dp"
android:clipChildren="false"
android:clipToPadding="false"
android:visibility="invisible"
app:layout_anchor="@id/viewpager"
app:layout_anchorGravity="bottom|right|end"
>
<com.stardust.scriptdroid.ui.main.FloatingActionMenu
android:id="@+id/floating_action_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end|bottom"
android:clipChildren="false"
android:clipToPadding="false"
android:visibility="invisible"/>
<com.stardust.theme.widget.ThemeColorFloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end|bottom"
android:clickable="true"
android:src="@drawable/ic_add_white_48dp"
app:backgroundTint="@color/colorPrimary"
app:layout_behavior="com.stardust.widget.ScrollAwareFABBehavior"/>
</FrameLayout>
app:layout_anchorGravity="bottom|right|end"/>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<com.stardust.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/text_login"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="12dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_email"
android:inputType="textEmailAddress"
android:textColor="#dd000000"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_username"
android:textColor="#dd000000"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_password"
android:inputType="textPassword"
android:textColor="#dd000000"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<TextView
android:id="@+id/register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/colorPrimary"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:padding="12dp"
android:text="@string/text_register"
android:textColor="@android:color/white"
android:textSize="15sp"/>
</FrameLayout>

View File

@ -27,7 +27,7 @@
android:layout_gravity="right"
android:orientation="horizontal">
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/edit"
android:layout_width="40dp"
android:layout_height="match_parent"
@ -35,7 +35,7 @@
app:icon_color="@android:color/white"
app:text="@string/text_edit"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/run"
android:layout_width="40dp"
android:layout_height="match_parent"

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<com.stardust.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/text_login"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<com.stardust.scriptdroid.ui.main.community.CommunityWebView
android:id="@+id/eweb_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/icon_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/avatar_view_bg"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="20sp"
android:visibility="gone"
tools:text="A"/>
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="@drawable/profile_avatar_placeholder"
app:riv_mutate_background="true"
app:riv_oval="true"/>
</FrameLayout>

View File

@ -27,7 +27,7 @@
android:textColor="@android:color/primary_text_light"
android:textSize="18sp"/>
<com.stardust.widget.CommonMarkdownView
<com.stardust.scriptdroid.ui.widget.CommonMarkdownView
android:id="@+id/release_notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

View File

@ -39,7 +39,7 @@
android:textSize="14sp"
tools:text="@string/text_auto_operate_service"/>
<com.stardust.widget.PrefSwitch
<com.stardust.scriptdroid.ui.widget.PrefSwitch
android:id="@+id/sw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -31,7 +31,7 @@
android:layout_gravity="right"
android:orientation="horizontal">
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/run"
android:layout_width="40dp"
android:layout_height="match_parent"
@ -39,21 +39,21 @@
app:icon_color="@android:color/white"
app:text="@string/text_run"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/undo"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_undo_white_48dp"
app:text="@string/text_undo"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/redo"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_redo_white_48dp"
app:text="@string/text_redo"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/save"
android:layout_width="40dp"
android:layout_height="match_parent"
@ -70,21 +70,21 @@
android:layout_gravity="right"
android:orientation="horizontal">
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/replace"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_ali_replace"
app:text="@string/text_replace"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/find_prev"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_ali_up"
app:text="@string/text_find_prev"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/find_next"
android:layout_width="40dp"
android:layout_height="match_parent"
@ -92,7 +92,7 @@
app:text="@string/text_find_next"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/cancel"
android:layout_width="40dp"
android:layout_height="match_parent"
@ -161,7 +161,7 @@
</LinearLayout>
<com.stardust.widget.EWebView
<com.stardust.scriptdroid.ui.widget.EWebView
android:id="@+id/docs"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -10,7 +10,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
<com.stardust.scriptdroid.ui.widget.NestedWebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -20,7 +20,7 @@
android:paddingBottom="16dp"
android:paddingTop="16dp">
<com.stardust.widget.CheckBoxCompat
<com.stardust.scriptdroid.ui.widget.CheckBoxCompat
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -20,7 +20,7 @@
android:orientation="horizontal"
android:padding="8dp">
<com.stardust.widget.CheckBoxCompat
<com.stardust.scriptdroid.ui.widget.CheckBoxCompat
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -14,14 +14,14 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/close"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_close_white_48dp"
app:text="@string/text_close"/>
<com.stardust.widget.ToolbarMenuItem
<com.stardust.scriptdroid.ui.widget.ToolbarMenuItem
android:id="@+id/move_or_resize"
android:layout_width="40dp"
android:layout_height="match_parent"

View File

@ -63,7 +63,7 @@
android:background="#cccccc"/>
<com.stardust.widget.EWebView
<com.stardust.scriptdroid.ui.widget.EWebView
android:id="@+id/eweb_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -16,18 +16,21 @@
android:layout_height="170dp"
android:layout_marginBottom="5dp">
<com.makeramen.roundedimageview.RoundedImageView
<View
android:id="@+id/shadow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/drawer_header_shadow"
android:visibility="gone"/>
<com.stardust.scriptdroid.ui.widget.AvatarView
android:id="@+id/avatar"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_above="@+id/username"
android:layout_marginBottom="16dp"
android:layout_marginLeft="8dp"
android:scaleType="fitXY"
android:src="@drawable/profile_avatar_placeholder"
app:riv_border_color="#77f2f3f5"
app:riv_border_width="0.5dp"
app:riv_corner_radius="40dp"/>
android:layout_marginBottom="8dp"
android:layout_marginLeft="12dp"
android:scaleType="fitXY"/>
<TextView
android:id="@+id/username"
@ -35,24 +38,23 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="12dp"
android:layout_marginBottom="12dp"
android:layout_marginLeft="20dp"
android:gravity="center"
android:text="@string/not_login"
android:textColor="@android:color/white"
android:textSize="14sp"/>
android:textSize="16sp"/>
<ImageView
android:id="@+id/default_cover"
android:layout_width="match_parent"
android:layout_height="118dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="-12dp"
android:layout_toRightOf="@+id/avatar"
android:alpha="0.08"
android:src="@drawable/android_eating_half"
android:tint="#000000"/>
</RelativeLayout>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<com.stardust.widget.EWebView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/eweb_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.stardust.scriptdroid.ui.widget.EWebView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/eweb_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

View File

@ -6,7 +6,7 @@
android:layout_height="32dp"
android:padding="5dp">
<com.stardust.widget.LevelBeamView
<com.stardust.scriptdroid.ui.widget.LevelBeamView
android:id="@+id/dataItemLevelBeam"
android:layout_width="wrap_content"
android:layout_height="32dp"/>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_register"
android:icon="@drawable/ic_ali_register"
android:title="@string/text_register"
app:showAsAction="always"/>
</menu>

View File

@ -200,7 +200,7 @@
<string name="text_username">用户名</string>
<string name="text_password">密码</string>
<string name="text_login">登录</string>
<string name="text_forgot_password">忘记密码</string>
<string name="text_forgot_password">忘记密码?</string>
<string name="text_username_cannot_be_empty">用户名不能为空</string>
<string name="text_password_cannot_be_empty">密码不能为空</string>
<string name="text_time">时间</string>
@ -264,6 +264,17 @@
<string name="text_floating_edit">悬浮编辑</string>
<string name="text_select_icon">选择图标</string>
<string name="text_use_android_n_shortcut">添加到图标快捷方式</string>
<string name="text_login_succeed">登录成功</string>
<string name="text_login_fail">登录失败</string>
<string name="text_reset_password">重置密码</string>
<string name="text_logining">登录中</string>
<string name="text_register">注册</string>
<string name="text_email">邮箱</string>
<string name="text_email_cannot_be_empty">邮箱不能为空</string>
<string name="text_email_format_error">邮箱格式错误</string>
<string name="text_registering">注册中</string>
<string name="text_register_fail">注册失败</string>
<string name="text_register_succeed">注册成功</string>
<string-array name="ad_showing_mode_keys">

View File

@ -3,6 +3,8 @@ package com.stardust.scriptdroid;
import org.junit.Test;
import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
@ -20,28 +22,10 @@ public class ExampleUnitTest {
@Test
public void test() {
Observable.fromCallable(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread());
return "";
}
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.doOnComplete(new Action() {
@Override
public void run() throws Exception {
System.out.println(Thread.currentThread());
}
})
.observeOn(Schedulers.newThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
System.out.println(Thread.currentThread());
}
});
Matcher matcher = Pattern.compile("[0-9]+").matcher("2937Finish!");
if (matcher.find()) {
System.out.println(matcher.group());
}
}
@Test

View File

@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 17

View File

@ -20,6 +20,9 @@ import com.stardust.automator.simple_action.SimpleAction;
import com.stardust.util.DeveloperUtils;
import com.stardust.util.ScreenMetrics;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeJavaObject;
/**
* Created by Stardust on 2017/4/2.
*/

View File

@ -14,6 +14,7 @@ import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow;
import com.stardust.util.UiHandler;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@ -67,7 +68,7 @@ public class StardustConsole extends AbstractConsole {
private LogListener mLogListener;
private UiHandler mUiHandler;
private BlockingQueue<String> mInput = new ArrayBlockingQueue<>(1);
private ConsoleView mConsoleView;
private WeakReference<ConsoleView> mConsoleView;
private volatile boolean mShown = false;
public StardustConsole(UiHandler uiHandler) {
@ -88,7 +89,7 @@ public class StardustConsole extends AbstractConsole {
}
public void setConsoleView(ConsoleView consoleView) {
mConsoleView = consoleView;
mConsoleView = new WeakReference<>(consoleView);
setLogListener(consoleView);
synchronized (this) {
this.notify();
@ -177,13 +178,13 @@ public class StardustConsole extends AbstractConsole {
@ScriptInterface
public String rawInput() {
if (mConsoleView == null) {
if (mConsoleView == null || mConsoleView.get() == null) {
if (!mShown) {
show();
}
waitForConsoleView();
}
mConsoleView.showEditText();
mConsoleView.get().showEditText();
try {
return mInput.take();
} catch (InterruptedException e) {

View File

@ -56,7 +56,7 @@ public class InputEventToAutoFileRecorder extends InputEventRecorder {
public void recordInputEvent(@NonNull InputEventObserver.InputEvent event) {
try {
convertEventOrThrow(event);
//Log.d(LOG_TAG, "recordInputEvent: " + event);
Log.d(LOG_TAG, "recordInputEvent: " + event);
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -3,14 +3,23 @@ package com.stardust.autojs.engine;
import android.content.Context;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.Patterns;
import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.api.ProcessShell;
import com.stardust.autojs.core.inputevent.InputDevices;
import com.stardust.autojs.runtime.exception.ScriptException;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.script.AutoFileSource;
import com.stardust.pio.PFiles;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Stardust on 2017/8/1.
@ -22,6 +31,7 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
private static final String KEY_TOUCH_DEVICE = RootAutomatorEngine.class.getName() + ".touch_device";
private static final String LOG_TAG = "RootAutomatorEngine";
private static final Pattern PID_PATTERN = Pattern.compile("[0-9]{2,}");
private static int sTouchDevice = -1;
private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator";
@ -30,6 +40,8 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
private String mDeviceNameOrPath;
private Thread mThread;
private String mExecutablePath;
private String mPid;
private Process mProcess;
public RootAutomatorEngine(Context context, String deviceNameOrPath) {
mContext = context;
@ -44,11 +56,49 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
public void execute(String autoFile) {
mExecutablePath = getExecutablePath(mContext);
Log.d(LOG_TAG, "exec: " + autoFile);
AbstractShell.Result result = ProcessShell.execCommand(new String[]{
"chmod 777 " + mExecutablePath,
mExecutablePath + " \"" + autoFile + "\" -d " + mDeviceNameOrPath
}, true);
Log.d(LOG_TAG, "result = " + result);
final String[] commands = {
"chmod 755 " + mExecutablePath,
String.format("\"%s\" \"%s\" -d \"%s\" &", mExecutablePath, autoFile, mDeviceNameOrPath), // to run root_automator
"echo $!", // to print the root_automator pid
"exit", // to exit su
"exit" // to exit shell
};
try {
mProcess = Runtime.getRuntime().exec("su");
executeCommands(mProcess, commands);
mPid = readPid(mProcess);
mProcess.waitFor();
} catch (IOException e) {
throw new ScriptException(e);
} catch (InterruptedException e) {
throw new ScriptInterruptedException();
} finally {
mProcess.destroy();
mProcess = null;
}
}
private String readPid(Process process) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
Matcher matcher = PID_PATTERN.matcher(line);
if (matcher.find()) {
return matcher.group();
}
}
return null;
}
private void executeCommands(Process process, String[] commands) throws IOException {
DataOutputStream os = new DataOutputStream(process.getOutputStream());
for (String command : commands) {
if (command != null) {
os.write(command.getBytes());
os.writeBytes("\n");
}
}
os.flush();
}
@ -96,7 +146,9 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
@Override
public void forceStop() {
mThread.interrupt();
ProcessShell.exec("killall " + mExecutablePath, true);
if (mPid != null) {
ProcessShell.exec("kill " + mPid, true);
}
}
@Override

View File

@ -226,7 +226,7 @@ public class ProcessShell extends AbstractShell {
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(line).append('\n');
}
return builder.toString();
}

View File

@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 17

View File

@ -3,11 +3,11 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4'
classpath 'me.tatarka:gradle-retrolambda:3.7.0'
}
}

View File

@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 17

Some files were not shown because too many files have changed in this diff Show More