Added Script file chooser. Fixed the issue that background image setting not working

This commit is contained in:
hyb1996
2017-04-03 16:28:07 +08:00
parent bfabef6a0e
commit 59811a4a5d
53 changed files with 1465 additions and 530 deletions

View File

@@ -13,8 +13,6 @@ import com.stardust.scriptdroid.autojs.AutoJs;
public class Pref {
private static final SharedPreferences DISPOSABLE_BOOLEAN = App.getApp().getSharedPreferences("DISPOSABLE_BOOLEAN", Context.MODE_PRIVATE);
public static final String KEY_DRAWER_HEADER_IMAGE_PATH = "KEY_DRAWER_HEADER_IMAGE_PATH";
public static final String KEY_APP_BAR_IMAGE_PATH = "KEY_APP_BAR_IMAGE_PATH";
private static SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
@@ -84,22 +82,6 @@ public class Pref {
return getDisposableBoolean("isFirstUsing", true);
}
public static String getDrawerHeaderImagePath() {
return def().getString(KEY_DRAWER_HEADER_IMAGE_PATH, null);
}
public static void setDrawerHeaderImagePath(String path) {
def().edit().putString(KEY_DRAWER_HEADER_IMAGE_PATH, path).apply();
}
public static String getAppBarImagePath() {
return def().getString(KEY_APP_BAR_IMAGE_PATH, null);
}
public static void setAppBarImagePath(String path) {
def().edit().putString(KEY_APP_BAR_IMAGE_PATH, path).apply();
}
static {
def().registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
}

View File

@@ -1,5 +1,7 @@
package com.stardust.scriptdroid.external;
import android.os.Bundle;
/**
* Created by Stardust on 2017/4/1.
*/
@@ -10,5 +12,8 @@ public class CommonUtils {
public static final String EXTRA_KEY_PREPARE_SCRIPT = "script";
public static boolean isTaskerBundleValid(Bundle bundle) {
return bundle.containsKey(CommonUtils.EXTRA_KEY_PATH);
}
}

View File

@@ -23,19 +23,16 @@ public class FireSettingReceiver extends AbstractPluginSettingReceiver {
@Override
protected boolean isBundleValid(@NonNull Bundle bundle) {
Log.v(TAG, "isBundleValid: " + bundle);
return bundle.containsKey(CommonUtils.EXTRA_KEY_PATH);
return CommonUtils.isTaskerBundleValid(bundle);
}
@Override
protected boolean isAsync() {
Log.v(TAG, "isAsync");
return true;
}
@Override
protected void firePluginSetting(@NonNull Context context, @NonNull Bundle bundle) {
Log.v(TAG, "firePluginSetting" + bundle);
context.startActivity(new Intent(App.getApp(), RunIntentActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(CommonUtils.EXTRA_KEY_PATH, bundle.getString(CommonUtils.EXTRA_KEY_PATH))

View File

@@ -9,7 +9,8 @@ import android.util.Log;
import com.stardust.scriptdroid.scripts.ScriptFile;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.CommonUtils;
import com.stardust.scriptdroid.ui.main.my_script_list.ScriptAndFolderListRecyclerView;
import com.stardust.scriptdroid.ui.main.script_list.ScriptAndFolderListRecyclerView;
import com.stardust.scriptdroid.ui.main.script_list.ScriptListWithProgressBarView;
import com.twofortyfouram.locale.sdk.client.ui.activity.AbstractPluginActivity;
/**
@@ -18,20 +19,19 @@ import com.twofortyfouram.locale.sdk.client.ui.activity.AbstractPluginActivity;
public class TaskPrefEditActivity extends AbstractPluginActivity {
private static final String TAG = "TaskPrefEditActivity";
private String mSelectedScriptFilePath;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate");
setContentView(R.layout.activity_tasker_edit);
initScriptListRecyclerView();
}
private void initScriptListRecyclerView() {
ScriptAndFolderListRecyclerView scriptListRecyclerView = (ScriptAndFolderListRecyclerView) findViewById(R.id.script_list);
scriptListRecyclerView.setOnItemClickListener(new ScriptAndFolderListRecyclerView.OnScriptFileClickListener() {
ScriptListWithProgressBarView scriptListWithProgressBarView = (ScriptListWithProgressBarView) findViewById(R.id.script_list);
scriptListWithProgressBarView.setScriptFileOperationEnabled(false);
scriptListWithProgressBarView.setOnItemClickListener(new ScriptAndFolderListRecyclerView.OnScriptFileClickListener() {
@Override
public void onClick(ScriptFile file) {
mSelectedScriptFilePath = file.getPath();
@@ -43,22 +43,17 @@ public class TaskPrefEditActivity extends AbstractPluginActivity {
@Override
public boolean isBundleValid(@NonNull Bundle bundle) {
boolean valid = bundle.getString(CommonUtils.EXTRA_KEY_PATH) != null;
Log.v(TAG, "isBundleValid: " + valid);
Context context;
return valid;
return CommonUtils.isTaskerBundleValid(bundle);
}
@Override
public void onPostCreateWithPreviousResult(@NonNull Bundle bundle, @NonNull String s) {
Log.v(TAG, "onPostCreateWithPreviousResult: bundle=" + bundle + " str=" + s);
mSelectedScriptFilePath = bundle.getString(CommonUtils.EXTRA_KEY_PATH);
}
@Nullable
@Override
public Bundle getResultBundle() {
Log.v(TAG, "getResultBundle");
Bundle bundle = new Bundle();
bundle.putString(CommonUtils.EXTRA_KEY_PATH, mSelectedScriptFilePath);
return bundle;
@@ -67,7 +62,6 @@ public class TaskPrefEditActivity extends AbstractPluginActivity {
@NonNull
@Override
public String getResultBlurb(@NonNull Bundle bundle) {
Log.v(TAG, "getResultBlurb");
return bundle.getString(CommonUtils.EXTRA_KEY_PATH, getString(R.string.text_path_is_empty));
}
}

View File

@@ -178,7 +178,7 @@ public class LayoutHierarchyView extends MultiLevelListView {
NodeInfo nodeInfo = (NodeInfo) object;
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.layout_hierarchy_view_item, null);
convertView = LayoutInflater.from(getContext()).inflate(R.layout.layout_hierarchy_view_item, LayoutHierarchyView.this, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {

View File

@@ -6,9 +6,12 @@ import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.util.FileSorter;
import com.stardust.util.LimitedHashMap;
import com.stardust.util.MapEntries;
import org.greenrobot.eventbus.EventBus;
import java.util.Map;
/**
* Created by Stardust on 2017/3/31.
*/
@@ -29,11 +32,19 @@ public class StorageScriptProvider {
public static final ScriptFile DEFAULT_DIRECTORY = new ScriptFile(DEFAULT_DIRECTORY_PATH);
private static StorageScriptProvider instance = new StorageScriptProvider();
private static StorageScriptProvider defaultProvider = new StorageScriptProvider();
public static StorageScriptProvider getDefault() {
return instance;
return defaultProvider;
}
private static StorageScriptProvider externalStorageProvider;
public static StorageScriptProvider getExternalStorageProvider() {
if (externalStorageProvider == null) {
externalStorageProvider = new StorageScriptProvider(Environment.getExternalStorageDirectory().getPath(), 5);
}
return externalStorageProvider;
}
private EventBus mDirectoryEventBus = new EventBus();
@@ -47,7 +58,6 @@ public class StorageScriptProvider {
public StorageScriptProvider(ScriptFile initialDirectory, int cacheSize) {
mInitialDirectory = initialDirectory;
mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner();
mScriptFileCache = new LimitedHashMap<>(cacheSize);
}
@@ -57,7 +67,7 @@ public class StorageScriptProvider {
public void notifyDirectoryChanged(ScriptFile directory) {
if (directory.equals(mInitialDirectory)) {
mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner();
mInitialDirectoryScriptFiles = getInitialDirectoryScriptFiles();
} else {
clearCache(directory);
}
@@ -66,15 +76,28 @@ public class StorageScriptProvider {
public void notifyStoragePermissionGranted() {
mScriptFileCache.clear();
mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner();
mInitialDirectoryScriptFiles = null;
mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory));
}
public void refreshAll() {
Map<String, ScriptFile> files = (Map<String, ScriptFile>) mScriptFileCache.clone();
mScriptFileCache.clear();
mInitialDirectoryScriptFiles = null;
mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory));
for (Map.Entry<String, ScriptFile> file : files.entrySet()) {
mDirectoryEventBus.post(new DirectoryChangeEvent(new ScriptFile(file.getKey())));
}
}
public ScriptFile getInitialDirectory() {
return mInitialDirectory;
}
public ScriptFile[] getInitialDirectoryScriptFiles() {
if (mInitialDirectoryScriptFiles == null) {
mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner();
}
return mInitialDirectoryScriptFiles;
}
@@ -84,7 +107,7 @@ public class StorageScriptProvider {
public ScriptFile[] getDirectoryScriptFiles(ScriptFile directory) {
if (directory.equals(mInitialDirectory)) {
return mInitialDirectoryScriptFiles;
return getInitialDirectoryScriptFiles();
}
ScriptFile[] scriptFiles = getScriptFilesFromCache(directory);
if (scriptFiles == null) {
@@ -93,6 +116,10 @@ public class StorageScriptProvider {
return scriptFiles;
}
public void clearCacheExceptInitialDirectory() {
mScriptFileCache.clear();
}
private void clearCache(ScriptFile directory) {
mScriptFileCache.remove(directory.getPath());
}
@@ -119,7 +146,8 @@ public class StorageScriptProvider {
public void registerDirectoryChangeListener(Object subscriber) {
mDirectoryEventBus.register(subscriber);
if (!mDirectoryEventBus.isRegistered(subscriber))
mDirectoryEventBus.register(subscriber);
}
public void unregisterDirectoryChangeListener(Object subscriber) {

View File

@@ -0,0 +1,141 @@
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.PFile;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.Callable;
/**
* Created by Stardust on 2017/4/3.
*/
public abstract class DrawableSaver {
private static final String PREFIX = "saved_drawable_";
protected Drawable mOriginalDrawble;
private Context mContext;
private String mName;
public DrawableSaver(Context context, String name, Drawable originalDrawble) {
mContext = context;
mName = PREFIX + name;
mOriginalDrawble = originalDrawble;
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);
PFile.write(inputStream, outputStream);
outputStream.close();
inputStream.close();
callback.run();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public void select(Activity activity, final OnActivityResultDelegate.Intermediary intermediary) {
new ImageSelector(activity, intermediary, new ImageSelector.ImageSelectorCallback() {
@Override
public void onImageSelected(ImageSelector selector, InputStream inputStream) {
if (inputStream != null)
setDrawable(inputStream);
intermediary.removeDelegate(selector);
}
}).select();
}
public void reset() {
applyDrawableToView(mOriginalDrawble);
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

@@ -9,6 +9,9 @@ import android.provider.MediaStore;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.scriptdroid.R;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* Created by Stardust on 2017/3/5.
*/
@@ -16,7 +19,7 @@ import com.stardust.scriptdroid.R;
public class ImageSelector implements OnActivityResultDelegate {
public interface ImageSelectorCallback {
void onImageSelected(ImageSelector selector, String path);
void onImageSelected(ImageSelector selector, InputStream path);
}
private static final int REQUEST_CODE = "LOVE EATING".hashCode() >> 16;
@@ -38,19 +41,16 @@ public class ImageSelector implements OnActivityResultDelegate {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null)
if (data == null) {
mCallback.onImageSelected(this, null);
return;
Uri selectedImageUri = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = mActivity.getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
mCallback.onImageSelected(this, filePath);
}
try {
InputStream inputStream = mActivity.getContentResolver().openInputStream(data.getData());
mCallback.onImageSelected(this, inputStream);
} catch (FileNotFoundException e) {
mCallback.onImageSelected(this, null);
}
}

View File

@@ -24,7 +24,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
* Created by Stardust on 2017/1/23.
*/
public class BaseActivity extends AppCompatActivity {
public abstract class BaseActivity extends AppCompatActivity {
protected static final int PERMISSION_REQUEST_CODE = 11186;
private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer();

View File

@@ -17,7 +17,7 @@ import java.util.Map;
/**
* Created by Stardust on 2017/1/30.
*/
public class Editor920Activity extends IActivity {
public abstract class Editor920Activity extends IActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {

View File

@@ -0,0 +1,642 @@
package com.stardust.scriptdroid.ui.error;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringDef;
import android.support.annotation.StringRes;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.github.aakira.expandablelayout.ExpandableRelativeLayout;
import com.heinrichreimersoftware.androidissuereporter.model.DeviceInfo;
import com.heinrichreimersoftware.androidissuereporter.model.Report;
import com.heinrichreimersoftware.androidissuereporter.model.github.ExtraInfo;
import com.heinrichreimersoftware.androidissuereporter.model.github.GithubLogin;
import com.heinrichreimersoftware.androidissuereporter.model.github.GithubTarget;
import com.heinrichreimersoftware.androidissuereporter.util.ColorUtils;
import com.heinrichreimersoftware.androidissuereporter.util.ThemeUtils;
import org.eclipse.egit.github.core.Issue;
import org.eclipse.egit.github.core.client.GitHubClient;
import org.eclipse.egit.github.core.client.RequestException;
import org.eclipse.egit.github.core.service.IssueService;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import static android.util.Patterns.EMAIL_ADDRESS;
import com.heinrichreimersoftware.androidissuereporter.R;
import com.stardust.theme.ThemeColorManager;
/**
* Created by Stardust on 2017/4/3.
*/
public abstract class AbstractIssueReporterActivity extends AppCompatActivity {
private static final String TAG = AbstractIssueReporterActivity.class.getSimpleName();
private static final int STATUS_BAD_CREDENTIALS = 401;
private static final int STATUS_ISSUES_NOT_ENABLED = 410;
private boolean mCrash = false;
private boolean mReportFailed = true;
@StringDef({RESULT_OK, RESULT_BAD_CREDENTIALS, RESULT_INVALID_TOKEN, RESULT_ISSUES_NOT_ENABLED,
RESULT_UNKNOWN})
@Retention(RetentionPolicy.SOURCE)
private @interface Result {
}
private static final String RESULT_OK = "RESULT_OK";
private static final String RESULT_BAD_CREDENTIALS = "RESULT_BAD_CREDENTIALS";
private static final String RESULT_INVALID_TOKEN = "RESULT_INVALID_TOKEN";
private static final String RESULT_ISSUES_NOT_ENABLED = "RESULT_ISSUES_NOT_ENABLED";
private static final String RESULT_UNKNOWN = "RESULT_UNKNOWN";
private boolean emailRequired = false;
private int bodyMinChar = 0;
private Toolbar toolbar;
private TextInputEditText inputTitle;
private TextInputEditText inputDescription;
private TextView textDeviceInfo;
private ImageButton buttonDeviceInfo;
private ExpandableRelativeLayout layoutDeviceInfo;
private ExpandableRelativeLayout layoutAnonymous;
private TextInputEditText inputUsername;
private TextInputEditText inputPassword;
private TextInputEditText inputEmail;
private RadioButton optionUseAccount;
private RadioButton optionAnonymous;
private ExpandableRelativeLayout layoutLogin;
private FloatingActionButton buttonSend;
private Drawable optionUseAccountButtonDrawable = null;
private String token;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (TextUtils.isEmpty(getTitle()))
setTitle(R.string.air_title_report_issue);
setContentView(com.stardust.scriptdroid.R.layout.air_activity_issue_reporter);
findViews();
//noinspection deprecation
token = getGuestToken();
initViews();
DeviceInfo deviceInfo = new DeviceInfo(this);
textDeviceInfo.setText(deviceInfo.toString());
handleIntent();
optionAnonymous.post(new Runnable() {
@Override
public void run() {
optionAnonymous.performClick();
}
});
}
private void handleIntent() {
final String errorDetail = getIntent().getStringExtra("error");
if (errorDetail != null) {
inputDescription.setText(errorDetail);
String title = getFirstLine(errorDetail);
inputTitle.setText(title);
mCrash = true;
}
}
private String getFirstLine(String str) {
int i = str.indexOf('\n');
if (i < 0)
return str;
return str.substring(0, i);
}
private void findViews() {
toolbar = (Toolbar) findViewById(R.id.air_toolbar);
inputTitle = (TextInputEditText) findViewById(R.id.air_inputTitle);
inputDescription = (TextInputEditText) findViewById(R.id.air_inputDescription);
textDeviceInfo = (TextView) findViewById(R.id.air_textDeviceInfo);
buttonDeviceInfo = (ImageButton) findViewById(R.id.air_buttonDeviceInfo);
layoutDeviceInfo = (ExpandableRelativeLayout) findViewById(R.id.air_layoutDeviceInfo);
inputUsername = (TextInputEditText) findViewById(R.id.air_inputUsername);
inputPassword = (TextInputEditText) findViewById(R.id.air_inputPassword);
inputEmail = (TextInputEditText) findViewById(R.id.air_inputEmail);
optionUseAccount = (RadioButton) findViewById(R.id.air_optionUseAccount);
optionAnonymous = (RadioButton) findViewById(R.id.air_optionAnonymous);
layoutLogin = (ExpandableRelativeLayout) findViewById(R.id.air_layoutLogin);
layoutAnonymous = (ExpandableRelativeLayout) findViewById(R.id.air_layoutGuest);
buttonSend = (FloatingActionButton) findViewById(R.id.air_buttonSend);
}
private void initViews() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ThemeColorManager.getColorPrimary());
}
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(com.stardust.scriptdroid.R.string.text_issue_report);
}
toolbar.setBackgroundColor(ThemeColorManager.getColorPrimary());
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
buttonDeviceInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
layoutDeviceInfo.toggle();
}
});
inputPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND) {
reportIssue();
return true;
}
return false;
}
});
updateGuestTokenViews();
buttonSend.setImageResource(ColorUtils.isDark(ThemeUtils.getColorAccent(this)) ?
R.drawable.air_ic_send_dark : R.drawable.air_ic_send_light);
buttonSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
reportIssue();
} catch (Exception e) {
e.printStackTrace();
mReportFailed = true;
finish();
}
}
});
}
private void setOptionUseAccountMarginStart(int marginStart) {
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) optionUseAccount.getLayoutParams();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
layoutParams.setMarginStart(marginStart);
} else {
layoutParams.leftMargin = marginStart;
}
optionUseAccount.setLayoutParams(layoutParams);
}
private void updateGuestTokenViews() {
if (TextUtils.isEmpty(token)) {
int baseline = getResources().getDimensionPixelSize(R.dimen.air_baseline);
int radioButtonPaddingStart = getResources().getDimensionPixelSize(R.dimen.air_radio_button_padding_start);
setOptionUseAccountMarginStart(-2 * baseline - radioButtonPaddingStart);
optionUseAccount.setEnabled(false);
optionAnonymous.setVisibility(View.GONE);
} else {
setOptionUseAccountMarginStart(0);
optionUseAccount.setEnabled(true);
optionUseAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
layoutLogin.expand();
layoutAnonymous.collapse();
inputUsername.setEnabled(true);
inputPassword.setEnabled(true);
}
});
optionAnonymous.setVisibility(View.VISIBLE);
optionAnonymous.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
layoutLogin.collapse();
layoutAnonymous.expand();
inputUsername.setEnabled(false);
inputPassword.setEnabled(false);
}
});
}
}
private void reportIssue() {
if (!validateInput()) return;
if (optionUseAccount.isChecked()) {
String username = inputUsername.getText().toString();
String password = inputPassword.getText().toString();
sendBugReport(new GithubLogin(username, password), null);
} else {
if (TextUtils.isEmpty(token))
throw new IllegalStateException("You must provide a GitHub API Token.");
String email = null;
if (!TextUtils.isEmpty(inputEmail.getText()) &&
EMAIL_ADDRESS.matcher(inputEmail.getText().toString()).matches()) {
email = inputEmail.getText().toString();
}
sendBugReport(new GithubLogin(token), email);
}
}
private boolean validateInput() {
boolean hasErrors = false;
if (optionUseAccount.isChecked()) {
if (TextUtils.isEmpty(inputUsername.getText())) {
setError(inputUsername, R.string.air_error_no_username);
hasErrors = true;
} else {
removeError(inputUsername);
}
if (TextUtils.isEmpty(inputPassword.getText())) {
setError(inputPassword, R.string.air_error_no_password);
hasErrors = true;
} else {
removeError(inputPassword);
}
} else {
if (emailRequired) {
if (TextUtils.isEmpty(inputEmail.getText()) ||
!EMAIL_ADDRESS.matcher(inputEmail.getText().toString()).matches()) {
setError(inputEmail, R.string.air_error_no_email);
hasErrors = true;
} else {
removeError(inputEmail);
}
}
}
if (TextUtils.isEmpty(inputTitle.getText())) {
setError(inputTitle, R.string.air_error_no_title);
hasErrors = true;
} else {
removeError(inputTitle);
}
if (TextUtils.isEmpty(inputDescription.getText())) {
setError(inputDescription, R.string.air_error_no_description);
hasErrors = true;
} else {
if (bodyMinChar > 0) {
if (inputDescription.getText().toString().length() < bodyMinChar) {
setError(inputDescription, getResources().getQuantityString(R.plurals.air_error_short_description, bodyMinChar, bodyMinChar));
hasErrors = true;
} else {
removeError(inputDescription);
}
} else
removeError(inputDescription);
}
return !hasErrors;
}
private void setError(TextInputEditText editText, @StringRes int errorRes) {
try {
View layout = (View) editText.getParent();
while (!layout.getClass().getSimpleName().equals(TextInputLayout.class.getSimpleName()))
layout = (View) layout.getParent();
TextInputLayout realLayout = (TextInputLayout) layout;
realLayout.setError(getString(errorRes));
} catch (ClassCastException | NullPointerException e) {
Log.e(TAG, "Issue while setting error UI.", e);
}
}
private void setError(TextInputEditText editText, String error) {
try {
View layout = (View) editText.getParent();
while (!layout.getClass().getSimpleName().equals(TextInputLayout.class.getSimpleName()))
layout = (View) layout.getParent();
TextInputLayout realLayout = (TextInputLayout) layout;
realLayout.setError(error);
} catch (ClassCastException | NullPointerException e) {
Log.e(TAG, "Issue while setting error UI.", e);
}
}
private void removeError(TextInputEditText editText) {
try {
View layout = (View) editText.getParent();
while (!layout.getClass().getSimpleName().equals(TextInputLayout.class.getSimpleName()))
layout = (View) layout.getParent();
TextInputLayout realLayout = (TextInputLayout) layout;
realLayout.setError(null);
} catch (ClassCastException | NullPointerException e) {
Log.e(TAG, "Issue while removing error UI.", e);
}
}
private void sendBugReport(GithubLogin login, String email) {
if (!validateInput()) return;
String bugTitle = inputTitle.getText().toString();
String bugDescription = inputDescription.getText().toString();
DeviceInfo deviceInfo = new DeviceInfo(this);
ExtraInfo extraInfo = new ExtraInfo();
onSaveExtraInfo(extraInfo);
Report report = new Report(bugTitle, bugDescription, deviceInfo, extraInfo, email);
GithubTarget target = getTarget();
report(this, report, target, login);
}
protected final void setGuestEmailRequired(boolean required) {
this.emailRequired = required;
if (required) {
optionAnonymous.setText(R.string.air_label_use_email);
((TextInputLayout) findViewById(R.id.air_inputEmailParent)).setHint(getString(R.string.air_label_email));
} else {
optionAnonymous.setText(R.string.air_label_use_guest);
((TextInputLayout) findViewById(R.id.air_inputEmailParent)).setHint(getString(R.string.air_label_email_optional));
}
}
protected final void setMinimumDescriptionLength(int length) {
this.bodyMinChar = length;
}
protected void onSaveExtraInfo(ExtraInfo extraInfo) {
}
protected abstract GithubTarget getTarget();
@Deprecated
protected String getGuestToken() {
return null;
}
protected final void setGuestToken(String token) {
this.token = token;
Log.d(TAG, "GuestToken: " + token);
updateGuestTokenViews();
}
@Override
public void finish() {
if (mCrash) {
if (!mReportFailed) {
Toast.makeText(this, com.stardust.scriptdroid.R.string.text_report_succeed, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, com.stardust.scriptdroid.R.string.text_report_fail, Toast.LENGTH_SHORT).show();
}
finishAffinity();
} else {
super.finish();
}
}
private void report(Activity activity, Report report, GithubTarget target,
GithubLogin login) {
new ReportIssueTask(activity, report, target, login).execute();
}
private class ReportIssueTask extends DialogAsyncTask<Void, Void, String> {
private final Report report;
private final GithubTarget target;
private final GithubLogin login;
private ReportIssueTask(Activity activity, Report report, GithubTarget target,
GithubLogin login) {
super(activity);
this.report = report;
this.target = target;
this.login = login;
}
@Override
protected Dialog createDialog(@NonNull Context context) {
return new MaterialDialog.Builder(context)
.progress(true, 0)
.progressIndeterminateStyle(true)
.title(R.string.air_dialog_title_loading)
.show();
}
@Override
@Result
protected String doInBackground(Void... params) {
GitHubClient client;
if (login.shouldUseApiToken()) {
client = new GitHubClient().setOAuth2Token(login.getApiToken());
} else {
client = new GitHubClient().setCredentials(login.getUsername(), login.getPassword());
}
Issue issue = new Issue().setTitle(report.getTitle()).setBody(report.getDescription());
try {
new IssueService(client).createIssue(target.getUsername(), target.getRepository(), issue);
return RESULT_OK;
} catch (RequestException e) {
switch (e.getStatus()) {
case STATUS_BAD_CREDENTIALS:
if (login.shouldUseApiToken())
return RESULT_INVALID_TOKEN;
return RESULT_BAD_CREDENTIALS;
case STATUS_ISSUES_NOT_ENABLED:
return RESULT_ISSUES_NOT_ENABLED;
default:
e.printStackTrace();
return RESULT_UNKNOWN;
}
} catch (IOException e) {
e.printStackTrace();
return RESULT_UNKNOWN;
}
}
@Override
protected void onPostExecute(@Result String result) {
super.onPostExecute(result);
Context context = getContext();
if (context == null) return;
switch (result) {
case RESULT_OK:
mReportFailed = false;
tryToFinishActivity();
break;
case RESULT_BAD_CREDENTIALS:
new MaterialDialog.Builder(context)
.title(R.string.air_dialog_title_failed)
.content(R.string.air_dialog_description_failed_wrong_credentials)
.positiveText(R.string.air_dialog_action_failed)
.show();
break;
case RESULT_INVALID_TOKEN:
new MaterialDialog.Builder(context)
.title(R.string.air_dialog_title_failed)
.content(R.string.air_dialog_description_failed_invalid_token)
.positiveText(R.string.air_dialog_action_failed)
.show();
break;
case RESULT_ISSUES_NOT_ENABLED:
new MaterialDialog.Builder(context)
.title(R.string.air_dialog_title_failed)
.content(R.string.air_dialog_description_failed_issues_not_available)
.positiveText(R.string.air_dialog_action_failed)
.show();
break;
default:
new MaterialDialog.Builder(context)
.title(R.string.air_dialog_title_failed)
.content(R.string.air_dialog_description_failed_unknown)
.positiveText(R.string.air_dialog_action_failed)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog,
@NonNull DialogAction which) {
tryToFinishActivity();
}
})
.cancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
tryToFinishActivity();
}
})
.show();
break;
}
}
private void tryToFinishActivity() {
Context context = getContext();
if (context instanceof Activity && !((Activity) context).isFinishing()) {
((Activity) context).finish();
}
}
}
private static abstract class DialogAsyncTask<Pa, Pr, Re> extends AsyncTask<Pa, Pr, Re> {
private WeakReference<Context> contextWeakReference;
private WeakReference<Dialog> dialogWeakReference;
private boolean supposedToBeDismissed;
private DialogAsyncTask(Context context) {
contextWeakReference = new WeakReference<>(context);
dialogWeakReference = new WeakReference<>(null);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Context context = getContext();
if (!supposedToBeDismissed && context != null) {
Dialog dialog = createDialog(context);
dialogWeakReference = new WeakReference<>(dialog);
dialog.show();
}
}
@SuppressWarnings("unchecked")
@Override
protected final void onProgressUpdate(Pr... values) {
super.onProgressUpdate(values);
Dialog dialog = getDialog();
if (dialog != null) {
onProgressUpdate(dialog, values);
}
}
@SuppressWarnings("unchecked")
private void onProgressUpdate(@NonNull Dialog dialog, Pr... values) {
}
@Nullable
Context getContext() {
return contextWeakReference.get();
}
@Nullable
Dialog getDialog() {
return dialogWeakReference.get();
}
@Override
protected void onCancelled(Re result) {
super.onCancelled(result);
tryToDismiss();
}
@Override
protected void onPostExecute(Re result) {
super.onPostExecute(result);
tryToDismiss();
}
private void tryToDismiss() {
supposedToBeDismissed = true;
try {
Dialog dialog = getDialog();
if (dialog != null)
dialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
protected abstract Dialog createDialog(@NonNull Context context);
}
}

View File

@@ -79,7 +79,7 @@ public class ErrorReportActivity extends BaseActivity {
}
private void startIssueReportActivity() {
Intent intent = new Intent(this, IssueReportActivity.class);
Intent intent = new Intent(this, IssueReporterActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtras(getIntent());
startActivity(intent);

View File

@@ -1,145 +0,0 @@
package com.stardust.scriptdroid.ui.error;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.widget.Toolbar;
import android.util.Base64;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.heinrichreimersoftware.androidissuereporter.IssueReporterActivity;
import com.heinrichreimersoftware.androidissuereporter.model.github.GithubTarget;
import com.stardust.scriptdroid.R;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by Stardust on 2017/2/13.
*/
public class IssueReportActivity extends IssueReporterActivity {
private boolean mCrash = false;
private Method mReportIssue, mValidateInput;
private boolean mReportFailed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleIntent();
setUpToobar();
hookSendClick();
}
private void hookSendClick() {
FloatingActionButton send = (FloatingActionButton) this.findViewById(com.heinrichreimersoftware.androidissuereporter.R.id.air_buttonSend);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
reportIssue();
} catch (Exception e) {
mReportFailed = true;
e.printStackTrace();
finish();
}
}
});
}
private void setUpToobar() {
getSupportActionBar().setTitle(R.string.text_issue_report);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Toolbar toolbar = (Toolbar) findViewById(R.id.air_toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
private void handleIntent() {
final String errorDetail = getIntent().getStringExtra("error");
if (errorDetail != null) {
((EditText) findViewById(R.id.air_inputDescription)).setText(errorDetail);
String title = getFirstLine(errorDetail);
((EditText) findViewById(R.id.air_inputTitle)).setText(title);
mCrash = true;
}
}
private String getFirstLine(String str) {
int i = str.indexOf('\n');
if(i < 0)
return str;
return str.substring(0, i);
}
private boolean validateInput() {
if (mValidateInput == null) {
try {
mValidateInput = IssueReporterActivity.class.getDeclaredMethod("validateInput");
mValidateInput.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
try {
return mValidateInput != null && (Boolean) mValidateInput.invoke(this);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
private void reportIssue() {
if (mReportIssue == null) {
try {
mReportIssue = IssueReporterActivity.class.getDeclaredMethod("reportIssue");
mReportIssue.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
try {
mReportIssue.invoke(this);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public void finish() {
if (mCrash) {
if (!mReportFailed) {
Toast.makeText(IssueReportActivity.this, R.string.text_report_succeed, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(IssueReportActivity.this, R.string.text_report_fail, Toast.LENGTH_SHORT).show();
}
finishAffinity();
} else {
super.finish();
}
}
@Override
protected GithubTarget getTarget() {
return new GithubTarget("hyb1996", "NoRootScriptDroid");
}
@Override
protected String getGuestToken() {
//绕过github安全检查
return decode("MzA5MWJhNWI0NDM2NWYzOGRmNDA4ZWRhM2Y5MTUxN2ZlNDVlZDBhZQ==");
}
public static String decode(String str) {
return new String(Base64.decode(str.getBytes(), Base64.DEFAULT));
}
}

View File

@@ -0,0 +1,33 @@
package com.stardust.scriptdroid.ui.error;
import android.os.Bundle;
import android.util.Base64;
import com.heinrichreimersoftware.androidissuereporter.model.github.GithubTarget;
/**
* Created by Stardust on 2017/2/13.
*/
public class IssueReporterActivity extends AbstractIssueReporterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//绕过GitHub安全检查
String token = decode("MzA5MWJhNWI0NDM2NWYzOGRmNDA4ZWRhM2Y5MTUxN2ZlNDVlZDBhZQ==");
setGuestToken(token);
}
@Override
protected GithubTarget getTarget() {
return new GithubTarget("hyb1996", "NoRootScriptDroid");
}
public static String decode(String str) {
return new String(Base64.decode(str.getBytes(), Base64.DEFAULT));
}
}

View File

@@ -7,10 +7,7 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
@@ -25,22 +22,23 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.folderselector.FileChooserDialog;
import com.stardust.app.FragmentPagerAdapterBuilder;
import com.stardust.app.NotAskAgainDialog;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.scripts.ScriptFile;
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
import com.stardust.scriptdroid.tool.ImageSelector;
import com.stardust.scriptdroid.tool.DrawableSaver;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.my_script_list.MyScriptListFragment;
import com.stardust.scriptdroid.ui.main.script_list.MyScriptListFragment;
import com.stardust.scriptdroid.ui.main.sample_list.SampleScriptListFragment;
import com.stardust.scriptdroid.ui.main.script_list.ScriptFileChooserDialogBuilder;
import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment;
import com.stardust.scriptdroid.ui.settings.SettingsActivity;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.BackPressedHandler;
import com.stardust.util.MessageEvent;
import com.stardust.view.ViewBinding;
import com.stardust.widget.SlidingUpPanel;
import com.stardust.scriptdroid.BuildConfig;
@@ -48,10 +46,13 @@ import com.stardust.scriptdroid.R;
import com.stardust.view.ViewBinder;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
import java.io.File;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
public class MainActivity extends BaseActivity implements FileChooserDialog.FileCallback {
public class MainActivity extends BaseActivity {
public static final String MESSAGE_CLEAR_BACKGROUND_SETTINGS = "MESSAGE_CLEAR_BACKGROUND_SETTINGS";
private static final String EXTRA_ACTION = "EXTRA_ACTION";
@@ -66,6 +67,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
private FragmentPagerAdapterBuilder.StoredFragmentPagerAdapter mPagerAdapter;
private OnActivityResultDelegate.Intermediary mActivityResultIntermediary = new OnActivityResultDelegate.Intermediary();
private DrawableSaver mDrawerHeaderBackgroundSaver, mAppbarBackgroundSaver;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -74,6 +76,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
checkPermissions();
registerBackPressHandlers();
handleIntent(getIntent());
EventBus.getDefault().register(this);
}
private void registerBackPressHandlers() {
@@ -131,21 +134,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
private void setUpDrawerHeader() {
TextView version = $(R.id.version);
version.setText("Version " + BuildConfig.VERSION_NAME);
String path = Pref.getDrawerHeaderImagePath();
if (path != null) {
setDrawerHeaderImage(path);
}
path = Pref.getAppBarImagePath();
if (path != null) {
setAppBarImage(path);
}
}
private void setDrawerHeaderImage(String path) {
Drawable d = BitmapDrawable.createFromPath(path);
if (d != null) {
((ImageView) $(R.id.drawer_header_img)).setImageDrawable(d);
}
mDrawerHeaderBackgroundSaver = new DrawableSaver.ImageSaver(this, "drawer_header_background", (ImageView) $(R.id.drawer_header_img));
}
private void setUpToolbar() {
@@ -156,6 +145,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
R.string.text_drawer_close);
drawerToggle.syncState();
mDrawerLayout.addDrawerListener(drawerToggle);
mAppbarBackgroundSaver = new DrawableSaver.ImageSaver(this, "appbar_background", (ImageView) $(R.id.app_bar_bg));
}
private void setUpTabViewPager() {
@@ -167,6 +157,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
.add(new TaskManagerFragment(), R.string.text_task_manage)
.build();
viewPager.setAdapter(mPagerAdapter);
viewPager.setOffscreenPageLimit(mPagerAdapter.getCount());
tabLayout.setupWithViewPager(viewPager);
}
@@ -187,9 +178,30 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
@ViewBinding.Click(R.id.import_from_file)
private void showFileChooser() {
new FileChooserDialog.Builder(this)
.initialPath(Environment.getExternalStorageDirectory().getPath())
.extensionsFilter(".js", ".txt")
new ScriptFileChooserDialogBuilder(this)
.scriptProvider(StorageScriptProvider.getExternalStorageProvider())
.fileCallback(new ScriptFileChooserDialogBuilder.FileCallback() {
@Override
public void onFileSelection(MaterialDialog dialog, ScriptFile file) {
dialog.dismiss();
StorageScriptProvider.getExternalStorageProvider().clearCacheExceptInitialDirectory();
getMyScriptListFragment().importFile(file.getPath());
}
})
.title(R.string.text_please_choose_file_to_import)
.autoDismiss(false)
.positiveText(R.string.cancel)
.neutralText(R.string.text_refresh)
.onAny(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
if (which == DialogAction.POSITIVE) {
dialog.dismiss();
} else {
StorageScriptProvider.getExternalStorageProvider().refreshAll();
}
}
})
.show();
}
@@ -205,19 +217,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
@ViewBinding.Click(R.id.drawer_header_img)
public void selectHeaderImage() {
new ImageSelector(this, mActivityResultIntermediary, new ImageSelector.ImageSelectorCallback() {
@Override
public void onImageSelected(ImageSelector selector, String path) {
setDrawerHeaderImage(path);
Pref.setDrawerHeaderImagePath(path);
mActivityResultIntermediary.removeDelegate(selector);
}
}).select();
}
@Override
public void onFileSelection(@NonNull FileChooserDialog dialog, @NonNull File file) {
getMyScriptListFragment().importFile(file.getPath());
mDrawerHeaderBackgroundSaver.select(this, mActivityResultIntermediary);
}
@Override
@@ -275,7 +275,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
.putExtra(ARGUMENT_PATH, path));
}
private MyScriptListFragment getMyScriptListFragment() {
public MyScriptListFragment getMyScriptListFragment() {
return ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
}
@@ -299,21 +299,20 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
@ViewBinding.Click(R.id.toolbar)
public void OnToolbarClick() {
new ImageSelector(this, mActivityResultIntermediary, new ImageSelector.ImageSelectorCallback() {
@Override
public void onImageSelected(ImageSelector selector, String path) {
Pref.setAppBarImagePath(path);
setAppBarImage(path);
mActivityResultIntermediary.removeDelegate(selector);
}
}).select();
mAppbarBackgroundSaver.select(this, mActivityResultIntermediary);
}
private void setAppBarImage(String path) {
Drawable d = BitmapDrawable.createFromPath(path);
if (d != null) {
((ImageView) $(R.id.app_bar_bg)).setImageDrawable(d);
@Subscribe
public void onMessageEvent(MessageEvent event) {
if (event.message.equals(MESSAGE_CLEAR_BACKGROUND_SETTINGS)) {
mAppbarBackgroundSaver.reset();
mDrawerHeaderBackgroundSaver.reset();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}

View File

@@ -9,18 +9,13 @@ import android.view.ViewGroup;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.app.Fragment;
import com.stardust.scriptdroid.scripts.ScriptFile;
import com.stardust.scriptdroid.scripts.ScriptFileList;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
import com.stardust.scriptdroid.scripts.sample.Sample;
import com.stardust.scriptdroid.scripts.sample.SampleFileManager;
import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.scriptdroid.ui.main.my_script_list.MyScriptListFragment;
import com.stardust.util.MessageEvent;
import com.stardust.scriptdroid.ui.main.MainActivity;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
/**
* Created by Stardust on 2017/3/13.
@@ -70,13 +65,12 @@ public class SampleScriptListFragment extends Fragment {
}
private void copySampleToMyScripts(Sample sample) {
String path = StorageScriptProvider.DEFAULT_DIRECTORY_PATH + sample.name + ".js";
if (!ScriptFileList.getImpl().containsPath(path) && PFile.copyAsset(getActivity(), sample.path, path)) {
ScriptFileList.getImpl().add(new ScriptFile(path));
EventBus.getDefault().post(new MessageEvent(MyScriptListFragment.MESSAGE_SCRIPT_FILE_ADDED));
Snackbar.make(mSampleScriptListRecyclerView, R.string.text_import_succeed, Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(mSampleScriptListRecyclerView, R.string.text_file_exists, Snackbar.LENGTH_SHORT).show();
try {
((MainActivity) getActivity()).getMyScriptListFragment().
importFile(sample.name, getActivity().getAssets().open(sample.path));
} catch (IOException e) {
e.printStackTrace();
Snackbar.make(mSampleScriptListRecyclerView, R.string.text_import_fail, Snackbar.LENGTH_SHORT).show();
}
}

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.ui.main.my_script_list;
package com.stardust.scriptdroid.ui.main.script_list;
import android.os.Bundle;
import android.support.annotation.NonNull;
@@ -24,6 +24,9 @@ import com.stardust.view.ViewBinding;
import com.stardust.widget.SimpleAdapterDataObserver;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* Created by Stardust on 2017/3/13.
@@ -34,8 +37,8 @@ public class MyScriptListFragment extends Fragment {
public static final String MESSAGE_SCRIPT_FILE_ADDED = "MESSAGE_SCRIPT_FILE_ADDED";
private ScriptAndFolderListRecyclerView mScriptListRecyclerView;
private ScriptListWithProgressBarView mScriptListWithProgressBarView;
private View mNoScriptHint;
private View mProgressBar;
private MaterialDialog mScriptFileOperationDialog;
private MaterialDialog mDirectoryOperationDialog;
private ScriptFile mSelectedScriptFile;
@@ -57,14 +60,15 @@ public class MyScriptListFragment extends Fragment {
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mScriptListRecyclerView = $(R.id.script_list);
mScriptListWithProgressBarView = $(R.id.script_list);
mScriptListRecyclerView = mScriptListWithProgressBarView.getScriptAndFolderListRecyclerView();
mNoScriptHint = $(R.id.hint_no_script);
mProgressBar = $(R.id.progressBar);
initScriptListRecyclerView();
initDialogs();
}
private void initScriptListRecyclerView() {
mScriptListWithProgressBarView.setStorageScriptProvider(StorageScriptProvider.getDefault());
mScriptListRecyclerView.getAdapter().registerAdapterDataObserver(new SimpleAdapterDataObserver() {
@Override
public void onSomethingChanged() {
@@ -141,14 +145,22 @@ public class MyScriptListFragment extends Fragment {
}
public void importFile(final String pathFrom) {
showFileNameInputDialog(PFile.getNameWithoutExtension(pathFrom), new MaterialDialog.InputCallback() {
try {
importFile(PFile.getNameWithoutExtension(pathFrom), new FileInputStream(pathFrom));
} catch (FileNotFoundException e) {
showMessage(R.string.file_not_exists);
}
}
public void importFile(String prefix, final InputStream inputStream) {
showFileNameInputDialog(PFile.getNameWithoutExtension(prefix), new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
final String pathTo = getCurrentDirectoryPath() + input + ".js";
new Thread(new Runnable() {
@Override
public void run() {
if (PFile.copy(pathFrom, pathTo)) {
if (PFile.copyStream(inputStream, pathTo)) {
showMessage(R.string.text_import_succeed);
} else {
showMessage(R.string.text_import_fail);
@@ -156,7 +168,6 @@ public class MyScriptListFragment extends Fragment {
notifyScriptFileChanged();
}
}).start();
}
});
}
@@ -237,10 +248,10 @@ public class MyScriptListFragment extends Fragment {
private void onScriptFileOperated() {
mSelectedScriptFile = null;
mProgressBar.post(new Runnable() {
getView().post(new Runnable() {
@Override
public void run() {
mProgressBar.setVisibility(View.GONE);
mScriptListWithProgressBarView.hideProgressBar();
}
});
}
@@ -276,7 +287,7 @@ public class MyScriptListFragment extends Fragment {
}
private void doDeletingScriptFile() {
mProgressBar.setVisibility(View.VISIBLE);
mScriptListWithProgressBarView.showProgressBar();
new Thread(new Runnable() {
@Override
public void run() {

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.ui.main.my_script_list;
package com.stardust.scriptdroid.ui.main.script_list;
import android.content.Context;
import android.os.Bundle;
@@ -17,7 +17,6 @@ import android.widget.TextView;
import com.stardust.autojs.script.FileScriptSource;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.scripts.ScriptFile;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
@@ -40,6 +39,13 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
void onLongClick(ScriptFile file);
}
public interface FileProcessListener {
void onFilesListing();
void onFileListed();
}
private OnScriptFileClickListener mOnItemClickListener;
private OnScriptFileLongClickListener mOnItemLongClickListener;
private final OnClickListener mOnItemClickListenerProxy = new OnClickListener() {
@@ -86,13 +92,14 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
}
};
private ScriptFile[] mScriptFileList;
private ScriptFile[] mScriptFileList = new ScriptFile[0];
private ScriptFile mCurrentFolder;
private ScriptFile mRootFolder;
private Adapter mAdapter;
private boolean mCanGoBack;
private StorageScriptProvider mStorageScriptProvider = StorageScriptProvider.getDefault();
private boolean mCanGoBack = false;
private StorageScriptProvider mStorageScriptProvider;
private FileProcessListener mFileProcessListener;
private boolean mScriptFileOperationEnabled = true;
public ScriptAndFolderListRecyclerView(Context context) {
super(context);
@@ -109,11 +116,25 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
init();
}
private void setCurrentFolder(ScriptFile folder, boolean canGoBack) {
private void setCurrentFolder(final ScriptFile folder, boolean canGoBack) {
mCurrentFolder = folder;
mScriptFileList = mStorageScriptProvider.getDirectoryScriptFiles(folder);
mCanGoBack = canGoBack;
mAdapter.notifyDataSetChanged();
if (mFileProcessListener != null) {
mFileProcessListener.onFilesListing();
}
new Thread(new Runnable() {
@Override
public void run() {
mScriptFileList = mStorageScriptProvider.getDirectoryScriptFiles(folder);
post(new Runnable() {
@Override
public void run() {
mFileProcessListener.onFileListed();
mAdapter.notifyDataSetChanged();
}
});
}
}).start();
}
private void setRootFolder(ScriptFile folder) {
@@ -121,8 +142,16 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
setCurrentFolder(mRootFolder, false);
}
public void setFileProcessListener(FileProcessListener fileProcessListener) {
mFileProcessListener = fileProcessListener;
}
public void setStorageScriptProvider(StorageScriptProvider storageScriptProvider) {
if (mStorageScriptProvider != null)
mStorageScriptProvider.unregisterDirectoryChangeListener(this);
mStorageScriptProvider = storageScriptProvider;
mStorageScriptProvider.registerDirectoryChangeListener(this);
setRootFolder(mStorageScriptProvider.getInitialDirectory());
}
public void setOnItemClickListener(OnScriptFileClickListener onItemClickListener) {
@@ -137,6 +166,10 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
return mCurrentFolder;
}
public void setScriptFileOperationEnabled(boolean scriptFileOperationEnabled) {
mScriptFileOperationEnabled = scriptFileOperationEnabled;
}
private void goBack() {
ScriptFile parent = mCurrentFolder.getParentFile();
setCurrentFolder(parent, !parent.equals(mRootFolder));
@@ -147,7 +180,6 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL));
mAdapter = new Adapter();
setAdapter(mAdapter);
setRootFolder(mStorageScriptProvider.getInitialDirectory());
}
@Override
@@ -171,7 +203,8 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mStorageScriptProvider.registerDirectoryChangeListener(this);
if (mStorageScriptProvider != null)
mStorageScriptProvider.registerDirectoryChangeListener(this);
}
@Override
@@ -268,8 +301,13 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
FileViewHolder(View itemView) {
super(itemView);
itemView.findViewById(R.id.edit).setOnClickListener(mOnEditClickListener);
itemView.findViewById(R.id.run).setOnClickListener(mOnRunClickListener);
if (mScriptFileOperationEnabled) {
itemView.findViewById(R.id.edit).setOnClickListener(mOnEditClickListener);
itemView.findViewById(R.id.run).setOnClickListener(mOnRunClickListener);
} else {
itemView.findViewById(R.id.edit).setVisibility(GONE);
itemView.findViewById(R.id.run).setVisibility(GONE);
}
}
}

View File

@@ -0,0 +1,63 @@
package com.stardust.scriptdroid.ui.main.script_list;
import android.content.Context;
import android.support.annotation.NonNull;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.scripts.ScriptFile;
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
/**
* Created by Stardust on 2017/4/3.
*/
public class ScriptFileChooserDialogBuilder extends MaterialDialog.Builder {
public interface FileCallback {
void onFileSelection(MaterialDialog dialog, ScriptFile file);
}
private ScriptListWithProgressBarView mScriptListWithProgressBarView;
private StorageScriptProvider mStorageScriptProvider;
private FileCallback mFileCallback;
public ScriptFileChooserDialogBuilder(@NonNull Context context) {
super(context);
mScriptListWithProgressBarView = new ScriptListWithProgressBarView(context);
mScriptListWithProgressBarView.setMinimumHeight(800);
mScriptListWithProgressBarView.setScriptFileOperationEnabled(false);
}
public ScriptFileChooserDialogBuilder fileCallback(final FileCallback fileCallback) {
mFileCallback = fileCallback;
return this;
}
public ScriptFileChooserDialogBuilder initialPath(String initialPath) {
mStorageScriptProvider = new StorageScriptProvider(initialPath, 5);
return this;
}
public ScriptFileChooserDialogBuilder scriptProvider(StorageScriptProvider storageScriptProvider) {
mStorageScriptProvider = storageScriptProvider;
return this;
}
public MaterialDialog build() {
if (mStorageScriptProvider != null) {
mScriptListWithProgressBarView.setStorageScriptProvider(mStorageScriptProvider);
}
customView(mScriptListWithProgressBarView, false);
final MaterialDialog dialog = super.build();
if (mFileCallback != null) {
mScriptListWithProgressBarView.setOnItemClickListener(new ScriptAndFolderListRecyclerView.OnScriptFileClickListener() {
@Override
public void onClick(ScriptFile file) {
mFileCallback.onFileSelection(dialog, file);
}
});
}
return dialog;
}
}

View File

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

View File

@@ -0,0 +1,92 @@
package com.stardust.scriptdroid.ui.main.script_list;
import android.content.Context;
import android.os.Build;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.annotation.StyleRes;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
/**
* Created by Stardust on 2017/4/3.
*/
public class ScriptListWithProgressBarView extends FrameLayout {
private View mProgressBar;
private ScriptAndFolderListRecyclerView mScriptAndFolderListRecyclerView;
public ScriptListWithProgressBarView(@NonNull Context context) {
super(context);
init();
}
public ScriptListWithProgressBarView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ScriptListWithProgressBarView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public ScriptListWithProgressBarView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
inflate(getContext(), R.layout.script_and_folder_list_view, this);
mProgressBar = findViewById(R.id.progressBar);
mScriptAndFolderListRecyclerView = (ScriptAndFolderListRecyclerView) findViewById(R.id.script_list_recycler_view);
mScriptAndFolderListRecyclerView.setFileProcessListener(new ScriptAndFolderListRecyclerView.FileProcessListener() {
@Override
public void onFilesListing() {
showProgressBar();
}
@Override
public void onFileListed() {
hideProgressBar();
}
});
}
public ScriptAndFolderListRecyclerView getScriptAndFolderListRecyclerView() {
return mScriptAndFolderListRecyclerView;
}
public void setStorageScriptProvider(StorageScriptProvider storageScriptProvider) {
mScriptAndFolderListRecyclerView.setStorageScriptProvider(storageScriptProvider);
}
public void setOnItemClickListener(ScriptAndFolderListRecyclerView.OnScriptFileClickListener onItemClickListener) {
mScriptAndFolderListRecyclerView.setOnItemClickListener(onItemClickListener);
}
public void setScriptFileOperationEnabled(boolean enabled) {
mScriptAndFolderListRecyclerView.setScriptFileOperationEnabled(enabled);
}
public void showProgressBar() {
mProgressBar.setVisibility(VISIBLE);
}
public void hideProgressBar() {
mProgressBar.setVisibility(GONE);
}
}

View File

@@ -12,12 +12,16 @@ import android.widget.Toast;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.error.IssueReportActivity;
import com.stardust.scriptdroid.ui.error.IssueReporterActivity;
import com.stardust.scriptdroid.ui.main.MainActivity;
import com.stardust.util.IntentUtil;
import com.stardust.util.MapEntries;
import com.stardust.scriptdroid.R;
import com.stardust.theme.app.ColorSelectActivity;
import com.stardust.theme.util.ListBuilder;
import com.stardust.util.MessageEvent;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
import java.util.Map;
@@ -108,15 +112,13 @@ public class SettingsActivity extends BaseActivity {
.entry(getString(R.string.text_reset_background), new Runnable() {
@Override
public void run() {
Pref.setAppBarImagePath(null);
Pref.setDrawerHeaderImagePath(null);
Toast.makeText(getActivity(), R.string.text_restart_app_to_apply, Toast.LENGTH_SHORT).show();
EventBus.getDefault().post(new MessageEvent(MainActivity.MESSAGE_CLEAR_BACKGROUND_SETTINGS));
}
})
.entry(getString(R.string.text_issue_report), new Runnable() {
@Override
public void run() {
startActivity(new Intent(getActivity(), IssueReportActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
startActivity(new Intent(getActivity(), IssueReporterActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
})
.entry(getString(R.string.text_join_qq_group), new Runnable() {