diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/FloatyWindowManger.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/FloatyWindowManger.java new file mode 100644 index 00000000..f741b578 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/FloatyWindowManger.java @@ -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(); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java b/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java index 87714d18..bab57a3a 100644 --- a/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java +++ b/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java @@ -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); } } diff --git a/app/src/main/java/com/stardust/scriptdroid/script/StorageFileProvider.java b/app/src/main/java/com/stardust/scriptdroid/script/StorageFileProvider.java index 742da390..f69a65e7 100644 --- a/app/src/main/java/com/stardust/scriptdroid/script/StorageFileProvider.java +++ b/app/src/main/java/com/stardust/scriptdroid/script/StorageFileProvider.java @@ -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 mScriptFileCache; + private LimitedHashMap> 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 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 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 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 getDirectoryScriptFiles(ScriptFile directory) { - ScriptFile[] scriptFiles = getScriptFilesFromCache(directory); + List 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 listAndSortFiles(ScriptFile directory) { + private Observable listFiles(ScriptFile directory) { return Observable.just(directory) - .observeOn(Schedulers.computation()) - .flatMap(new Function>() { - - + .flatMap(new Function>() { @Override - public Observable apply(@NonNull ScriptFile dir) throws Exception { + public ObservableSource 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 getScriptFilesFromCache(ScriptFile directory) { return mScriptFileCache.get(directory.getPath()); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java index 10dd170e..83ba0344 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java @@ -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 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() { @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); } }); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/CodeMirrorEditor.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/CodeMirrorEditor.java index 47c936b3..7422998f 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/CodeMirrorEditor.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/CodeMirrorEditor.java @@ -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); } } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/floating/EditorFloaty.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/EditorFloaty.java index 1cc50bf6..f74a2c88 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/floating/EditorFloaty.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/EditorFloaty.java @@ -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) { diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListRecyclerView.java index 168f7bd6..8f87090d 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListRecyclerView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListRecyclerView.java @@ -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(); } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java index 0b32ca31..9d07398f 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java @@ -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 { @@ -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(); + } + } } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/viewmodel/ScriptList.java b/app/src/main/java/com/stardust/scriptdroid/ui/viewmodel/ScriptList.java index 6cef647f..56133982 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/viewmodel/ScriptList.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/viewmodel/ScriptList.java @@ -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); } } diff --git a/app/src/main/res/drawable/ic_dir_up.png b/app/src/main/res/drawable/ic_dir_up.png new file mode 100644 index 00000000..c81ca1ad Binary files /dev/null and b/app/src/main/res/drawable/ic_dir_up.png differ diff --git a/app/src/main/res/layout/script_file_list_category.xml b/app/src/main/res/layout/script_file_list_category.xml index 3e55004b..42149fc0 100644 --- a/app/src/main/res/layout/script_file_list_category.xml +++ b/app/src/main/res/layout/script_file_list_category.xml @@ -34,6 +34,17 @@ + +