fix: import sample or create file not working. add: edit icon of view sample activity
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
package com.stardust.scriptdroid.ui.common;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.script.Scripts;
|
||||
import com.stardust.scriptdroid.script.StorageScriptProvider;
|
||||
import com.stardust.scriptdroid.script.sample.Sample;
|
||||
import com.stardust.scriptdroid.ui.edit.EditActivity;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
import com.stardust.scriptdroid.ui.main.script_list.MyScriptListFragment;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.UnderuseExecutors;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.ObservableEmitter;
|
||||
import io.reactivex.ObservableOnSubscribe;
|
||||
import io.reactivex.Scheduler;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.functions.Function;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/7/31.
|
||||
*/
|
||||
|
||||
public class ScriptOperations {
|
||||
|
||||
private Activity mActivity;
|
||||
private View mView;
|
||||
private ScriptFile mCurrentDirectory;
|
||||
|
||||
public ScriptOperations(Activity activity, View view, ScriptFile currentDirectory) {
|
||||
mActivity = activity;
|
||||
mView = view;
|
||||
mCurrentDirectory = currentDirectory;
|
||||
}
|
||||
|
||||
public ScriptOperations(Activity activity, View view) {
|
||||
this(activity, view, MyScriptListFragment.getCurrentDirectory());
|
||||
}
|
||||
|
||||
public void newScriptFileForScript(final String script) {
|
||||
showFileNameInputDialog("")
|
||||
.subscribe(new Consumer<String>() {
|
||||
@Override
|
||||
public void accept(@io.reactivex.annotations.NonNull String input) throws Exception {
|
||||
createScriptFile(getCurrentDirectoryPath() + input + ".js", script);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getCurrentDirectoryPath() {
|
||||
return getCurrentDirectory().getPath() + "/";
|
||||
}
|
||||
|
||||
private ScriptFile getCurrentDirectory() {
|
||||
return mCurrentDirectory;
|
||||
}
|
||||
|
||||
public void createScriptFile(String path, String script) {
|
||||
if (PFile.createIfNotExists(path)) {
|
||||
if (script != null) {
|
||||
try {
|
||||
PFile.write(path, script);
|
||||
} catch (UncheckedIOException e) {
|
||||
Snackbar.make(mView, R.string.text_file_write_fail, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
notifyScriptFileChanged();
|
||||
Scripts.edit(path);
|
||||
} else {
|
||||
Snackbar.make(mView, R.string.text_create_fail, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void newScriptFile() {
|
||||
newScriptFileForScript(null);
|
||||
}
|
||||
|
||||
public Observable<String> importFile(final String pathFrom) {
|
||||
try {
|
||||
return importFile(PFile.getNameWithoutExtension(pathFrom), new FileInputStream(pathFrom));
|
||||
} catch (FileNotFoundException e) {
|
||||
showMessage(R.string.file_not_exists);
|
||||
return Observable.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Observable<String> importFile(String prefix, final InputStream inputStream) {
|
||||
return showFileNameInputDialog(PFile.getNameWithoutExtension(prefix))
|
||||
.observeOn(Schedulers.io())
|
||||
.map(new Function<String, String>() {
|
||||
@Override
|
||||
public String apply(@io.reactivex.annotations.NonNull String s) throws Exception {
|
||||
final String pathTo = getCurrentDirectoryPath() + s + ".js";
|
||||
if (PFile.copyStream(inputStream, pathTo)) {
|
||||
showMessage(R.string.text_import_succeed);
|
||||
} else {
|
||||
showMessage(R.string.text_import_fail);
|
||||
}
|
||||
notifyScriptFileChanged();
|
||||
return pathTo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void newDirectory() {
|
||||
showNameInputDialog("", new InputCallback(true))
|
||||
.subscribe(new Consumer<String>() {
|
||||
@Override
|
||||
public void accept(@io.reactivex.annotations.NonNull String path) throws Exception {
|
||||
if (new ScriptFile(getCurrentDirectory(), path).mkdirs()) {
|
||||
showMessage(R.string.text_already_create);
|
||||
notifyScriptFileChanged();
|
||||
} else {
|
||||
showMessage(R.string.text_create_fail);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyScriptFileChanged() {
|
||||
StorageScriptProvider.getDefault().notifyDirectoryChanged(mCurrentDirectory);
|
||||
}
|
||||
|
||||
private void showMessage(final int resId) {
|
||||
mActivity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Snackbar.make(mView, resId, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private Observable<String> showFileNameInputDialog(String prefix) {
|
||||
return showNameInputDialog(prefix, new InputCallback(false));
|
||||
}
|
||||
|
||||
private Observable<String> showNameInputDialog(String prefix, MaterialDialog.InputCallback textWatcher) {
|
||||
final PublishSubject<String> input = PublishSubject.create();
|
||||
new ThemeColorMaterialDialogBuilder(mActivity).title(R.string.text_name)
|
||||
.inputType(InputType.TYPE_CLASS_TEXT)
|
||||
.alwaysCallInputCallback()
|
||||
.input(getString(R.string.text_please_input_name), prefix, false, textWatcher)
|
||||
.onPositive(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
input.onNext(dialog.getInputEditText().getText().toString());
|
||||
input.onComplete();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
private CharSequence getString(int resId) {
|
||||
return mActivity.getString(resId);
|
||||
}
|
||||
|
||||
public Observable<String> importSample(Sample sample) {
|
||||
try {
|
||||
return importFile(sample.name, mActivity.getAssets().open(sample.path));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Snackbar.make(mView, R.string.text_import_fail, Snackbar.LENGTH_SHORT).show();
|
||||
return Observable.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Observable<Boolean> rename(final ScriptFile file) {
|
||||
String originalName = file.getSimplifiedName();
|
||||
return showNameInputDialog(originalName, new InputCallback(file.isDirectory(), originalName))
|
||||
.map(new Function<String, Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(@io.reactivex.annotations.NonNull String newName) throws Exception {
|
||||
return file.renameTo(newName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class InputCallback implements MaterialDialog.InputCallback {
|
||||
|
||||
private boolean mIsDirectory = false;
|
||||
private String mExcluded;
|
||||
private boolean mIsFirstTextChanged = true;
|
||||
|
||||
InputCallback(boolean isDirectory, String excluded) {
|
||||
mIsDirectory = isDirectory;
|
||||
mExcluded = excluded;
|
||||
}
|
||||
|
||||
InputCallback(boolean isDirectory) {
|
||||
mIsDirectory = isDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||
if (mIsFirstTextChanged) {
|
||||
mIsFirstTextChanged = false;
|
||||
return;
|
||||
}
|
||||
EditText editText = dialog.getInputEditText();
|
||||
if (editText == null)
|
||||
return;
|
||||
int errorResId = 0;
|
||||
if (input == null || input.length() == 0) {
|
||||
errorResId = R.string.text_name_should_not_be_empty;
|
||||
} else if (!input.equals(mExcluded)) {
|
||||
if (new File(getCurrentDirectory(), mIsDirectory ? input.toString() : input.toString() + ".js").exists()) {
|
||||
errorResId = R.string.text_file_exists;
|
||||
}
|
||||
}
|
||||
if (errorResId == 0) {
|
||||
editText.setError(null);
|
||||
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true);
|
||||
} else {
|
||||
editText.setError(getString(errorResId));
|
||||
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.script.Scripts;
|
||||
import com.stardust.scriptdroid.script.sample.Sample;
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils;
|
||||
import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity;
|
||||
@@ -33,11 +34,11 @@ import com.stardust.util.SparseArrayEntries;
|
||||
import com.stardust.widget.ToolbarMenuItem;
|
||||
|
||||
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EActivity;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Consumer;
|
||||
|
||||
import static com.stardust.scriptdroid.script.Scripts.ACTION_ON_EXECUTION_FINISHED;
|
||||
import static com.stardust.scriptdroid.script.Scripts.EXTRA_EXCEPTION_MESSAGE;
|
||||
@@ -118,6 +119,20 @@ public class ViewSampleActivity extends Editor920Activity implements OnActivityR
|
||||
mScriptExecution = Scripts.runWithBroadcastSender(new StringScriptSource(mSample.name, mEditorDelegate.getText()));
|
||||
}
|
||||
|
||||
@OnClick(R.id.edit)
|
||||
void edit() {
|
||||
new ScriptOperations(this, mView)
|
||||
.importSample(mSample)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<String>() {
|
||||
@Override
|
||||
public void accept(@NonNull String path) throws Exception {
|
||||
EditActivity.editFile(ViewSampleActivity.this, path);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initMenuItem() {
|
||||
mMenuMap = new SparseArrayEntries<ToolbarMenuItem>()
|
||||
.entry(R.id.run, (ToolbarMenuItem) findViewById(R.id.run))
|
||||
@@ -152,7 +167,9 @@ public class ViewSampleActivity extends Editor920Activity implements OnActivityR
|
||||
HelpCatalogueActivity.showMainCatalogue(this);
|
||||
return true;
|
||||
case R.id.action_import:
|
||||
MainActivity.importSample(this, mSample);
|
||||
new ScriptOperations(this, mView)
|
||||
.importSample(mSample)
|
||||
.subscribe();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.stardust.scriptdroid.external.open.ImportIntentActivity;
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.script.StorageScriptProvider;
|
||||
import com.stardust.scriptdroid.script.sample.Sample;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_;
|
||||
import com.stardust.util.IntentExtras;
|
||||
import com.stardust.view.accessibility.AccessibilityService;
|
||||
@@ -67,6 +68,7 @@ import org.androidannotations.annotations.ViewById;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@@ -221,22 +223,14 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
|
||||
@Click(R.id.create_new_file)
|
||||
void createScriptFile() {
|
||||
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() {
|
||||
@Override
|
||||
public void call(MyScriptListFragment myScriptListFragment) {
|
||||
myScriptListFragment.newScriptFile();
|
||||
}
|
||||
});
|
||||
new ScriptOperations(this, mDrawerLayout)
|
||||
.newScriptFile();
|
||||
}
|
||||
|
||||
@Click(R.id.create_new_directory)
|
||||
void createNewDirectory() {
|
||||
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() {
|
||||
@Override
|
||||
public void call(MyScriptListFragment myScriptListFragment) {
|
||||
myScriptListFragment.newDirectory();
|
||||
}
|
||||
});
|
||||
new ScriptOperations(this, mDrawerLayout)
|
||||
.newDirectory();
|
||||
}
|
||||
|
||||
@Click(R.id.import_from_file)
|
||||
@@ -249,12 +243,8 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
public void onFileSelection(MaterialDialog dialog, final ScriptFile file) {
|
||||
dialog.dismiss();
|
||||
provider.clearCacheExceptInitialDirectory();
|
||||
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() {
|
||||
@Override
|
||||
public void call(MyScriptListFragment myScriptListFragment) {
|
||||
myScriptListFragment.importFile(file.getPath());
|
||||
}
|
||||
});
|
||||
new ScriptOperations(MainActivity.this, mDrawerLayout)
|
||||
.importFile(file.getPath());
|
||||
}
|
||||
})
|
||||
.title(R.string.text_please_choose_file_to_import)
|
||||
@@ -324,48 +314,19 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
case ACTION_IMPORT_SCRIPT:
|
||||
handleImportScriptFile(intent);
|
||||
break;
|
||||
case ACTION_IMPORT_SAMPLE:
|
||||
handleImportSample(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleImportScriptFile(Intent intent) {
|
||||
mViewPager.setCurrentItem(0, true);
|
||||
MyScriptListFragment fragment = getMyScriptListFragment();
|
||||
if (fragment == null) {
|
||||
mIntentToHandle = intent;
|
||||
} else {
|
||||
String path = intent.getStringExtra(ARGUMENT_PATH);
|
||||
if (path != null) {
|
||||
fragment.importFile(intent.getStringExtra(ARGUMENT_PATH));
|
||||
return;
|
||||
}
|
||||
InputStream inputStream = IntentExtras.fromIntent(intent).getAndClear(ARGUMENT_INPUT_STREAM);
|
||||
fragment.importFile("", inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void handleImportSample(Intent intent) {
|
||||
mViewPager.setCurrentItem(0, true);
|
||||
MyScriptListFragment fragment = getMyScriptListFragment();
|
||||
if (fragment == null) {
|
||||
mIntentToHandle = intent;
|
||||
} else {
|
||||
final Sample sample = (Sample) intent.getSerializableExtra(ARGUMENT_SAMPLE);
|
||||
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() {
|
||||
@Override
|
||||
public void call(MyScriptListFragment myScriptListFragment) {
|
||||
try {
|
||||
myScriptListFragment.importFile(sample.name, getAssets().open(sample.path));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Snackbar.make(mDrawerLayout, R.string.text_import_fail, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
String path = intent.getStringExtra(ARGUMENT_PATH);
|
||||
if (path != null) {
|
||||
new ScriptOperations(MainActivity.this, mDrawerLayout)
|
||||
.importFile(intent.getStringExtra(ARGUMENT_PATH));
|
||||
return;
|
||||
}
|
||||
InputStream inputStream = IntentExtras.fromIntent(intent).getAndClear(ARGUMENT_INPUT_STREAM);
|
||||
new ScriptOperations(MainActivity.this, mDrawerLayout)
|
||||
.importFile("", inputStream);
|
||||
}
|
||||
|
||||
private void handleRecordedScript(final String script) {
|
||||
@@ -376,12 +337,8 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
@Override
|
||||
public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
|
||||
if (position == 0) {
|
||||
doWithMyScriptListFragment(new Callback<MyScriptListFragment>() {
|
||||
@Override
|
||||
public void call(MyScriptListFragment myScriptListFragment) {
|
||||
myScriptListFragment.newScriptFileForScript(script);
|
||||
}
|
||||
});
|
||||
new ScriptOperations(MainActivity.this, mDrawerLayout)
|
||||
.newScriptFileForScript(script);
|
||||
} else {
|
||||
((ClipboardManager) getSystemService(CLIPBOARD_SERVICE))
|
||||
.setPrimaryClip(ClipData.newPlainText("script", script));
|
||||
@@ -418,39 +375,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void importSample(Context context, Sample sample) {
|
||||
context.startActivity(new Intent(context, MainActivity_.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
.putExtra(EXTRA_ACTION, ACTION_IMPORT_SAMPLE)
|
||||
.putExtra(ARGUMENT_SAMPLE, sample));
|
||||
}
|
||||
|
||||
public void doWithMyScriptListFragment(final Callback<MyScriptListFragment> callback) {
|
||||
MyScriptListFragment fragment = ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
|
||||
if (fragment != null) {
|
||||
callback.call(fragment);
|
||||
return;
|
||||
}
|
||||
mViewPager.setCurrentItem(0);
|
||||
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if (position == 0) {
|
||||
mViewPager.removeOnPageChangeListener(this);
|
||||
doWithMyScriptListFragment(callback);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MyScriptListFragment getMyScriptListFragment() {
|
||||
MyScriptListFragment fragment = ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
|
||||
if (fragment == null) {
|
||||
mViewPager.setCurrentItem(0);
|
||||
}
|
||||
return ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
|
||||
}
|
||||
|
||||
@Click(R.id.toolbar)
|
||||
public void OnToolbarClick() {
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.script.Scripts;
|
||||
import com.stardust.scriptdroid.script.sample.Sample;
|
||||
import com.stardust.scriptdroid.script.sample.SampleFileManager;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.edit.ViewSampleActivity;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
|
||||
@@ -66,7 +67,9 @@ public class SampleScriptListFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void copySampleToMyScripts(Sample sample) {
|
||||
MainActivity.importSample(getActivity(), sample);
|
||||
new ScriptOperations(getActivity(), getView())
|
||||
.importSample(sample)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
private void viewSample(Sample sample) {
|
||||
|
||||
@@ -22,11 +22,15 @@ import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.script.Scripts;
|
||||
import com.stardust.scriptdroid.script.StorageScriptProvider;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.edit.EditActivity;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.UnderuseExecutors;
|
||||
import com.stardust.widget.SimpleAdapterDataObserver;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -34,6 +38,10 @@ import java.io.InputStream;
|
||||
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Optional;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/13.
|
||||
@@ -45,13 +53,14 @@ public class MyScriptListFragment extends Fragment {
|
||||
|
||||
private static final String TAG = "MyScriptListFragment";
|
||||
|
||||
private static ScriptFile sCurrentDirectory = StorageScriptProvider.DEFAULT_DIRECTORY;
|
||||
|
||||
private ScriptAndFolderListRecyclerView mScriptListRecyclerView;
|
||||
private ScriptListWithProgressBarView mScriptListWithProgressBarView;
|
||||
private View mNoScriptHint;
|
||||
private MaterialDialog mScriptFileOperationDialog;
|
||||
private MaterialDialog mDirectoryOperationDialog;
|
||||
private ScriptFile mSelectedScriptFile;
|
||||
private String mFilePathToImport;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -68,10 +77,6 @@ public class MyScriptListFragment extends Fragment {
|
||||
mNoScriptHint = $(R.id.hint_no_script);
|
||||
initScriptListRecyclerView();
|
||||
initDialogs();
|
||||
if (mFilePathToImport != null) {
|
||||
importFile(mFilePathToImport);
|
||||
mFilePathToImport = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initScriptListRecyclerView() {
|
||||
@@ -103,9 +108,14 @@ public class MyScriptListFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
});
|
||||
mScriptListRecyclerView.setOnCurrentDirectoryChangeListener(new ScriptAndFolderListRecyclerView.OnCurrentDirectoryChangeListener() {
|
||||
@Override
|
||||
public void onChange(ScriptFile oldDir, ScriptFile newDir) {
|
||||
sCurrentDirectory = newDir;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void initDialogs() {
|
||||
mScriptFileOperationDialog = new OperationDialogBuilder(getContext())
|
||||
.item(R.id.loop, R.drawable.ic_loop_white_24dp, R.string.text_run_repeatedly)
|
||||
@@ -122,107 +132,11 @@ public class MyScriptListFragment extends Fragment {
|
||||
.build();
|
||||
}
|
||||
|
||||
public void newScriptFileForScript(final String script) {
|
||||
showFileNameInputDialog("", new MaterialDialog.InputCallback() {
|
||||
@Override
|
||||
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||
createScriptFile(getCurrentDirectoryPath() + input + ".js", script);
|
||||
}
|
||||
});
|
||||
|
||||
public static ScriptFile getCurrentDirectory() {
|
||||
return sCurrentDirectory;
|
||||
}
|
||||
|
||||
private String getCurrentDirectoryPath() {
|
||||
return getCurrentDirectory().getPath() + "/";
|
||||
}
|
||||
|
||||
public void createScriptFile(String path, String script) {
|
||||
if (PFile.createIfNotExists(path)) {
|
||||
if (script != null) {
|
||||
try {
|
||||
PFile.write(path, script);
|
||||
} catch (UncheckedIOException e) {
|
||||
Snackbar.make(getView(), R.string.text_file_write_fail, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
notifyScriptFileChanged();
|
||||
Scripts.edit(path);
|
||||
} else {
|
||||
Snackbar.make(getView(), R.string.text_create_fail, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void newScriptFile() {
|
||||
newScriptFileForScript(null);
|
||||
}
|
||||
|
||||
public void importFile(final String pathFrom) {
|
||||
if (getActivity() == null) {
|
||||
mFilePathToImport = pathFrom;
|
||||
return;
|
||||
}
|
||||
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.copyStream(inputStream, pathTo)) {
|
||||
showMessage(R.string.text_import_succeed);
|
||||
} else {
|
||||
showMessage(R.string.text_import_fail);
|
||||
}
|
||||
notifyScriptFileChanged();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void newDirectory() {
|
||||
showNameInputDialog("", new InputCallback(true), new MaterialDialog.InputCallback() {
|
||||
@Override
|
||||
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||
if (new ScriptFile(getCurrentDirectory(), input.toString()).mkdirs()) {
|
||||
showMessage(R.string.text_already_create);
|
||||
notifyScriptFileChanged();
|
||||
} else {
|
||||
showMessage(R.string.text_create_fail);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ScriptFile getCurrentDirectory() {
|
||||
return mScriptListRecyclerView.getCurrentDirectory();
|
||||
}
|
||||
|
||||
private void showFileNameInputDialog(String prefix, final MaterialDialog.InputCallback callback) {
|
||||
showNameInputDialog(prefix, new InputCallback(false), callback);
|
||||
}
|
||||
|
||||
private void showNameInputDialog(String prefix, MaterialDialog.InputCallback textWatcher, final MaterialDialog.InputCallback callback) {
|
||||
new ThemeColorMaterialDialogBuilder(getActivity()).title(R.string.text_name)
|
||||
.inputType(InputType.TYPE_CLASS_TEXT)
|
||||
.alwaysCallInputCallback()
|
||||
.input(getString(R.string.text_please_input_name), prefix, false, textWatcher)
|
||||
.onPositive(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
callback.onInput(dialog, dialog.getInputEditText().getText());
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private void notifyScriptFileChanged() {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@@ -245,15 +159,15 @@ public class MyScriptListFragment extends Fragment {
|
||||
@OnClick(R.id.rename)
|
||||
void renameScriptFile() {
|
||||
dismissDialogs();
|
||||
String originalName = mSelectedScriptFile.getSimplifiedName();
|
||||
showNameInputDialog(originalName, new InputCallback(mSelectedScriptFile.isDirectory(), originalName), new MaterialDialog.InputCallback() {
|
||||
@Override
|
||||
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||
mSelectedScriptFile.renameTo(input.toString());
|
||||
StorageScriptProvider.getDefault().notifyDirectoryChanged(mScriptListRecyclerView.getCurrentDirectory());
|
||||
onScriptFileOperated();
|
||||
}
|
||||
});
|
||||
new ScriptOperations(getActivity(), getView())
|
||||
.rename(mSelectedScriptFile)
|
||||
.subscribe(new Consumer<Boolean>() {
|
||||
@Override
|
||||
public void accept(@io.reactivex.annotations.NonNull Boolean renamed) throws Exception {
|
||||
StorageScriptProvider.getDefault().notifyDirectoryChanged(mScriptListRecyclerView.getCurrentDirectory());
|
||||
onScriptFileOperated();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void dismissDialogs() {
|
||||
@@ -274,7 +188,7 @@ public class MyScriptListFragment extends Fragment {
|
||||
|
||||
private void onScriptFileOperated() {
|
||||
mSelectedScriptFile = null;
|
||||
getView().post(new Runnable() {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mScriptListWithProgressBarView.hideProgressBar();
|
||||
@@ -310,18 +224,21 @@ public class MyScriptListFragment extends Fragment {
|
||||
|
||||
private void doDeletingScriptFile() {
|
||||
mScriptListWithProgressBarView.showProgressBar();
|
||||
UnderuseExecutors.execute(new Runnable() {
|
||||
Observable.fromPublisher(new Publisher<Boolean>() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (PFile.deleteRecursively(mSelectedScriptFile)) {
|
||||
showMessage(R.string.text_already_delete);
|
||||
notifyScriptFileChanged();
|
||||
} else {
|
||||
showMessage(R.string.text_already_delete);
|
||||
}
|
||||
onScriptFileOperated();
|
||||
public void subscribe(Subscriber<? super Boolean> s) {
|
||||
s.onNext(PFile.deleteRecursively(mSelectedScriptFile));
|
||||
}
|
||||
});
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<Boolean>() {
|
||||
@Override
|
||||
public void accept(@io.reactivex.annotations.NonNull Boolean deleted) throws Exception {
|
||||
showMessage(deleted ? R.string.text_already_delete : R.string.text_delete_failed);
|
||||
notifyScriptFileChanged();
|
||||
onScriptFileOperated();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showMessage(final int resId) {
|
||||
|
||||
@@ -27,10 +27,19 @@ import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
||||
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/27.
|
||||
*/
|
||||
@@ -54,6 +63,12 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
|
||||
void onFileListed();
|
||||
}
|
||||
|
||||
public interface OnCurrentDirectoryChangeListener {
|
||||
|
||||
void onChange(ScriptFile oldDir, ScriptFile newDir);
|
||||
|
||||
}
|
||||
|
||||
public static final int VIEW_TYPE_DIRECTORY = 1;
|
||||
public static final int VIEW_TYPE_FILE = 2;
|
||||
|
||||
@@ -143,8 +158,8 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
|
||||
private boolean mCanGoBack = false;
|
||||
private StorageScriptProvider mStorageScriptProvider;
|
||||
private FileProcessListener mFileProcessListener;
|
||||
private OnCurrentDirectoryChangeListener mOnCurrentDirectoryChangeListener;
|
||||
private boolean mScriptFileOperationEnabled = true;
|
||||
private Executor mFileListingExecutor = Executors.newSingleThreadExecutor();
|
||||
|
||||
public ScriptAndFolderListRecyclerView(Context context) {
|
||||
super(context);
|
||||
@@ -162,26 +177,31 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
|
||||
}
|
||||
|
||||
private void setCurrentDirectory(final ScriptFile directory, boolean canGoBack) {
|
||||
if (!directory.equals(mCurrentDirectory) && mOnCurrentDirectoryChangeListener != null) {
|
||||
mOnCurrentDirectoryChangeListener.onChange(mCurrentDirectory, directory);
|
||||
}
|
||||
mCurrentDirectory = directory;
|
||||
mCanGoBack = canGoBack;
|
||||
if (mFileProcessListener != null) {
|
||||
mFileProcessListener.onFilesListing();
|
||||
}
|
||||
mFileListingExecutor.execute(new Runnable() {
|
||||
Observable.fromPublisher(new Publisher<ScriptFile[]>() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ScriptFile[] scriptFiles = mStorageScriptProvider.getDirectoryScriptFiles(directory);
|
||||
post(new Runnable() {
|
||||
public void subscribe(Subscriber<? super ScriptFile[]> s) {
|
||||
s.onNext(mStorageScriptProvider.getDirectoryScriptFiles(directory));
|
||||
s.onComplete();
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<ScriptFile[]>() {
|
||||
@Override
|
||||
public void run() {
|
||||
public void accept(@NonNull ScriptFile[] scriptFiles) throws Exception {
|
||||
mAdapter.setScripts(scriptFiles);
|
||||
if (mFileProcessListener != null)
|
||||
mFileProcessListener.onFileListed();
|
||||
smoothScrollToPosition(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setCurrentDirectory(final ScriptFile directory) {
|
||||
@@ -216,6 +236,10 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
|
||||
mOnItemLongClickListener = onItemLongClickListener;
|
||||
}
|
||||
|
||||
public void setOnCurrentDirectoryChangeListener(OnCurrentDirectoryChangeListener onCurrentDirectoryChangeListener) {
|
||||
mOnCurrentDirectoryChangeListener = onCurrentDirectoryChangeListener;
|
||||
}
|
||||
|
||||
public ScriptFile getCurrentDirectory() {
|
||||
return mCurrentDirectory;
|
||||
}
|
||||
@@ -297,7 +321,7 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onDirectoryChange(StorageScriptProvider.DirectoryChangeEvent event) {
|
||||
if (event.directory.equals(mCurrentDirectory)) {
|
||||
updateCurrentDirectory();
|
||||
|
||||
@@ -45,6 +45,8 @@ public class TaskManagerFragment extends Fragment {
|
||||
mTaskListRecyclerView.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mNoRunningScriptNotice == null)
|
||||
return;
|
||||
mNoRunningScriptNotice.setVisibility(noRunningScript ? View.VISIBLE : View.GONE);
|
||||
mCloseAllView.setVisibility(noRunningScript ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
BIN
app/src/main/res/drawable/ic_edit_white_24dp.png
Normal file
BIN
app/src/main/res/drawable/ic_edit_white_24dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 302 B |
@@ -27,6 +27,14 @@
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.stardust.widget.ToolbarMenuItem
|
||||
android:id="@+id/edit"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_edit_white_24dp"
|
||||
app:icon_color="@android:color/white"
|
||||
app:text="@string/text_edit"/>
|
||||
|
||||
<com.stardust.widget.ToolbarMenuItem
|
||||
android:id="@+id/run"
|
||||
android:layout_width="40dp"
|
||||
@@ -35,6 +43,8 @@
|
||||
app:icon_color="@android:color/white"
|
||||
app:text="@string/text_run"/>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.stardust.theme.widget.ThemeColorToolbar>
|
||||
|
||||
@@ -211,6 +211,7 @@
|
||||
<string name="script_anr">没有相应,要强制停止吗</string>
|
||||
<string name="text_enable_accessibitliy_service_by_root_failed">使用root权限开启失败</string>
|
||||
<string name="text_on_progress">处理中</string>
|
||||
<string name="text_delete_failed">删除失败</string>
|
||||
|
||||
|
||||
<string-array name="record_control_keys">
|
||||
|
||||
Reference in New Issue
Block a user