fix: script list not updated when script is renamed, deleted or created

This commit is contained in:
hyb1996 2017-09-30 20:45:48 +08:00
parent f35de5ce02
commit 7eb0bec0a7
11 changed files with 219 additions and 53 deletions

View File

@ -0,0 +1,52 @@
package com.stardust.scriptdroid.external.floatingwindow;
import android.content.Context;
import android.content.Intent;
import android.view.WindowManager;
import android.widget.Toast;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.FloatyWindow;
import com.stardust.enhancedfloaty.util.FloatingWindowPermissionUtil;
import com.stardust.scriptdroid.R;
import ezy.assist.compat.SettingsCompat;
/**
* Created by Stardust on 2017/9/30.
*/
public class FloatyWindowManger {
public static void addWindow(Context context, FloatyWindow window) {
context.startService(new Intent(context, FloatyService.class));
if (SettingsCompat.canDrawOverlays(context)) {
Toast.makeText(context, R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show();
manageDrawOverlays(context);
return;
}
try {
FloatyService.addWindow(window);
// SecurityException: https://github.com/hyb1996-guest/AutoJsIssueReport/issues/4781
} catch (Exception e) {
e.printStackTrace();
manageDrawOverlays(context);
Toast.makeText(context, R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show();
}
}
public static void manageDrawOverlays(Context context) {
try {
SettingsCompat.manageDrawOverlays(context);
} catch (Exception ex) {
FloatingWindowPermissionUtil.goToAppDetailSettings(context, context.getPackageName());
}
}
public static void closeWindow(FloatyWindow window) {
window.close();
}
}

View File

@ -2,6 +2,7 @@ package com.stardust.scriptdroid.script;
import android.os.Environment;
import android.renderscript.Script;
import android.support.annotation.Nullable;
import com.stardust.autojs.script.AutoFileSource;
import com.stardust.autojs.script.JavaScriptFileSource;
@ -34,6 +35,11 @@ public class ScriptFile extends File {
init();
}
public ScriptFile(String parent, String name) {
super(parent, name);
init();
}
private void init() {
mSimplifiedName = PFile.getNameWithoutExtension(getName());
mSimplifyPath = getPath();
@ -54,6 +60,17 @@ public class ScriptFile extends File {
return renameTo(new File(getParent(), newName + "." + getExtension()));
}
@Nullable
public ScriptFile renameAndReturnNewFile(String newName) {
ScriptFile newFile = isDirectory() ? new ScriptFile(getParent(), newName) :
new ScriptFile(getParent(), newName + "." + getExtension());
if (renameTo(newFile)) {
return newFile;
} else {
return null;
}
}
private String getExtension() {
return PFile.getExtension(getName());
}
@ -123,10 +140,10 @@ public class ScriptFile extends File {
return renameTo(new File(to, getName()));
}
public ScriptSource toSource(){
if(getType() == TYPE_JAVA_SCRIPT){
public ScriptSource toSource() {
if (getType() == TYPE_JAVA_SCRIPT) {
return new JavaScriptFileSource(this);
}else {
} else {
return new AutoFileSource(this);
}
}

View File

@ -4,18 +4,19 @@ import android.os.Environment;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.util.FileSorter;
import com.stardust.util.LimitedHashMap;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Stardust on 2017/3/31.
@ -23,13 +24,48 @@ import io.reactivex.schedulers.Schedulers;
public class StorageFileProvider {
public static final int REMOVE = 0;
public static final int CREATE = 1;
public static final int CHANGE = 2;
public static final int ALL = 3;
public static class DirectoryChangeEvent {
public ScriptFile directory;
private final ScriptFile mDir;
private final int mChange;
private final ScriptFile mFile;
private final ScriptFile mNewFile;
public DirectoryChangeEvent(ScriptFile dir, int change, ScriptFile file) {
this(dir, change, file, file);
}
public DirectoryChangeEvent(ScriptFile directory) {
this.directory = directory;
this(directory, ALL, null);
}
public DirectoryChangeEvent(ScriptFile dir, int change, ScriptFile oldFile, ScriptFile newFile) {
mDir = dir;
mChange = change;
mFile = oldFile;
mNewFile = newFile;
}
public ScriptFile getDir() {
return mDir;
}
public int getChange() {
return mChange;
}
public ScriptFile getFile() {
return mFile;
}
public ScriptFile getNewFile() {
return mNewFile;
}
}
@ -53,7 +89,7 @@ public class StorageFileProvider {
}
private EventBus mDirectoryEventBus = new EventBus();
private LimitedHashMap<String, ScriptFile[]> mScriptFileCache;
private LimitedHashMap<String, List<ScriptFile>> mScriptFileCache;
private ScriptFile mInitialDirectory;
private ScriptFile[] mInitialDirectoryScriptFiles;
@ -75,6 +111,35 @@ public class StorageFileProvider {
mDirectoryEventBus.post(new DirectoryChangeEvent(directory));
}
public void notifyFileChanged(ScriptFile dir, ScriptFile oldFile, ScriptFile newFile) {
List<ScriptFile> files = getScriptFilesFromCache(dir);
if (files == null)
return;
int i = files.indexOf(oldFile);
if (i >= 0) {
files.set(i, newFile);
mDirectoryEventBus.post(new DirectoryChangeEvent(dir, CHANGE, oldFile, newFile));
}
}
public void notifyFileRemoved(ScriptFile dir, ScriptFile file) {
List<ScriptFile> files = getScriptFilesFromCache(dir);
if (files == null)
return;
if (files.remove(file)) {
mDirectoryEventBus.post(new DirectoryChangeEvent(dir, REMOVE, file));
}
}
public void notifyFileCreated(ScriptFile dir, ScriptFile file) {
List<ScriptFile> files = getScriptFilesFromCache(dir);
if (files == null)
return;
files.add(0, file);
mDirectoryEventBus.post(new DirectoryChangeEvent(dir, CREATE, file));
}
public void notifyStoragePermissionGranted() {
mScriptFileCache.clear();
mInitialDirectoryScriptFiles = null;
@ -101,11 +166,11 @@ public class StorageFileProvider {
}
public Observable<ScriptFile> getDirectoryScriptFiles(ScriptFile directory) {
ScriptFile[] scriptFiles = getScriptFilesFromCache(directory);
List<ScriptFile> scriptFiles = getScriptFilesFromCache(directory);
if (scriptFiles == null) {
return listAndSortFiles(directory);
return listFiles(directory);
}
return Observable.fromArray(scriptFiles);
return Observable.fromIterable(scriptFiles);
}
private void clearCache(ScriptFile directory) {
@ -113,27 +178,19 @@ public class StorageFileProvider {
}
private Observable<ScriptFile> listAndSortFiles(ScriptFile directory) {
private Observable<ScriptFile> listFiles(ScriptFile directory) {
return Observable.just(directory)
.observeOn(Schedulers.computation())
.flatMap(new Function<ScriptFile, Observable<ScriptFile>>() {
.flatMap(new Function<ScriptFile, ObservableSource<ScriptFile>>() {
@Override
public Observable<ScriptFile> apply(@NonNull ScriptFile dir) throws Exception {
public ObservableSource<ScriptFile> apply(@NonNull ScriptFile dir) throws Exception {
ScriptFile[] scriptFiles = dir.listFiles();
if (scriptFiles == null) {
return Observable.empty();
} else {
FileSorter.sort(scriptFiles, FileSorter.NAME);
mScriptFileCache.put(dir.getPath(), scriptFiles);
return Observable.fromArray(scriptFiles);
}
mScriptFileCache.put(dir.getPath(), new ArrayList<>(Arrays.asList(scriptFiles)));
return Observable.fromArray(scriptFiles);
}
});
}
private ScriptFile[] getScriptFilesFromCache(ScriptFile directory) {
private List<ScriptFile> getScriptFilesFromCache(ScriptFile directory) {
return mScriptFileCache.get(directory.getPath());
}

View File

@ -47,11 +47,13 @@ public class ScriptOperations {
private Context mContext;
private View mView;
private ScriptFile mCurrentDirectory;
private StorageFileProvider mStorageFileProvider;
public ScriptOperations(Context context, View view, ScriptFile currentDirectory) {
mContext = context;
mView = view;
mCurrentDirectory = currentDirectory;
mStorageFileProvider = StorageFileProvider.getDefault();
}
public ScriptOperations(Context context, View view) {
@ -83,9 +85,10 @@ public class ScriptOperations {
PFile.write(path, script);
} catch (UncheckedIOException e) {
showMessage(R.string.text_file_write_fail);
return;
}
}
notifyScriptFileChanged();
mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(path));
if (edit)
Scripts.edit(path);
} else {
@ -115,7 +118,7 @@ public class ScriptOperations {
} else {
showMessage(R.string.text_import_fail);
}
notifyScriptFileChanged();
mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(pathTo));
return pathTo;
}
});
@ -133,7 +136,7 @@ public class ScriptOperations {
} else {
showMessage(R.string.text_import_fail);
}
notifyScriptFileChanged();
mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(pathTo));
return pathTo;
}
});
@ -147,7 +150,7 @@ public class ScriptOperations {
public void accept(@io.reactivex.annotations.NonNull String path) throws Exception {
if (new ScriptFile(getCurrentDirectory(), path).mkdirs()) {
showMessage(R.string.text_already_create);
notifyScriptFileChanged();
mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(path));
} else {
showMessage(R.string.text_create_fail);
}
@ -155,10 +158,6 @@ public class ScriptOperations {
});
}
private void notifyScriptFileChanged() {
StorageFileProvider.getDefault().notifyDirectoryChanged(mCurrentDirectory);
}
private void showMessage(final int resId) {
if (Looper.myLooper() == Looper.getMainLooper()) {
showMessageWithoutThreadSwitch(resId);
@ -218,13 +217,18 @@ public class ScriptOperations {
}
public Observable<Boolean> rename(final ScriptFile file) {
final ScriptFile oldFile = new ScriptFile(file.getPath());
String originalName = file.getSimplifiedName();
return showNameInputDialog(originalName, new InputCallback(file.isDirectory() ? null : PFile.getExtension(file.getName()),
originalName))
.map(new Function<String, Boolean>() {
@Override
public Boolean apply(@io.reactivex.annotations.NonNull String newName) throws Exception {
return file.renameTo(newName);
ScriptFile newFile = file.renameAndReturnNewFile(newName);
if (newFile != null) {
mStorageFileProvider.notifyFileChanged(mCurrentDirectory, oldFile, newFile);
}
return newFile != null;
}
});
}
@ -246,7 +250,8 @@ public class ScriptOperations {
@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();
if (deleted)
mStorageFileProvider.notifyFileRemoved(mCurrentDirectory, scriptFile);
}
});
}

View File

@ -2,11 +2,13 @@ package com.stardust.scriptdroid.ui.edit;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
@ -59,7 +61,7 @@ public class CodeMirrorEditor extends FrameLayout {
private static String[] sAvailableThemes;
private String mTheme = "neo";
private MaterialProgressBar mProgressBar;
private FrameLayout mProgressBarContainer;
private WebView mWebView;
private JavaScriptBridge mJavaScriptBridge = new JavaScriptBridge();
private Callback mCallback;
@ -141,11 +143,15 @@ public class CodeMirrorEditor extends FrameLayout {
}
private void setupProgress() {
mProgressBar = new MaterialProgressBar(getContext());
mProgressBarContainer = new FrameLayout(getContext());
mProgressBarContainer.setBackgroundColor(Color.WHITE);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
addView(mProgressBarContainer, params);
MaterialProgressBar progressBar = new MaterialProgressBar(getContext());
int dp50 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(dp50, dp50);
params.gravity = Gravity.CENTER;
addView(mProgressBar, params);
FrameLayout.LayoutParams p = new FrameLayout.LayoutParams(dp50, dp50);
p.gravity = Gravity.CENTER;
mProgressBarContainer.addView(progressBar, p);
}
private void setupWebView() {
@ -171,7 +177,7 @@ public class CodeMirrorEditor extends FrameLayout {
}
public void setProgress(boolean onProgress) {
mProgressBar.setVisibility(onProgress ? VISIBLE : GONE);
mProgressBarContainer.setVisibility(onProgress ? VISIBLE : GONE);
}
public void setText(final String text) {
@ -464,7 +470,7 @@ public class CodeMirrorEditor extends FrameLayout {
@Override
public void onProgressChanged(WebView view, int newProgress) {
mProgressBar.setVisibility(newProgress == 100 ? GONE : VISIBLE);
setProgress(newProgress != 100);
}
}
}

View File

@ -7,9 +7,11 @@ import android.view.ContextThemeWrapper;
import android.view.View;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.FloatyWindow;
import com.stardust.enhancedfloaty.ResizableFloaty;
import com.stardust.enhancedfloaty.ResizableFloatyWindow;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.floatingwindow.FloatyWindowManger;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.ui.edit.EditActivity_;
import com.stardust.scriptdroid.ui.edit.EditorView;
@ -41,8 +43,7 @@ public class EditorFloaty implements ResizableFloaty {
}
public static void floatingEdit(Context context, Intent intent) {
FloatyService.addWindow(new ResizableFloatyWindow(new EditorFloaty(intent)));
context.startService(new Intent(context, FloatyService.class));
FloatyWindowManger.addWindow(context, new ResizableFloatyWindow(new EditorFloaty(intent)));
}
public static void floatingEdit(Context context, String path) {

View File

@ -314,7 +314,7 @@ public class ScriptListRecyclerView extends RecyclerView {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDirectoryChange(StorageFileProvider.DirectoryChangeEvent event) {
if (event.directory.equals(mCurrentDirectory)) {
if (event.getDir().equals(mCurrentDirectory)) {
updateCurrentDirectory();
}
}

View File

@ -30,6 +30,7 @@ import com.stardust.widget.BindableViewHolder;
import org.greenrobot.eventbus.Subscribe;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;
import butterknife.BindView;
import butterknife.ButterKnife;
@ -104,7 +105,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
initScriptListRecyclerView();
mStorageFileProvider = StorageFileProvider.getDefault();
setCurrentDirectory(mStorageFileProvider.getInitialDirectory());
//mStorageFileProvider.registerDirectoryChangeListener(this);
mStorageFileProvider.registerDirectoryChangeListener(this);
}
private void initScriptListRecyclerView() {
@ -158,9 +159,10 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Subscribe
void onDirectoryChange(StorageFileProvider.DirectoryChangeEvent event) {
if (event.directory.equals(mCurrentDirectory)) {
loadScriptList();
if (!event.getDir().equals(mCurrentDirectory)) {
return;
}
loadScriptList();
}
@Override
@ -238,7 +240,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// mStorageFileProvider.unregisterDirectoryChangeListener(this);
mStorageFileProvider.unregisterDirectoryChangeListener(this);
}
private class ScriptListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@ -404,6 +406,9 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@BindView(R.id.order)
ImageView mSortOrder;
@BindView(R.id.back)
ImageView mGoBack;
private boolean mIsDir;
CategoryViewHolder(View itemView) {
@ -415,6 +420,11 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
public void bind(Boolean isDirCategory, int position) {
mTitle.setText(isDirCategory ? R.string.text_directory : R.string.text_file);
mIsDir = isDirCategory;
if (isDirCategory && canGoBack()) {
mGoBack.setVisibility(VISIBLE);
} else {
mGoBack.setVisibility(GONE);
}
}
@OnClick(R.id.order)
@ -441,5 +451,12 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
popupMenu.show();
}
@OnClick(R.id.back)
void back() {
if (canGoBack()) {
goBack();
}
}
}
}

View File

@ -77,10 +77,10 @@ public class ScriptList {
}
public void add(ScriptFile file) {
if (file.isFile()) {
mScriptFiles.add(file);
} else {
if (file.isDirectory()) {
mDirectories.add(file);
} else {
mScriptFiles.add(file);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

View File

@ -34,6 +34,17 @@
</LinearLayout>
<ImageView
android:id="@+id/back"
android:layout_width="32dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:padding="9dp"
android:src="@drawable/ic_dir_up"
android:tint="#828384"/>
<ImageView
android:id="@+id/order"
android:layout_width="32dp"