refactor(ui): refactor ScriptListView
This commit is contained in:
@@ -2,6 +2,7 @@ package org.autojs.autojs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
@@ -9,6 +10,7 @@ import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
|
||||
|
||||
import org.autojs.autojs.autojs.key.GlobalKeyObserver;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -98,7 +100,7 @@ public class Pref {
|
||||
}
|
||||
|
||||
public static boolean shouldShowAd() {
|
||||
if(isFirstDay() && !BuildConfig.DEBUG){
|
||||
if (isFirstDay() && !BuildConfig.DEBUG) {
|
||||
return false;
|
||||
}
|
||||
String adShowingMode = def().getString(getString(R.string.key_ad_showing_mode), "Default");
|
||||
@@ -116,10 +118,10 @@ public class Pref {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int getAdType(){
|
||||
public static int getAdType() {
|
||||
try {
|
||||
return Integer.parseInt(def().getString(getString(R.string.key_ad_type), String.valueOf(Constants.AD_TYPE_RANDOM)));
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Constants.AD_TYPE_RANDOM;
|
||||
}
|
||||
@@ -127,7 +129,7 @@ public class Pref {
|
||||
|
||||
private static boolean isFirstDay() {
|
||||
long firstUsingMillis = def().getLong("firstUsingMillis", -1);
|
||||
if(firstUsingMillis == -1){
|
||||
if (firstUsingMillis == -1) {
|
||||
def().edit().putLong("firstUsingMillis", System.currentTimeMillis()).apply();
|
||||
return true;
|
||||
}
|
||||
@@ -195,7 +197,8 @@ public class Pref {
|
||||
}
|
||||
|
||||
public static String getScriptDirPath() {
|
||||
return def().getString(getString(R.string.key_script_dir_path),
|
||||
String dir = def().getString(getString(R.string.key_script_dir_path),
|
||||
getString(R.string.default_value_script_dir_path));
|
||||
return new File(Environment.getExternalStorageDirectory(), dir).getPath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@ import com.stardust.autojs.script.JavaScriptFileSource;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
import com.stardust.autojs.script.SequenceScriptSource;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.model.script.PathChecker;
|
||||
|
||||
import java.io.File;
|
||||
@@ -51,7 +52,7 @@ public class ScriptIntents {
|
||||
}
|
||||
config.executePath(new File(path).getParent());
|
||||
} else {
|
||||
config.executePath(StorageFileProvider.getDefaultDirectoryPath());
|
||||
config.executePath(Pref.getScriptDirPath());
|
||||
}
|
||||
if (source == null) {
|
||||
return false;
|
||||
|
||||
@@ -2,23 +2,24 @@ package org.autojs.autojs.external.tasker;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.external.ScriptIntents;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.ui.main.scripts.ScriptListView;
|
||||
import com.twofortyfouram.locale.sdk.client.ui.activity.AbstractAppCompatPluginActivity;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EActivity;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.external.ScriptIntents;
|
||||
import org.autojs.autojs.model.explorer.ExplorerDirPage;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.ui.main.scripts.ExplorerView;
|
||||
|
||||
import static org.autojs.autojs.ui.edit.EditorView.EXTRA_CONTENT;
|
||||
|
||||
@@ -31,7 +32,6 @@ public class TaskPrefEditActivity extends AbstractAppCompatPluginActivity {
|
||||
|
||||
private String mSelectedScriptFilePath;
|
||||
private String mPreExecuteScript;
|
||||
private StorageFileProvider mStorageFileProvider;
|
||||
|
||||
@AfterViews
|
||||
void setUpViews() {
|
||||
@@ -41,11 +41,10 @@ public class TaskPrefEditActivity extends AbstractAppCompatPluginActivity {
|
||||
|
||||
|
||||
private void initScriptListRecyclerView() {
|
||||
mStorageFileProvider = StorageFileProvider.getExternalStorageProvider();
|
||||
ScriptListView scriptList = (ScriptListView) findViewById(R.id.script_list);
|
||||
scriptList.setStorageFileProvider(mStorageFileProvider, new ScriptFile(StorageFileProvider.getDefaultDirectory()));
|
||||
scriptList.setOnScriptFileClickListener((view, file) -> {
|
||||
mSelectedScriptFilePath = file.getPath();
|
||||
ExplorerView explorerView = (ExplorerView) findViewById(R.id.script_list);
|
||||
explorerView.setExplorer(Explorers.external(), ExplorerDirPage.createRoot(Environment.getExternalStorageDirectory()));
|
||||
explorerView.setOnItemClickListener((view, item) -> {
|
||||
mSelectedScriptFilePath = item.getPath();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
@@ -59,7 +58,7 @@ public class TaskPrefEditActivity extends AbstractAppCompatPluginActivity {
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_refresh) {
|
||||
mStorageFileProvider.refreshAll();
|
||||
Explorers.external().refreshAll();
|
||||
} else if (item.getItemId() == R.id.action_clear_file_selection) {
|
||||
mSelectedScriptFilePath = null;
|
||||
} else {
|
||||
|
||||
@@ -3,18 +3,20 @@ package org.autojs.autojs.external.widget;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.ui.main.scripts.ScriptListView;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.EActivity;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.explorer.Explorer;
|
||||
import org.autojs.autojs.model.explorer.ExplorerDirPage;
|
||||
import org.autojs.autojs.model.explorer.ExplorerFileProvider;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.ui.main.scripts.ExplorerView;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/7/11.
|
||||
@@ -22,9 +24,8 @@ import org.androidannotations.annotations.EActivity;
|
||||
@EActivity(R.layout.activity_script_widget_settings)
|
||||
public class ScriptWidgetSettingsActivity extends BaseActivity {
|
||||
|
||||
|
||||
private String mSelectedScriptFilePath;
|
||||
private StorageFileProvider mStorageFileProvider;
|
||||
private Explorer mExplorer;
|
||||
private int mAppWidgetId;
|
||||
|
||||
@Override
|
||||
@@ -41,11 +42,10 @@ public class ScriptWidgetSettingsActivity extends BaseActivity {
|
||||
|
||||
|
||||
private void initScriptListRecyclerView() {
|
||||
mStorageFileProvider = StorageFileProvider.getExternalStorageProvider();
|
||||
ScriptListView scriptList = (ScriptListView) findViewById(R.id.script_list);
|
||||
scriptList.setStorageFileProvider(mStorageFileProvider);
|
||||
scriptList.setCurrentDirectory(new ScriptFile(StorageFileProvider.getDefaultDirectory()));
|
||||
scriptList.setOnScriptFileClickListener((view, file) -> {
|
||||
mExplorer = new Explorer(new ExplorerFileProvider(Scripts.FILE_FILTER), 0);
|
||||
ExplorerView explorerView = (ExplorerView) findViewById(R.id.script_list);
|
||||
explorerView.setExplorer(mExplorer, ExplorerDirPage.createRoot(Environment.getExternalStorageDirectory()));
|
||||
explorerView.setOnItemClickListener((view, file) -> {
|
||||
mSelectedScriptFilePath = file.getPath();
|
||||
finish();
|
||||
});
|
||||
@@ -55,7 +55,7 @@ public class ScriptWidgetSettingsActivity extends BaseActivity {
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_refresh) {
|
||||
mStorageFileProvider.refreshAll();
|
||||
mExplorer.refreshAll();
|
||||
} else if (item.getItemId() == R.id.action_clear_file_selection) {
|
||||
mSelectedScriptFilePath = null;
|
||||
}
|
||||
|
||||
114
app/src/main/java/org/autojs/autojs/model/explorer/Explorer.java
Normal file
114
app/src/main/java/org/autojs/autojs/model/explorer/Explorer.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.LruCache;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
||||
import static org.autojs.autojs.model.explorer.ExplorerChangeEvent.*;
|
||||
|
||||
|
||||
public class Explorer {
|
||||
|
||||
private final ExplorerProvider mExplorerProvider;
|
||||
private final EventBus mEventBus;
|
||||
@Nullable
|
||||
private final LruCache<String, ExplorerPage> mExplorerPageLruCache;
|
||||
|
||||
public Explorer(ExplorerProvider explorerProvider, int cacheSize, EventBus eventBus) {
|
||||
mExplorerPageLruCache = cacheSize <= 0 ? null : new LruCache<>(cacheSize);
|
||||
mExplorerProvider = explorerProvider;
|
||||
mEventBus = eventBus;
|
||||
}
|
||||
|
||||
public Explorer(ExplorerProvider explorerProvider, int cacheSize) {
|
||||
this(explorerProvider, cacheSize, EventBus.getDefault());
|
||||
}
|
||||
|
||||
public void notifyChildrenChanged(ExplorerPage itemGroup) {
|
||||
clearCache(itemGroup);
|
||||
mEventBus.post(new ExplorerChangeEvent(itemGroup));
|
||||
}
|
||||
|
||||
public void notifyItemChanged(ExplorerItem oldItem, ExplorerItem newItem) {
|
||||
ExplorerPage itemGroup = getParentFromCache(oldItem);
|
||||
if (itemGroup != null) {
|
||||
itemGroup.updateChild(oldItem, newItem);
|
||||
}
|
||||
mEventBus.post(new ExplorerChangeEvent(oldItem.getParent(), CHANGE, oldItem, newItem));
|
||||
}
|
||||
|
||||
private ExplorerPage getParentFromCache(ExplorerItem item) {
|
||||
if (mExplorerPageLruCache == null) {
|
||||
return null;
|
||||
}
|
||||
ExplorerPage parent = item.getParent();
|
||||
if (parent == null) {
|
||||
if (item instanceof ExplorerFileItem) {
|
||||
PFile parentFile = ((ExplorerFileItem) item).getFile().getParentFile();
|
||||
return parentFile == null ? null : mExplorerPageLruCache.get(parentFile.getPath());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return mExplorerPageLruCache.get(parent.getPath());
|
||||
}
|
||||
|
||||
|
||||
public void notifyItemRemoved(ExplorerItem item) {
|
||||
ExplorerPage itemGroup = getParentFromCache(item);
|
||||
if (itemGroup != null) {
|
||||
itemGroup.removeChild(item);
|
||||
}
|
||||
mEventBus.post(new ExplorerChangeEvent(item.getParent(), REMOVE, item));
|
||||
}
|
||||
|
||||
public void notifyItemCreated(ExplorerItem item) {
|
||||
ExplorerPage itemGroup = getParentFromCache(item);
|
||||
if (itemGroup != null) {
|
||||
itemGroup.addChild(item);
|
||||
}
|
||||
mEventBus.post(new ExplorerChangeEvent(item.getParent(), CREATE, item));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void refreshAll() {
|
||||
if (mExplorerPageLruCache != null)
|
||||
mExplorerPageLruCache.evictAll();
|
||||
mEventBus.post(new ExplorerChangeEvent(ALL));
|
||||
}
|
||||
|
||||
|
||||
public Single<ExplorerPage> fetchChildren(ExplorerPage page) {
|
||||
ExplorerPage cachedGroup = mExplorerPageLruCache.get(page.getPath());
|
||||
if (cachedGroup != null) {
|
||||
page.copyChildren(cachedGroup);
|
||||
return Single.just(page);
|
||||
}
|
||||
return mExplorerProvider.getExplorerPage(page)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.map(g -> {
|
||||
mExplorerPageLruCache.put(g.getPath(), g);
|
||||
page.copyChildren(g);
|
||||
return page;
|
||||
});
|
||||
}
|
||||
|
||||
private void clearCache(ExplorerPage item) {
|
||||
if (mExplorerPageLruCache != null)
|
||||
mExplorerPageLruCache.remove(item.getPath());
|
||||
}
|
||||
|
||||
public void registerChangeListener(Object subscriber) {
|
||||
if (!mEventBus.isRegistered(subscriber))
|
||||
mEventBus.register(subscriber);
|
||||
}
|
||||
|
||||
public void unregisterChangeListener(Object subscriber) {
|
||||
mEventBus.unregister(subscriber);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
public class ExplorerChangeEvent {
|
||||
|
||||
public static final int REMOVE = 0;
|
||||
public static final int CREATE = 1;
|
||||
public static final int CHANGE = 2;
|
||||
public static final int ALL = 3;
|
||||
|
||||
private final int mAction;
|
||||
private final ExplorerItem mItem;
|
||||
private final ExplorerItem mNewItem;
|
||||
private final ExplorerPage mItemGroup;
|
||||
|
||||
public ExplorerChangeEvent(ExplorerPage itemGroup) {
|
||||
this(itemGroup, CHANGE, null, null);
|
||||
}
|
||||
|
||||
public ExplorerChangeEvent(ExplorerPage parent, int action, ExplorerItem oldItem, ExplorerItem newItem) {
|
||||
mAction = action;
|
||||
mItemGroup = parent;
|
||||
mNewItem = newItem;
|
||||
mItem = oldItem;
|
||||
}
|
||||
|
||||
public ExplorerChangeEvent(ExplorerPage parent, int action, ExplorerItem item) {
|
||||
this(parent, action, item, null);
|
||||
}
|
||||
|
||||
public ExplorerChangeEvent(int action) {
|
||||
this(null, action, null, null);
|
||||
}
|
||||
|
||||
public int getAction() {
|
||||
return mAction;
|
||||
}
|
||||
|
||||
public ExplorerItem getItem() {
|
||||
return mItem;
|
||||
}
|
||||
|
||||
public ExplorerItem getNewItem() {
|
||||
return mNewItem;
|
||||
}
|
||||
|
||||
public ExplorerPage getItemGroup() {
|
||||
return mItemGroup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ExplorerDirPage extends ExplorerFileItem implements ExplorerPage {
|
||||
|
||||
private List<ExplorerItem> mChildren = Collections.emptyList();
|
||||
|
||||
public ExplorerDirPage(PFile file, ExplorerPage parent) {
|
||||
super(file, parent);
|
||||
}
|
||||
|
||||
public ExplorerDirPage(String path, ExplorerPage parent) {
|
||||
super(path, parent);
|
||||
}
|
||||
|
||||
public ExplorerDirPage(File file, ExplorerPage parent) {
|
||||
super(file, parent);
|
||||
}
|
||||
|
||||
public void copyChildren(ExplorerPage g) {
|
||||
ensureChildListWritable();
|
||||
mChildren.clear();
|
||||
mChildren.addAll(((ExplorerDirPage) g).mChildren);
|
||||
}
|
||||
|
||||
private void ensureChildListWritable() {
|
||||
if (mChildren == Collections.EMPTY_LIST) {
|
||||
mChildren = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updateChild(ExplorerItem oldItem, ExplorerItem newItem) {
|
||||
int i = mChildren.indexOf(oldItem);
|
||||
if (i < 0) {
|
||||
return false;
|
||||
}
|
||||
mChildren.set(i, newItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeChild(ExplorerItem item) {
|
||||
return mChildren.remove(item);
|
||||
}
|
||||
|
||||
public void addChild(ExplorerItem item) {
|
||||
ensureChildListWritable();
|
||||
mChildren.add(item);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Iterator<ExplorerItem> iterator() {
|
||||
return mChildren.iterator();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void forEach(Consumer<? super ExplorerItem> action) {
|
||||
mChildren.forEach(action);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public Spliterator<ExplorerItem> spliterator() {
|
||||
return mChildren.spliterator();
|
||||
}
|
||||
|
||||
public static ExplorerDirPage createRoot(String path){
|
||||
return new ExplorerDirPage(path, null);
|
||||
}
|
||||
|
||||
public static ExplorerPage createRoot(File directory) {
|
||||
return new ExplorerDirPage(directory, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ExplorerFileItem implements ExplorerItem {
|
||||
|
||||
private final PFile mFile;
|
||||
private final ExplorerPage mParent;
|
||||
|
||||
public ExplorerFileItem(PFile file, ExplorerPage parent) {
|
||||
mFile = file;
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
public ExplorerFileItem(String path, ExplorerPage parent) {
|
||||
mFile = new PFile(path);
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
public ExplorerFileItem(File file, ExplorerPage parent) {
|
||||
mFile = new PFile(file.getPath());
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
public PFile getFile() {
|
||||
return mFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return mFile.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerPage getParent() {
|
||||
return mParent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return mFile.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long lastModified() {
|
||||
return mFile.lastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
if(mFile.isDirectory()){
|
||||
return "/";
|
||||
}
|
||||
return mFile.getExtension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return mFile.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptFile toScriptFile() {
|
||||
return new ScriptFile(mFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable() {
|
||||
String type = getType();
|
||||
return type.equals("js") || type.equals("json") || type.equals("xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExecutable() {
|
||||
String type = getType();
|
||||
return type.equals("js") || type.equals("auto");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import java.io.FileFilter;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class ExplorerFileProvider implements ExplorerProvider {
|
||||
|
||||
private final FileFilter mFileFilter;
|
||||
|
||||
public ExplorerFileProvider(FileFilter fileFilter) {
|
||||
mFileFilter = fileFilter;
|
||||
}
|
||||
|
||||
public ExplorerFileProvider() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<? extends ExplorerPage> getExplorerPage(ExplorerPage page) {
|
||||
ExplorerPage parent = page.getParent();
|
||||
String path = page.getPath();
|
||||
return listFiles(new PFile(path))
|
||||
.collectInto(createExplorerPage(path, parent), (p, file) -> {
|
||||
if(file.isDirectory()){
|
||||
p.addChild(new ExplorerDirPage(file, p));
|
||||
}else {
|
||||
p.addChild(new ExplorerFileItem(file, p));
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
protected ExplorerDirPage createExplorerPage(String path, ExplorerPage parent) {
|
||||
return new ExplorerDirPage(path, parent);
|
||||
}
|
||||
|
||||
protected Observable<PFile> listFiles(PFile directory) {
|
||||
return Observable.just(directory)
|
||||
.flatMap(dir -> {
|
||||
PFile[] files;
|
||||
if (mFileFilter == null) {
|
||||
files = dir.listFiles();
|
||||
} else {
|
||||
files = dir.listFiles(mFileFilter);
|
||||
}
|
||||
if (files == null) {
|
||||
return Observable.empty();
|
||||
}
|
||||
return Observable.fromArray(files);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
|
||||
public interface ExplorerItem {
|
||||
|
||||
String TYPE_DIRECTORY = "/";
|
||||
String TYPE_JAVASCRIPT = "js";
|
||||
String TYPE_AUTO_FILE = "auto";
|
||||
String TYPE_JSON = "json";
|
||||
String TYPE_XML = "xml";
|
||||
String TYPE_UNKNOWN = "?";
|
||||
|
||||
String getName();
|
||||
|
||||
ExplorerPage getParent();
|
||||
|
||||
String getPath();
|
||||
|
||||
long lastModified();
|
||||
|
||||
String getType();
|
||||
|
||||
long getSize();
|
||||
|
||||
ScriptFile toScriptFile();
|
||||
|
||||
boolean isEditable();
|
||||
|
||||
boolean isExecutable();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public interface ExplorerPage extends ExplorerItem, Iterable<ExplorerItem> {
|
||||
|
||||
void copyChildren(ExplorerPage page);
|
||||
|
||||
boolean updateChild(ExplorerItem oldItem, ExplorerItem newItem);
|
||||
|
||||
boolean removeChild(ExplorerItem item);
|
||||
|
||||
void addChild(ExplorerItem item);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import io.reactivex.Single;
|
||||
|
||||
public interface ExplorerProvider {
|
||||
|
||||
Single<? extends ExplorerPage> getExplorerPage(ExplorerPage parent);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ExplorerSamplePage extends ExplorerDirPage {
|
||||
|
||||
private boolean mRoot = false;
|
||||
|
||||
public ExplorerSamplePage(PFile file, ExplorerPage parent) {
|
||||
super(file, parent);
|
||||
}
|
||||
|
||||
public ExplorerSamplePage(String path, ExplorerPage parent) {
|
||||
super(path, parent);
|
||||
}
|
||||
|
||||
public ExplorerSamplePage(File file, ExplorerPage parent) {
|
||||
super(file, parent);
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
return mRoot;
|
||||
}
|
||||
|
||||
public static ExplorerSamplePage createRoot(PFile dir) {
|
||||
ExplorerSamplePage page = new ExplorerSamplePage(dir, null);
|
||||
page.mRoot = true;
|
||||
return page;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ExplorerSorter {
|
||||
|
||||
private static final Collator collator = Collator.getInstance();
|
||||
|
||||
public static final Comparator<ExplorerItem> NAME = (o1, o2) -> collator.compare(o2.getName(), o1.getName());
|
||||
|
||||
public static final Comparator<ExplorerItem> DATE = (o1, o2) -> Long.compare(o1.lastModified(), o2.lastModified());
|
||||
|
||||
public static final Comparator<ExplorerItem> TYPE = (o1, o2) -> o2.getType().compareTo(o1.getType());
|
||||
|
||||
public static final Comparator<ExplorerItem> SIZE = (o1, o2) -> Long.compare(o2.getSize(), o1.getSize());
|
||||
|
||||
public static void sort(ExplorerItem[] items, final Comparator<ExplorerItem> comparator, boolean ascending) {
|
||||
if (ascending) {
|
||||
Arrays.sort(items, comparator);
|
||||
} else {
|
||||
Arrays.sort(items, (o1, o2) -> comparator.compare(o2, o1));
|
||||
}
|
||||
}
|
||||
|
||||
public static void sort(ExplorerItem[] items, Comparator<ExplorerItem> comparator) {
|
||||
sort(items, comparator, true);
|
||||
}
|
||||
|
||||
public static void sort(List<? extends ExplorerItem> items, final Comparator<ExplorerItem> comparator, boolean ascending) {
|
||||
if (ascending) {
|
||||
Collections.sort(items, comparator);
|
||||
} else {
|
||||
Collections.sort(items, (Comparator<ExplorerItem>) (o1, o2) -> comparator.compare(o2, o1));
|
||||
}
|
||||
}
|
||||
|
||||
public static void sort(List<? extends ExplorerItem> items, Comparator<ExplorerItem> comparator) {
|
||||
sort(items, comparator, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
public class Explorers {
|
||||
|
||||
|
||||
private static Explorer sWorkspaceExplorer = new Explorer(new WorkspaceFileProvider(GlobalAppContext.get(), null), 20);
|
||||
|
||||
private static Explorer sExternalExplorer = new Explorer(new ExplorerFileProvider(), 10);
|
||||
|
||||
public static Explorer workspace() {
|
||||
return sWorkspaceExplorer;
|
||||
}
|
||||
|
||||
public static Explorer external() {
|
||||
return sExternalExplorer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.autojs.autojs.model.explorer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class WorkspaceFileProvider extends ExplorerFileProvider {
|
||||
|
||||
private static final String SAMPLE_PATH = "sample";
|
||||
|
||||
private final PFile mSampleDir;
|
||||
private final AssetManager mAssetManager;
|
||||
private final Context mContext;
|
||||
|
||||
public WorkspaceFileProvider(Context context, FileFilter fileFilter) {
|
||||
super(fileFilter);
|
||||
mContext = context;
|
||||
mAssetManager = context.getAssets();
|
||||
mSampleDir = new PFile(context.getFilesDir(), SAMPLE_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<? extends ExplorerPage> getExplorerPage(ExplorerPage page) {
|
||||
ExplorerPage parent = page.getParent();
|
||||
String path = page.getPath();
|
||||
return listFiles(new PFile(path))
|
||||
.collectInto(createExplorerPage(path, parent), (p, file) -> {
|
||||
if(file.isDirectory()){
|
||||
if(file.getPath().startsWith(mSampleDir.getPath())){
|
||||
p.addChild(new ExplorerSamplePage(file, p));
|
||||
}else {
|
||||
p.addChild(new ExplorerDirPage(file, p));
|
||||
}
|
||||
}else {
|
||||
p.addChild(new ExplorerFileItem(file, p));
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Observable<PFile> listFiles(PFile directory) {
|
||||
if (directory.getPath().startsWith(mSampleDir.getPath())) {
|
||||
return listSamples(directory);
|
||||
}
|
||||
return super.listFiles(directory);
|
||||
}
|
||||
|
||||
private Observable<PFile> listSamples(PFile directory) {
|
||||
String pathOfSample;
|
||||
if(directory.getPath().length() <= mSampleDir.getPath().length() + 1){
|
||||
pathOfSample = "";
|
||||
}else {
|
||||
pathOfSample = directory.getPath().substring(mSampleDir.getPath().length());
|
||||
}
|
||||
String pathOfAsset = SAMPLE_PATH + pathOfSample;
|
||||
return Observable.just(pathOfAsset)
|
||||
.flatMap(path -> Observable.fromArray(mAssetManager.list(path)))
|
||||
.map(child -> {
|
||||
PFile file = new PFile(new File(directory, child).getPath());
|
||||
if(file.exists()){
|
||||
return file;
|
||||
}
|
||||
try {
|
||||
InputStream stream = mAssetManager.open(pathOfAsset + "/" + child);
|
||||
PFiles.copyStream(stream, file.getPath());
|
||||
}catch (FileNotFoundException e){
|
||||
file.mkdirs();
|
||||
}
|
||||
return file;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExplorerDirPage createExplorerPage(String path, ExplorerPage parent) {
|
||||
ExplorerDirPage page = super.createExplorerPage(path, parent);
|
||||
if (new File(path).equals(new File(Pref.getScriptDirPath()))) {
|
||||
page.addChild( ExplorerSamplePage.createRoot(mSampleDir));
|
||||
}
|
||||
return page;
|
||||
}
|
||||
}
|
||||
@@ -12,17 +12,18 @@ import com.stardust.autojs.execution.SimpleScriptExecutionListener;
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.external.ScriptIntents;
|
||||
import org.autojs.autojs.external.shortcut.Shortcut;
|
||||
import org.autojs.autojs.external.shortcut.ShortcutActivity;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.ui.edit.EditActivity;
|
||||
|
||||
import org.mozilla.javascript.RhinoException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/3.
|
||||
@@ -35,6 +36,9 @@ public class Scripts {
|
||||
public static final String EXTRA_EXCEPTION_LINE_NUMBER = "lineNumber";
|
||||
public static final String EXTRA_EXCEPTION_COLUMN_NUMBER = "columnNumber";
|
||||
|
||||
public static final FileFilter FILE_FILTER = file ->
|
||||
file.isDirectory() || file.getName().endsWith(".js") || file.getName().endsWith(".auto");
|
||||
|
||||
private static final ScriptExecutionListener BROADCAST_SENDER_SCRIPT_EXECUTION_LISTENER = new SimpleScriptExecutionListener() {
|
||||
|
||||
@Override
|
||||
@@ -99,8 +103,8 @@ public class Scripts {
|
||||
|
||||
public static ScriptExecution run(ScriptSource source) {
|
||||
return AutoJs.getInstance().getScriptEngineService().execute(source, new ExecutionConfig()
|
||||
.executePath(StorageFileProvider.getDefaultDirectoryPath())
|
||||
.requirePath(StorageFileProvider.getDefaultDirectoryPath()));
|
||||
.executePath(Pref.getScriptDirPath())
|
||||
.requirePath(Pref.getScriptDirPath()));
|
||||
}
|
||||
|
||||
public static ScriptExecution runWithBroadcastSender(File file) {
|
||||
|
||||
@@ -10,10 +10,10 @@ import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
@@ -99,7 +99,7 @@ public class DevPluginResponseHandler implements Handler {
|
||||
if (!name.endsWith(".js")) {
|
||||
name = name + ".js";
|
||||
}
|
||||
PFiles.write(new File(StorageFileProvider.getDefaultDirectoryPath(), name), script);
|
||||
PFiles.write(new File(Pref.getScriptDirPath(), name), script);
|
||||
GlobalAppContext.toast(R.string.text_script_save_successfully);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package org.autojs.autojs.storage.file;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.PFiles;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/28.
|
||||
*/
|
||||
|
||||
public class SampleFileProvider extends StorageFileProvider {
|
||||
|
||||
private AssetManager mAssetManager;
|
||||
private Context mContext;
|
||||
|
||||
public SampleFileProvider(String path, Context context) {
|
||||
super(path, 10);
|
||||
mContext = context;
|
||||
mAssetManager = context.getAssets();
|
||||
}
|
||||
|
||||
public SampleFileProvider(Context context) {
|
||||
this("sample/", context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Observable<PFile> listFiles(PFile directory) {
|
||||
return Observable.just(directory)
|
||||
.flatMap(dir -> Observable.fromArray(mAssetManager.list(directory.getPath())))
|
||||
.map(path -> {
|
||||
String absPath = new File(directory, path).getPath();
|
||||
if (!absPath.endsWith(".js")) {
|
||||
return new AssetDirectory(absPath);
|
||||
}
|
||||
PFile file = new PFile(mContext.getFilesDir(), absPath);
|
||||
if (!file.exists()) {
|
||||
copySample(mContext, absPath, file.getPath());
|
||||
}
|
||||
return file;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static boolean copySample(Context context, String samplePath, String pathTo) {
|
||||
PFiles.ensureDir(pathTo);
|
||||
return PFiles.copyAsset(context, samplePath, pathTo);
|
||||
}
|
||||
|
||||
public static class AssetDirectory extends ScriptFile {
|
||||
|
||||
public AssetDirectory(@NonNull String pathname) {
|
||||
super(pathname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFile() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
package org.autojs.autojs.storage.file;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
|
||||
import com.stardust.util.LimitedHashMap;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.io.FileFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/31.
|
||||
*/
|
||||
|
||||
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 final FileFilter SCRIPT_FILTER = file ->
|
||||
file.isDirectory() || file.getName().endsWith(".js") || file.getName().endsWith(".auto");
|
||||
|
||||
public static class DirectoryChangeEvent {
|
||||
|
||||
|
||||
private final PFile mDir;
|
||||
private final int mChange;
|
||||
private final PFile mFile;
|
||||
private final PFile mNewFile;
|
||||
|
||||
public DirectoryChangeEvent(PFile dir, int change, PFile file) {
|
||||
this(dir, change, file, file);
|
||||
}
|
||||
|
||||
public DirectoryChangeEvent(PFile directory) {
|
||||
this(directory, ALL, null);
|
||||
}
|
||||
|
||||
public DirectoryChangeEvent(PFile dir, int change, PFile oldFile, PFile newFile) {
|
||||
mDir = dir;
|
||||
mChange = change;
|
||||
mFile = oldFile;
|
||||
mNewFile = newFile;
|
||||
}
|
||||
|
||||
public PFile getDir() {
|
||||
return mDir;
|
||||
}
|
||||
|
||||
public int getChange() {
|
||||
return mChange;
|
||||
}
|
||||
|
||||
public PFile getFile() {
|
||||
return mFile;
|
||||
}
|
||||
|
||||
public PFile getNewFile() {
|
||||
return mNewFile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final PFile INITIAL_DIRECTORY_DEFAULT = new PFile("");
|
||||
|
||||
private static StorageFileProvider externalStorageProvider;
|
||||
private static final StorageFileProvider DEFAULT_PROVIDER = new StorageFileProvider(INITIAL_DIRECTORY_DEFAULT, 10, SCRIPT_FILTER);
|
||||
|
||||
private EventBus mDirectoryEventBus = new EventBus();
|
||||
private LimitedHashMap<String, List<PFile>> mPFileCache;
|
||||
private PFile mInitialDirectory;
|
||||
private FileFilter mFileFilter;
|
||||
|
||||
public StorageFileProvider(PFile initialDirectory, int cacheSize, FileFilter fileFilter) {
|
||||
mInitialDirectory = initialDirectory;
|
||||
mFileFilter = fileFilter;
|
||||
mPFileCache = new LimitedHashMap<>(cacheSize);
|
||||
}
|
||||
|
||||
|
||||
public StorageFileProvider(String path, int cacheSize) {
|
||||
this(new PFile(path), cacheSize);
|
||||
}
|
||||
|
||||
public StorageFileProvider(PFile initialDirectory, int cacheSize) {
|
||||
mInitialDirectory = initialDirectory;
|
||||
mPFileCache = new LimitedHashMap<>(cacheSize);
|
||||
}
|
||||
|
||||
public StorageFileProvider() {
|
||||
this(getDefaultDirectory(), 10);
|
||||
}
|
||||
|
||||
public static String getDefaultDirectoryPath() {
|
||||
return getDefaultDirectory().getPath();
|
||||
}
|
||||
|
||||
public static PFile getDefaultDirectory() {
|
||||
return new PFile(Environment.getExternalStorageDirectory(), Pref.getScriptDirPath());
|
||||
}
|
||||
|
||||
public static StorageFileProvider getDefault() {
|
||||
return DEFAULT_PROVIDER;
|
||||
}
|
||||
|
||||
public static StorageFileProvider getExternalStorageProvider() {
|
||||
if (externalStorageProvider == null) {
|
||||
externalStorageProvider = new StorageFileProvider(Environment.getExternalStorageDirectory().getPath(), 5);
|
||||
}
|
||||
return externalStorageProvider;
|
||||
}
|
||||
|
||||
public void notifyDirectoryChanged(PFile directory) {
|
||||
clearCache(directory);
|
||||
mDirectoryEventBus.post(new DirectoryChangeEvent(directory));
|
||||
}
|
||||
|
||||
public void notifyFileChanged(PFile dir, PFile oldFile, PFile newFile) {
|
||||
List<PFile> files = getFilesFromCache(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(PFile dir, PFile file) {
|
||||
List<PFile> files = getFilesFromCache(dir);
|
||||
if (files == null)
|
||||
return;
|
||||
if (files.remove(file)) {
|
||||
mDirectoryEventBus.post(new DirectoryChangeEvent(dir, REMOVE, file));
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyFileCreated(PFile dir, PFile file) {
|
||||
List<PFile> files = getFilesFromCache(dir);
|
||||
if (files == null)
|
||||
return;
|
||||
files.add(0, file);
|
||||
mDirectoryEventBus.post(new DirectoryChangeEvent(dir, CREATE, file));
|
||||
}
|
||||
|
||||
public void notifyStoragePermissionGranted() {
|
||||
mPFileCache.clear();
|
||||
mDirectoryEventBus.post(new DirectoryChangeEvent(getInitialDirectory()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void refreshAll() {
|
||||
Map<String, PFile> files = (Map<String, PFile>) mPFileCache.clone();
|
||||
mPFileCache.clear();
|
||||
mDirectoryEventBus.post(new DirectoryChangeEvent(getInitialDirectory()));
|
||||
for (Map.Entry<String, PFile> file : files.entrySet()) {
|
||||
mDirectoryEventBus.post(new DirectoryChangeEvent(new PFile(file.getKey())));
|
||||
}
|
||||
}
|
||||
|
||||
public PFile getInitialDirectory() {
|
||||
if (mInitialDirectory == INITIAL_DIRECTORY_DEFAULT) {
|
||||
return getDefaultDirectory();
|
||||
}
|
||||
return mInitialDirectory;
|
||||
}
|
||||
|
||||
public Observable<PFile> getInitialDirectoryFiles() {
|
||||
return getDirectoryFiles(getInitialDirectory());
|
||||
}
|
||||
|
||||
public Observable<PFile> getDirectoryFiles(PFile directory) {
|
||||
List<PFile> PFiles = getFilesFromCache(directory);
|
||||
if (PFiles == null) {
|
||||
return listFiles(directory);
|
||||
}
|
||||
return Observable.fromIterable(PFiles);
|
||||
}
|
||||
|
||||
private void clearCache(PFile directory) {
|
||||
mPFileCache.remove(directory.getPath());
|
||||
}
|
||||
|
||||
|
||||
protected Observable<PFile> listFiles(PFile directory) {
|
||||
return Observable.just(directory)
|
||||
.flatMap(dir -> {
|
||||
PFile[] files;
|
||||
if (mFileFilter == null) {
|
||||
files = dir.listFiles();
|
||||
} else {
|
||||
files = dir.listFiles(mFileFilter);
|
||||
}
|
||||
if (files == null) {
|
||||
return Observable.empty();
|
||||
}
|
||||
mPFileCache.put(dir.getPath(), new ArrayList<>(Arrays.asList(files)));
|
||||
return Observable.fromArray(files);
|
||||
});
|
||||
}
|
||||
|
||||
private List<PFile> getFilesFromCache(PFile directory) {
|
||||
return mPFileCache.get(directory.getPath());
|
||||
}
|
||||
|
||||
|
||||
public void registerDirectoryChangeListener(Object subscriber) {
|
||||
if (!mDirectoryEventBus.isRegistered(subscriber))
|
||||
mDirectoryEventBus.register(subscriber);
|
||||
}
|
||||
|
||||
public void unregisterDirectoryChangeListener(Object subscriber) {
|
||||
mDirectoryEventBus.unregister(subscriber);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,8 +14,8 @@ import com.raizlabs.android.dbflow.structure.BaseModel;
|
||||
import com.raizlabs.android.dbflow.structure.ModelAdapter;
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.storage.database.ModelChange;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -106,7 +106,7 @@ public class TimedTaskManager {
|
||||
public Flowable<IntentTask> getIntentTaskOfAction(String action) {
|
||||
IntentTask intentTask = new IntentTask();
|
||||
intentTask.setAction(Intent.ACTION_BOOT_COMPLETED);
|
||||
intentTask.setScriptPath(new File(StorageFileProvider.getDefaultDirectory(), "boot.js").getPath());
|
||||
intentTask.setScriptPath(new File(Pref.getScriptDirPath(), "boot.js").getPath());
|
||||
return Flowable.just(intentTask);
|
||||
// return RXSQLite.rx(SQLite.select().from(IntentTask.class))
|
||||
// .queryStreamResults()
|
||||
|
||||
@@ -23,11 +23,11 @@ import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EActivity;
|
||||
import org.androidannotations.annotations.ViewById;
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.build.AutoJsApkBuilder;
|
||||
import org.autojs.autojs.build.ApkBuilderPluginHelper;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import org.autojs.autojs.tool.BitmapTool;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
@@ -136,7 +136,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
|
||||
private void setupWithSourceFile(ScriptFile file) {
|
||||
String dir = file.getParent();
|
||||
if (dir.startsWith(getFilesDir().getPath())) {
|
||||
dir = StorageFileProvider.getDefaultDirectoryPath();
|
||||
dir = Pref.getScriptDirPath();
|
||||
}
|
||||
mOutputPath.setText(dir);
|
||||
mAppName.setText(file.getSimplifiedName());
|
||||
@@ -156,7 +156,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
|
||||
new FileChooserDialogBuilder(this)
|
||||
.title(R.string.text_source_file_path)
|
||||
.dir(Environment.getExternalStorageDirectory().getPath(),
|
||||
initialDir == null ? StorageFileProvider.getDefaultDirectoryPath() : initialDir)
|
||||
initialDir == null ? Pref.getScriptDirPath() : initialDir)
|
||||
.singleChoice(this::setSource)
|
||||
.show();
|
||||
}
|
||||
@@ -178,7 +178,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
|
||||
@Click(R.id.select_output)
|
||||
void selectOutputDirPath() {
|
||||
String initialDir = new File(mOutputPath.getText().toString()).exists() ?
|
||||
mOutputPath.getText().toString() : StorageFileProvider.getDefaultDirectoryPath();
|
||||
mOutputPath.getText().toString() : Pref.getScriptDirPath();
|
||||
new FileChooserDialogBuilder(this)
|
||||
.title(R.string.text_output_apk_path)
|
||||
.dir(initialDir)
|
||||
|
||||
@@ -9,7 +9,6 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
@@ -22,22 +21,24 @@ import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.external.ScriptIntents;
|
||||
import org.autojs.autojs.model.explorer.Explorer;
|
||||
import org.autojs.autojs.model.explorer.ExplorerFileItem;
|
||||
import org.autojs.autojs.model.explorer.ExplorerItem;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.storage.file.TmpScriptFiles;
|
||||
import org.autojs.autojs.model.sample.SampleFile;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.network.download.DownloadManager;
|
||||
import org.autojs.autojs.tool.SimpleObserver;
|
||||
import org.autojs.autojs.ui.filechooser.FileChooserDialogBuilder;
|
||||
import org.autojs.autojs.ui.shortcut.ShortcutCreateActivity;
|
||||
import org.autojs.autojs.ui.timing.TimedTaskSettingActivity_;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -53,23 +54,34 @@ import io.reactivex.subjects.PublishSubject;
|
||||
* Created by Stardust on 2017/7/31.
|
||||
*/
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
public class ScriptOperations {
|
||||
|
||||
private static final String LOG_TAG = "ScriptOperations";
|
||||
private final ExplorerItem mExplorerItem;
|
||||
private Context mContext;
|
||||
private View mView;
|
||||
private ScriptFile mCurrentDirectory;
|
||||
private StorageFileProvider mStorageFileProvider;
|
||||
private Explorer mExplorer;
|
||||
|
||||
public ScriptOperations(Context context, View view, ScriptFile currentDirectory) {
|
||||
mContext = context;
|
||||
mView = view;
|
||||
mCurrentDirectory = currentDirectory;
|
||||
mStorageFileProvider = StorageFileProvider.getDefault();
|
||||
mExplorer = Explorers.workspace();
|
||||
mExplorerItem = new ExplorerFileItem(currentDirectory, null);
|
||||
}
|
||||
|
||||
public ScriptOperations(Context context, View view, ExplorerItem item) {
|
||||
mContext = context;
|
||||
mView = view;
|
||||
mCurrentDirectory = item.toScriptFile();
|
||||
mExplorer = Explorers.workspace();
|
||||
mExplorerItem = item;
|
||||
}
|
||||
|
||||
public ScriptOperations(Context context, View view) {
|
||||
this(context, view, new ScriptFile(StorageFileProvider.getDefaultDirectory()));
|
||||
this(context, view, new ScriptFile(Pref.getScriptDirPath()));
|
||||
}
|
||||
|
||||
public void newScriptFileForScript(final String script) {
|
||||
@@ -97,7 +109,7 @@ public class ScriptOperations {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(path));
|
||||
notifyFileCreated(mCurrentDirectory, new ScriptFile(path));
|
||||
if (edit)
|
||||
Scripts.edit(path);
|
||||
} else {
|
||||
@@ -105,6 +117,10 @@ public class ScriptOperations {
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyFileCreated(ScriptFile directory, ScriptFile scriptFile) {
|
||||
mExplorer.notifyItemCreated(new ExplorerFileItem(scriptFile, mExplorerItem.getParent()));
|
||||
}
|
||||
|
||||
public void newScriptFile() {
|
||||
showFileNameInputDialog("", "js")
|
||||
.subscribe(input -> createScriptFile(getCurrentDirectoryPath() + input + ".js", null, true));
|
||||
@@ -123,7 +139,7 @@ public class ScriptOperations {
|
||||
return pathTo;
|
||||
})
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext(path -> mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(path)));
|
||||
.doOnNext(path -> notifyFileCreated(mCurrentDirectory, new ScriptFile(path)));
|
||||
}
|
||||
|
||||
public Observable<String> importFile(String prefix, final InputStream inputStream, final String ext) {
|
||||
@@ -136,7 +152,7 @@ public class ScriptOperations {
|
||||
} else {
|
||||
showMessage(R.string.text_import_fail);
|
||||
}
|
||||
mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(pathTo));
|
||||
notifyFileCreated(mCurrentDirectory, new ScriptFile(pathTo));
|
||||
return pathTo;
|
||||
});
|
||||
}
|
||||
@@ -148,7 +164,7 @@ public class ScriptOperations {
|
||||
ScriptFile newDir = new ScriptFile(getCurrentDirectory(), path);
|
||||
if (newDir.mkdirs()) {
|
||||
showMessage(R.string.text_already_create);
|
||||
mStorageFileProvider.notifyFileCreated(mCurrentDirectory, new ScriptFile(newDir));
|
||||
notifyFileCreated(mCurrentDirectory, new ScriptFile(newDir));
|
||||
} else {
|
||||
showMessage(R.string.text_create_fail);
|
||||
}
|
||||
@@ -213,12 +229,17 @@ public class ScriptOperations {
|
||||
.map(newName -> {
|
||||
PFile newFile = file.renameAndReturnNewFile(newName);
|
||||
if (newFile != null) {
|
||||
mStorageFileProvider.notifyFileChanged(mCurrentDirectory, oldFile, newFile);
|
||||
notifyFileChanged(mCurrentDirectory, oldFile, newFile);
|
||||
}
|
||||
return newFile != null;
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyFileChanged(ScriptFile directory, ScriptFile oldFile, PFile newFile) {
|
||||
mExplorer.notifyItemChanged(new ExplorerFileItem(oldFile, mExplorerItem.getParent()),
|
||||
new ExplorerFileItem(newFile, mExplorerItem.getParent()));
|
||||
}
|
||||
|
||||
public void createShortcut(ScriptFile file) {
|
||||
mContext.startActivity(new Intent(mContext, ShortcutCreateActivity.class)
|
||||
.putExtra(ShortcutCreateActivity.EXTRA_FILE, file));
|
||||
@@ -244,10 +265,14 @@ public class ScriptOperations {
|
||||
.subscribe(deleted -> {
|
||||
showMessage(deleted ? R.string.text_already_delete : R.string.text_delete_failed);
|
||||
if (deleted)
|
||||
mStorageFileProvider.notifyFileRemoved(mCurrentDirectory, scriptFile);
|
||||
notifyFileRemoved(mCurrentDirectory, scriptFile);
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyFileRemoved(ScriptFile directory, ScriptFile scriptFile) {
|
||||
mExplorer.notifyItemRemoved(new ExplorerFileItem(scriptFile, mExplorerItem.getParent()));
|
||||
}
|
||||
|
||||
|
||||
public Observable<ScriptFile> download(String url) {
|
||||
String fileName = DownloadManager.parseFileNameLocally(url);
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.autojs.autojs.ui.explorer;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.explorer.ExplorerFileItem;
|
||||
import org.autojs.autojs.model.explorer.ExplorerItem;
|
||||
import org.autojs.autojs.model.explorer.ExplorerPage;
|
||||
import org.autojs.autojs.model.explorer.ExplorerSamplePage;
|
||||
|
||||
import static android.support.v4.content.ContextCompat.getColor;
|
||||
import static org.autojs.autojs.model.explorer.ExplorerItem.TYPE_AUTO_FILE;
|
||||
import static org.autojs.autojs.model.explorer.ExplorerItem.TYPE_JAVASCRIPT;
|
||||
import static org.autojs.autojs.model.explorer.ExplorerItem.TYPE_UNKNOWN;
|
||||
|
||||
public class ExplorerViewHelper {
|
||||
|
||||
public static String getDisplayName(ExplorerItem item) {
|
||||
if (item instanceof ExplorerSamplePage && ((ExplorerSamplePage) item).isRoot()) {
|
||||
return GlobalAppContext.getString(R.string.text_sample);
|
||||
}
|
||||
if (item instanceof ExplorerPage) {
|
||||
return item.getName();
|
||||
}
|
||||
String type = item.getType();
|
||||
if (type.equals(TYPE_JAVASCRIPT) || type.equals(TYPE_AUTO_FILE)) {
|
||||
if (item instanceof ExplorerFileItem) {
|
||||
return ((ExplorerFileItem) item).getFile().getSimplifiedName();
|
||||
}
|
||||
return PFiles.getNameWithoutExtension(item.getName());
|
||||
}
|
||||
return item.getName();
|
||||
}
|
||||
|
||||
public static String getIconText(ExplorerItem item) {
|
||||
String type = item.getType();
|
||||
if (type.isEmpty()) {
|
||||
return TYPE_UNKNOWN;
|
||||
}
|
||||
if (type.equals(TYPE_AUTO_FILE)) {
|
||||
return "R";
|
||||
}
|
||||
|
||||
return type.substring(0, 1).toUpperCase();
|
||||
}
|
||||
|
||||
public static int getIconColor(ExplorerItem item) {
|
||||
switch (item.getType()) {
|
||||
case TYPE_JAVASCRIPT:
|
||||
return getColor(GlobalAppContext.get(), R.color.color_j);
|
||||
case TYPE_AUTO_FILE:
|
||||
return getColor(GlobalAppContext.get(), R.color.color_r);
|
||||
default:
|
||||
return Color.GRAY;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getIcon(ExplorerPage page) {
|
||||
if (page instanceof ExplorerSamplePage) {
|
||||
return R.drawable.ic_sample_dir;
|
||||
}
|
||||
return R.drawable.ic_folder_yellow_100px;
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,23 @@ package org.autojs.autojs.ui.filechooser;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.support.v7.widget.SimpleItemAnimator;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.explorer.ExplorerItem;
|
||||
import org.autojs.autojs.model.explorer.ExplorerPage;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.ui.main.scripts.ScriptListView;
|
||||
import org.autojs.autojs.ui.explorer.ExplorerViewHelper;
|
||||
import org.autojs.autojs.ui.main.scripts.ExplorerView;
|
||||
import org.autojs.autojs.ui.widget.BindableViewHolder;
|
||||
import org.autojs.autojs.ui.widget.CheckBoxCompat;
|
||||
|
||||
@@ -33,7 +37,7 @@ import butterknife.OnClick;
|
||||
* Created by Stardust on 2017/10/19.
|
||||
*/
|
||||
|
||||
public class FileChooseListView extends ScriptListView {
|
||||
public class FileChooseListView extends ExplorerView {
|
||||
|
||||
private int mMaxChoice = 1;
|
||||
private LinkedHashMap<PFile, Integer> mSelectedFiles = new LinkedHashMap<>();
|
||||
@@ -66,17 +70,16 @@ public class FileChooseListView extends ScriptListView {
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setDirectorySpanSize(2);
|
||||
((SimpleItemAnimator) getScriptListView().getItemAnimator())
|
||||
((SimpleItemAnimator) getExplorerItemListView().getItemAnimator())
|
||||
.setSupportsChangeAnimations(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BindableViewHolder<?> onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
|
||||
if (viewType == VIEW_TYPE_FILE) {
|
||||
return new ScriptFileViewHolder(inflater.inflate(R.layout.file_choose_list_file, parent, false));
|
||||
} else if (viewType == VIEW_TYPE_DIRECTORY) {
|
||||
return new DirectoryViewHolder(inflater.inflate(R.layout.file_choose_list_directory, parent, false));
|
||||
if (viewType == VIEW_TYPE_ITEM) {
|
||||
return new ExplorerItemViewHolder(inflater.inflate(R.layout.file_choose_list_file, parent, false));
|
||||
} else if (viewType == VIEW_TYPE_PAGE) {
|
||||
return new ExplorerPageViewHolder(inflater.inflate(R.layout.file_choose_list_directory, parent, false));
|
||||
} else {
|
||||
return super.onCreateViewHolder(inflater, parent, viewType);
|
||||
}
|
||||
@@ -87,13 +90,13 @@ public class FileChooseListView extends ScriptListView {
|
||||
Map.Entry<PFile, Integer> itemToUncheck = mSelectedFiles.entrySet().iterator().next();
|
||||
int positionOfItemToUncheck = itemToUncheck.getValue();
|
||||
mSelectedFiles.remove(itemToUncheck.getKey());
|
||||
getScriptListView().getAdapter().notifyItemChanged(positionOfItemToUncheck);
|
||||
getExplorerItemListView().getAdapter().notifyItemChanged(positionOfItemToUncheck);
|
||||
}
|
||||
mSelectedFiles.put(file, position);
|
||||
}
|
||||
|
||||
|
||||
class ScriptFileViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
class ExplorerItemViewHolder extends BindableViewHolder<ExplorerItem> {
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
@@ -105,27 +108,22 @@ public class FileChooseListView extends ScriptListView {
|
||||
TextView mDesc;
|
||||
GradientDrawable mFirstCharBackground;
|
||||
|
||||
private ScriptFile mScriptFile;
|
||||
private ExplorerItem mExplorerItem;
|
||||
|
||||
ScriptFileViewHolder(View itemView) {
|
||||
ExplorerItemViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile file, int position) {
|
||||
mScriptFile = file;
|
||||
mName.setText(file.getSimplifiedName());
|
||||
mDesc.setText(PFiles.getHumanReadableSize(file.length()));
|
||||
mCheckBox.setChecked(mSelectedFiles.containsKey(file), false);
|
||||
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
|
||||
mFirstChar.setText("J");
|
||||
mFirstCharBackground.setColor(ResourcesCompat.getColor(getResources(), R.color.color_j, getContext().getTheme()));
|
||||
} else {
|
||||
mFirstChar.setText("R");
|
||||
mFirstCharBackground.setColor(ResourcesCompat.getColor(getResources(), R.color.color_r, getContext().getTheme()));
|
||||
}
|
||||
public void bind(ExplorerItem item, int position) {
|
||||
mExplorerItem = item;
|
||||
mName.setText(ExplorerViewHelper.getDisplayName(item));
|
||||
mDesc.setText(PFiles.getHumanReadableSize(item.getSize()));
|
||||
mFirstChar.setText(ExplorerViewHelper.getIconText(item));
|
||||
mFirstCharBackground.setColor(ExplorerViewHelper.getIconColor(item));
|
||||
mCheckBox.setChecked(mSelectedFiles.containsKey(mExplorerItem.toScriptFile()), false);
|
||||
}
|
||||
|
||||
@OnClick(R.id.item)
|
||||
@@ -136,16 +134,16 @@ public class FileChooseListView extends ScriptListView {
|
||||
@OnCheckedChanged(R.id.checkbox)
|
||||
void onCheckedChanged() {
|
||||
if (mCheckBox.isChecked()) {
|
||||
check(mScriptFile, getAdapterPosition());
|
||||
check(mExplorerItem.toScriptFile(), getAdapterPosition());
|
||||
} else {
|
||||
mSelectedFiles.remove(mScriptFile);
|
||||
mSelectedFiles.remove(mExplorerItem.toScriptFile());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class DirectoryViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
class ExplorerPageViewHolder extends BindableViewHolder<ExplorerPage> {
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
@@ -153,34 +151,38 @@ public class FileChooseListView extends ScriptListView {
|
||||
@BindView(R.id.checkbox)
|
||||
CheckBoxCompat mCheckBox;
|
||||
|
||||
private ScriptFile mScriptFile;
|
||||
@BindView(R.id.icon)
|
||||
ImageView mIcon;
|
||||
|
||||
DirectoryViewHolder(View itemView) {
|
||||
private ExplorerPage mExplorerPage;
|
||||
|
||||
ExplorerPageViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
mCheckBox.setVisibility(mCanChooseDir ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile data, int position) {
|
||||
mName.setText(data.getSimplifiedName());
|
||||
mScriptFile = data;
|
||||
public void bind(ExplorerPage data, int position) {
|
||||
mExplorerPage = data;
|
||||
mName.setText(ExplorerViewHelper.getDisplayName(data));
|
||||
mIcon.setImageResource(ExplorerViewHelper.getIcon(data));
|
||||
if (mCanChooseDir) {
|
||||
mCheckBox.setChecked(mSelectedFiles.containsKey(data), false);
|
||||
mCheckBox.setChecked(mSelectedFiles.containsKey(data.toScriptFile()), false);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.item)
|
||||
void onItemClick() {
|
||||
setCurrentDirectory(mScriptFile);
|
||||
enterChildPage(mExplorerPage);
|
||||
}
|
||||
|
||||
@OnCheckedChanged(R.id.checkbox)
|
||||
void onCheckedChanged() {
|
||||
if (mCheckBox.isChecked()) {
|
||||
check(mScriptFile, getAdapterPosition());
|
||||
check(mExplorerPage.toScriptFile(), getAdapterPosition());
|
||||
} else {
|
||||
mSelectedFiles.remove(mScriptFile);
|
||||
mSelectedFiles.remove(mExplorerPage.toScriptFile());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,19 @@ import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.model.explorer.Explorer;
|
||||
import org.autojs.autojs.model.explorer.ExplorerDirPage;
|
||||
import org.autojs.autojs.model.explorer.ExplorerFileProvider;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,8 +38,10 @@ public class FileChooserDialogBuilder extends ThemeColorMaterialDialogBuilder {
|
||||
}
|
||||
|
||||
private FileChooseListView mFileChooseListView;
|
||||
private PFile mRootDir = StorageFileProvider.getDefaultDirectory();
|
||||
private MultiChoiceCallback mCallback;
|
||||
private FileFilter mFileFilter;
|
||||
private String mRootDir;
|
||||
private String mInitialDir;
|
||||
|
||||
public FileChooserDialogBuilder(@NonNull Context context) {
|
||||
super(context);
|
||||
@@ -41,9 +49,7 @@ public class FileChooserDialogBuilder extends ThemeColorMaterialDialogBuilder {
|
||||
customView(mFileChooseListView, false);
|
||||
positiveText(R.string.ok);
|
||||
negativeText(R.string.cancel);
|
||||
onPositive((dialog, which) -> {
|
||||
notifySelected();
|
||||
});
|
||||
onPositive((dialog, which) -> notifySelected());
|
||||
}
|
||||
|
||||
private void notifySelected() {
|
||||
@@ -58,28 +64,26 @@ public class FileChooserDialogBuilder extends ThemeColorMaterialDialogBuilder {
|
||||
}
|
||||
|
||||
public FileChooserDialogBuilder dir(String rootDir, String initialDir) {
|
||||
mRootDir = new PFile(rootDir);
|
||||
if (mRootDir.equals(StorageFileProvider.getDefaultDirectory())) {
|
||||
mFileChooseListView.setStorageFileProvider(StorageFileProvider.getDefault());
|
||||
} else {
|
||||
mFileChooseListView.setStorageFileProvider(new StorageFileProvider(mRootDir, 10), new ScriptFile(initialDir));
|
||||
}
|
||||
mRootDir = rootDir;
|
||||
mInitialDir = initialDir;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileChooserDialogBuilder dir(String dir) {
|
||||
return dir(dir, dir);
|
||||
mRootDir = dir;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileChooserDialogBuilder justScriptFile() {
|
||||
mFileChooseListView.setStorageFileProvider(new StorageFileProvider(mRootDir, 10, StorageFileProvider.SCRIPT_FILTER));
|
||||
mFileFilter = Scripts.FILE_FILTER;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public FileChooserDialogBuilder chooseDir() {
|
||||
mFileFilter = File::isDirectory;
|
||||
mFileChooseListView.setCanChooseDir(true);
|
||||
mFileChooseListView.setStorageFileProvider(new StorageFileProvider(mRootDir, 10, File::isDirectory));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -121,4 +125,18 @@ public class FileChooserDialogBuilder extends ThemeColorMaterialDialogBuilder {
|
||||
super.title(titleRes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialDialog build() {
|
||||
ExplorerDirPage root = ExplorerDirPage.createRoot(mRootDir);
|
||||
Explorer explorer = mFileFilter == null ? Explorers.external() :
|
||||
new Explorer(new ExplorerFileProvider(mFileFilter), 0);
|
||||
if(mInitialDir == null){
|
||||
mFileChooseListView.setExplorer(explorer, root);
|
||||
}else {
|
||||
mFileChooseListView.setExplorer(explorer, root,
|
||||
new ExplorerDirPage(mInitialDir, root));
|
||||
}
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,19 +15,22 @@ import com.stardust.autojs.core.record.Recorder;
|
||||
import com.stardust.enhancedfloaty.FloatyService;
|
||||
import com.stardust.enhancedfloaty.FloatyWindow;
|
||||
import com.stardust.floatingcircularactionmenu.CircularActionMenu;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.accessibility.AccessibilityService;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.autojs.record.GlobalActionRecorder;
|
||||
import org.autojs.autojs.model.explorer.ExplorerDirPage;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.tool.AccessibilityServiceTool;
|
||||
import org.autojs.autojs.tool.RootTool;
|
||||
import org.autojs.autojs.ui.common.NotAskAgainDialog;
|
||||
import org.autojs.autojs.ui.floating.layoutinspector.LayoutBoundsFloatyWindow;
|
||||
import org.autojs.autojs.ui.floating.layoutinspector.LayoutHierarchyFloatyWindow;
|
||||
import org.autojs.autojs.ui.main.MainActivity_;
|
||||
import org.autojs.autojs.ui.main.scripts.ScriptListView;
|
||||
import org.autojs.autojs.ui.main.scripts.ExplorerView;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
import com.stardust.util.Func1;
|
||||
@@ -132,16 +135,16 @@ public class CircularMenu implements Recorder.OnStateChangedListener, LayoutInsp
|
||||
@OnClick(R.id.script_list)
|
||||
void showScriptList() {
|
||||
mWindow.collapse();
|
||||
ScriptListView listView = new ScriptListView(mContext);
|
||||
listView.setStorageFileProvider(StorageFileProvider.getDefault());
|
||||
listView.setDirectorySpanSize(2);
|
||||
ExplorerView explorerView = new ExplorerView(mContext);
|
||||
explorerView.setExplorer(Explorers.workspace(), ExplorerDirPage.createRoot(Pref.getScriptDirPath()));
|
||||
explorerView.setDirectorySpanSize(2);
|
||||
final MaterialDialog dialog = new ThemeColorMaterialDialogBuilder(mContext)
|
||||
.title(R.string.text_run_script)
|
||||
.customView(listView, false)
|
||||
.customView(explorerView, false)
|
||||
.positiveText(R.string.cancel)
|
||||
.build();
|
||||
listView.setOnItemOperatedListener(file -> dialog.dismiss());
|
||||
listView.setOnScriptFileClickListener((view, file) -> Scripts.run(file));
|
||||
explorerView.setOnItemOperatedListener(file -> dialog.dismiss());
|
||||
explorerView.setOnItemClickListener((view, item) -> Scripts.run(item.toScriptFile()));
|
||||
DialogUtils.showDialog(dialog);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
package org.autojs.autojs.ui.main;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@@ -23,40 +19,12 @@ import android.view.View;
|
||||
|
||||
import com.stardust.app.FragmentPagerAdapterBuilder;
|
||||
import com.stardust.app.OnActivityResultDelegate;
|
||||
import com.stardust.autojs.core.image.OpenCVHelper;
|
||||
import com.stardust.autojs.core.permission.OnRequestPermissionsResultCallback;
|
||||
import com.stardust.autojs.core.permission.PermissionRequestProxyActivity;
|
||||
import com.stardust.autojs.core.permission.RequestPermissionCallbacks;
|
||||
import com.stardust.enhancedfloaty.FloatyService;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.model.indices.AndroidClassIndices;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.timing.TimedTaskManager;
|
||||
import org.autojs.autojs.tool.AccessibilityServiceTool;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.ui.common.NotAskAgainDialog;
|
||||
import org.autojs.autojs.ui.doc.DocsFragment_;
|
||||
import org.autojs.autojs.ui.floating.FloatyWindowManger;
|
||||
import org.autojs.autojs.ui.log.LogActivity_;
|
||||
import org.autojs.autojs.ui.main.community.CommunityFragment;
|
||||
import org.autojs.autojs.ui.main.community.CommunityFragment_;
|
||||
import org.autojs.autojs.ui.main.sample.SampleListFragment_;
|
||||
import org.autojs.autojs.ui.main.scripts.MyScriptListFragment_;
|
||||
import org.autojs.autojs.ui.main.task.TaskManagerFragment_;
|
||||
import org.autojs.autojs.ui.settings.SettingsActivity_;
|
||||
import org.autojs.autojs.ui.update.VersionGuard;
|
||||
import org.autojs.autojs.ui.widget.CommonMarkdownView;
|
||||
import org.autojs.autojs.ui.widget.SearchViewItem;
|
||||
|
||||
import com.stardust.theme.ThemeColorManager;
|
||||
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import com.stardust.util.BackPressedHandler;
|
||||
import com.stardust.util.DeveloperUtils;
|
||||
import com.stardust.util.DrawerAutoClose;
|
||||
@@ -65,14 +33,31 @@ import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EActivity;
|
||||
import org.androidannotations.annotations.ViewById;
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.tool.AccessibilityServiceTool;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.ui.common.NotAskAgainDialog;
|
||||
import org.autojs.autojs.ui.doc.DocsFragment_;
|
||||
import org.autojs.autojs.ui.floating.FloatyWindowManger;
|
||||
import org.autojs.autojs.ui.log.LogActivity_;
|
||||
import org.autojs.autojs.ui.main.community.CommunityFragment;
|
||||
import org.autojs.autojs.ui.main.community.CommunityFragment_;
|
||||
import org.autojs.autojs.ui.main.sample.MarketFragment_;
|
||||
import org.autojs.autojs.ui.main.scripts.MyScriptListFragment_;
|
||||
import org.autojs.autojs.ui.main.task.TaskManagerFragment_;
|
||||
import org.autojs.autojs.ui.settings.SettingsActivity_;
|
||||
import org.autojs.autojs.ui.update.VersionGuard;
|
||||
import org.autojs.autojs.ui.widget.CommonMarkdownView;
|
||||
import org.autojs.autojs.ui.widget.SearchViewItem;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.opencv.core.Core;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
||||
@EActivity(R.layout.activity_main)
|
||||
public class MainActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost, BackPressedHandler.HostActivity, PermissionRequestProxyActivity {
|
||||
|
||||
@@ -178,10 +163,10 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
private void setUpTabViewPager() {
|
||||
TabLayout tabLayout = $(R.id.tab);
|
||||
mPagerAdapter = new FragmentPagerAdapterBuilder(this)
|
||||
.add(new MyScriptListFragment_(), R.string.text_script)
|
||||
.add(new MyScriptListFragment_(), R.string.text_file)
|
||||
.add(new DocsFragment_(), R.string.text_tutorial)
|
||||
.add(new CommunityFragment_(), R.string.text_community)
|
||||
.add(new SampleListFragment_(), R.string.text_sample)
|
||||
.add(new MarketFragment_(), R.string.text_sample)
|
||||
.add(new TaskManagerFragment_(), R.string.text_manage)
|
||||
.build();
|
||||
mViewPager.setAdapter(mPagerAdapter);
|
||||
@@ -250,7 +235,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
return;
|
||||
}
|
||||
if (getGrantResult(Manifest.permission.READ_EXTERNAL_STORAGE, permissions, grantResults) == PackageManager.PERMISSION_GRANTED) {
|
||||
StorageFileProvider.getDefault().notifyStoragePermissionGranted();
|
||||
Explorers.workspace().refreshAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import android.webkit.ValueCallback;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.network.NodeBB;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.network.download.DownloadManager;
|
||||
import org.autojs.autojs.ui.common.OptionListView;
|
||||
@@ -24,7 +24,6 @@ import java.util.regex.Pattern;
|
||||
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Optional;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
||||
/**
|
||||
@@ -134,7 +133,7 @@ public class CommunityWebView extends EWebView {
|
||||
}
|
||||
new FileChooserDialogBuilder(getContext())
|
||||
.title(R.string.text_select_file_to_upload)
|
||||
.dir(StorageFileProvider.getDefaultDirectoryPath())
|
||||
.dir(Pref.getScriptDirPath())
|
||||
.singleChoice(file -> callback.onReceiveValue(Uri.fromFile(file)))
|
||||
.cancelListener(dialog -> callback.onReceiveValue(null))
|
||||
.show();
|
||||
|
||||
@@ -6,11 +6,9 @@ import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.storage.file.SampleFileProvider;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.ui.main.QueryEvent;
|
||||
import org.autojs.autojs.ui.main.ViewPagerFragment;
|
||||
import org.autojs.autojs.ui.main.scripts.ScriptListView;
|
||||
import org.autojs.autojs.ui.main.scripts.ExplorerView;
|
||||
import com.stardust.util.BackPressedHandler;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
@@ -22,17 +20,14 @@ import org.greenrobot.eventbus.Subscribe;
|
||||
/**
|
||||
* Created by Stardust on 2017/10/28.
|
||||
*/
|
||||
@EFragment(R.layout.fragment_sample_list)
|
||||
public class SampleListFragment extends ViewPagerFragment implements BackPressedHandler {
|
||||
@EFragment(R.layout.fragment_market)
|
||||
public class MarketFragment extends ViewPagerFragment implements BackPressedHandler {
|
||||
|
||||
|
||||
public SampleListFragment() {
|
||||
public MarketFragment() {
|
||||
super(ROTATION_GONE);
|
||||
}
|
||||
|
||||
@ViewById(R.id.sample_list)
|
||||
ScriptListView mScriptFileList;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -41,9 +36,7 @@ public class SampleListFragment extends ViewPagerFragment implements BackPressed
|
||||
|
||||
@AfterViews
|
||||
void setUpViews() {
|
||||
mScriptFileList.setDirectorySpanSize(2);
|
||||
mScriptFileList.setStorageFileProvider(new SampleFileProvider(getContext()));
|
||||
mScriptFileList.setOnScriptFileClickListener((view, file) -> Scripts.edit(file));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,10 +63,7 @@ public class SampleListFragment extends ViewPagerFragment implements BackPressed
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed(Activity activity) {
|
||||
if (mScriptFileList.canGoBack()) {
|
||||
mScriptFileList.goBack();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -84,11 +74,9 @@ public class SampleListFragment extends ViewPagerFragment implements BackPressed
|
||||
return;
|
||||
}
|
||||
if (event == QueryEvent.CLEAR) {
|
||||
mScriptFileList.setFilter(null);
|
||||
return;
|
||||
}
|
||||
String query = event.getQuery();
|
||||
mScriptFileList.setFilter((file -> file.getSimplifiedName().contains(query)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
package org.autojs.autojs.ui.main.sample;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.stardust.pio.PFiles;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.storage.file.SampleFileProvider;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.ui.common.ScriptOperations;
|
||||
import org.autojs.autojs.ui.main.scripts.ScriptListView;
|
||||
import org.autojs.autojs.ui.widget.BindableViewHolder;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/28.
|
||||
*/
|
||||
|
||||
public class SampleListView extends ScriptListView {
|
||||
public SampleListView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SampleListView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.copy_to_my_script:
|
||||
new ScriptOperations(getContext(), this)
|
||||
.importFile(mSelectedScriptFile.getPath())
|
||||
.subscribe();
|
||||
return true;
|
||||
case R.id.reset:
|
||||
resetSample();
|
||||
return true;
|
||||
default:
|
||||
return super.onMenuItemClick(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetSample() {
|
||||
String samplePath = new File(getCurrentDirectory(), mSelectedScriptFile.getName()).getPath();
|
||||
if (SampleFileProvider.copySample(getContext(), samplePath, mSelectedScriptFile.getPath())) {
|
||||
Snackbar.make(this, R.string.text_reset_succeed, Snackbar.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Snackbar.make(this, R.string.text_reset_fail, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BindableViewHolder<?> onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
|
||||
if (viewType == VIEW_TYPE_FILE) {
|
||||
return new SampleFileViewHolder(inflater.inflate(R.layout.script_file_list_file, parent, false));
|
||||
} else if (viewType == VIEW_TYPE_DIRECTORY) {
|
||||
DirectoryViewHolder viewHolder = (DirectoryViewHolder) super.onCreateViewHolder(inflater, parent, viewType);
|
||||
viewHolder.mOptions.setVisibility(GONE);
|
||||
return viewHolder;
|
||||
}
|
||||
return super.onCreateViewHolder(inflater, parent, viewType);
|
||||
}
|
||||
|
||||
class SampleFileViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
@BindView(R.id.first_char)
|
||||
TextView mFirstChar;
|
||||
@BindView(R.id.desc)
|
||||
TextView mDesc;
|
||||
@BindView(R.id.more)
|
||||
View mOptions;
|
||||
@BindView(R.id.edit)
|
||||
View mEdit;
|
||||
GradientDrawable mFirstCharBackground;
|
||||
private ScriptFile mScriptFile;
|
||||
|
||||
SampleFileViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile file, int position) {
|
||||
mScriptFile = file;
|
||||
mName.setText(file.getSimplifiedName());
|
||||
mDesc.setText(PFiles.getHumanReadableSize(file.length()));
|
||||
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
|
||||
mFirstChar.setText("J");
|
||||
mFirstCharBackground.setColor(ResourcesCompat.getColor(getResources(), R.color.color_j, getContext().getTheme()));
|
||||
mEdit.setVisibility(VISIBLE);
|
||||
} else {
|
||||
mFirstChar.setText("R");
|
||||
mFirstCharBackground.setColor(ResourcesCompat.getColor(getResources(), R.color.color_r, getContext().getTheme()));
|
||||
mEdit.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.item)
|
||||
void onItemClick() {
|
||||
if (mOnScriptFileClickListener != null) {
|
||||
mOnScriptFileClickListener.onScriptFileClick(itemView, mScriptFile);
|
||||
}
|
||||
notifyOperated();
|
||||
}
|
||||
|
||||
@OnClick(R.id.run)
|
||||
void run() {
|
||||
Scripts.run(mScriptFile);
|
||||
notifyOperated();
|
||||
}
|
||||
|
||||
@OnClick(R.id.edit)
|
||||
void edit() {
|
||||
Scripts.edit(mScriptFile);
|
||||
notifyOperated();
|
||||
}
|
||||
|
||||
@OnClick(R.id.more)
|
||||
void showOptionMenu() {
|
||||
mSelectedScriptFile = mScriptFile;
|
||||
PopupMenu popupMenu = new PopupMenu(getContext(), mOptions);
|
||||
popupMenu.inflate(R.menu.menu_sample_options);
|
||||
popupMenu.setOnMenuItemClickListener(SampleListView.this);
|
||||
popupMenu.show();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
@@ -17,22 +16,28 @@ import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.explorer.Explorer;
|
||||
import org.autojs.autojs.model.explorer.ExplorerChangeEvent;
|
||||
import org.autojs.autojs.model.explorer.ExplorerItem;
|
||||
import org.autojs.autojs.model.explorer.ExplorerPage;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.ui.build.BuildActivity;
|
||||
import org.autojs.autojs.ui.build.BuildActivity_;
|
||||
import org.autojs.autojs.ui.common.ScriptLoopDialog;
|
||||
import org.autojs.autojs.ui.common.ScriptOperations;
|
||||
import org.autojs.autojs.ui.viewmodel.ScriptList;
|
||||
import org.autojs.autojs.ui.explorer.ExplorerViewHelper;
|
||||
import org.autojs.autojs.ui.viewmodel.ExplorerItemList;
|
||||
import org.autojs.autojs.ui.widget.BindableViewHolder;
|
||||
import org.autojs.autojs.theme.widget.ThemeColorSwipeRefreshLayout;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
@@ -45,83 +50,93 @@ import io.reactivex.schedulers.Schedulers;
|
||||
* Created by Stardust on 2017/8/21.
|
||||
*/
|
||||
|
||||
public class ScriptListView extends ThemeColorSwipeRefreshLayout implements SwipeRefreshLayout.OnRefreshListener, PopupMenu.OnMenuItemClickListener {
|
||||
public class ExplorerView extends ThemeColorSwipeRefreshLayout implements SwipeRefreshLayout.OnRefreshListener, PopupMenu.OnMenuItemClickListener {
|
||||
|
||||
private static final String LOG_TAG = "ExplorerView";
|
||||
|
||||
private static final String LOG_TAG = "ScriptListView";
|
||||
|
||||
public interface OnScriptFileClickListener {
|
||||
void onScriptFileClick(View view, ScriptFile file);
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(View view, ExplorerItem item);
|
||||
}
|
||||
|
||||
public interface OnItemOperatedListener {
|
||||
void OnItemOperated(ScriptFile file);
|
||||
void OnItemOperated(ExplorerItem item);
|
||||
}
|
||||
|
||||
protected static final int VIEW_TYPE_FILE = 0;
|
||||
protected static final int VIEW_TYPE_DIRECTORY = 1;
|
||||
protected static final int VIEW_TYPE_ITEM = 0;
|
||||
protected static final int VIEW_TYPE_PAGE = 1;
|
||||
//category是类别,也即"文件", "文件夹"那两个
|
||||
protected static final int VIEW_TYPE_CATEGORY = 2;
|
||||
|
||||
private static final int positionOfCategoryDir = 0;
|
||||
private ScriptList mScriptList = new ScriptList();
|
||||
private RecyclerView mScriptListView;
|
||||
private ScriptListAdapter mScriptListAdapter = new ScriptListAdapter();
|
||||
private ScriptFile mCurrentDirectory;
|
||||
protected OnScriptFileClickListener mOnScriptFileClickListener;
|
||||
private Function<PFile, Boolean> mFilter;
|
||||
private OnItemOperatedListener mOnItemOperatedListener;
|
||||
protected ScriptFile mSelectedScriptFile;
|
||||
private StorageFileProvider mStorageFileProvider;
|
||||
private boolean mDirSortMenuShowing = false;
|
||||
private boolean mDirsCollapsed;
|
||||
private boolean mFilesCollapsed;
|
||||
private int mDirectorySpanSize = 1;
|
||||
|
||||
public ScriptListView(Context context) {
|
||||
private ExplorerItemList mExplorerItemList = new ExplorerItemList();
|
||||
private RecyclerView mExplorerItemListView;
|
||||
private ExplorerAdapter mExplorerAdapter = new ExplorerAdapter();
|
||||
protected OnItemClickListener mOnItemClickListener;
|
||||
private Function<ExplorerItem, Boolean> mFilter;
|
||||
private OnItemOperatedListener mOnItemOperatedListener;
|
||||
protected ExplorerItem mSelectedItem;
|
||||
private Explorer mExplorer;
|
||||
private Stack<ExplorerPageState> mPageStateHistory = new Stack<>();
|
||||
private ExplorerPageState mCurrentPageState = new ExplorerPageState();
|
||||
private boolean mDirSortMenuShowing = false;
|
||||
private int mDirectorySpanSize = 2;
|
||||
|
||||
public ExplorerView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ScriptListView(Context context, @Nullable AttributeSet attrs) {
|
||||
public ExplorerView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ScriptFile getCurrentDirectory() {
|
||||
return mCurrentDirectory;
|
||||
public ExplorerPage getCurrentPage() {
|
||||
return mCurrentPageState.page;
|
||||
}
|
||||
|
||||
public void setCurrentDirectory(ScriptFile currentDirectory) {
|
||||
mCurrentDirectory = currentDirectory;
|
||||
mDirsCollapsed = false;
|
||||
mFilesCollapsed = false;
|
||||
loadScriptList();
|
||||
}
|
||||
|
||||
public void setOnScriptFileClickListener(OnScriptFileClickListener onScriptFileClickListener) {
|
||||
mOnScriptFileClickListener = onScriptFileClickListener;
|
||||
}
|
||||
|
||||
public void setStorageFileProvider(StorageFileProvider storageFileProvider) {
|
||||
setStorageFileProvider(storageFileProvider, new ScriptFile(storageFileProvider.getInitialDirectory()));
|
||||
public void setRootPage(ExplorerPage page) {
|
||||
mPageStateHistory.clear();
|
||||
mCurrentPageState = new ExplorerPageState(page);
|
||||
loadItemList();
|
||||
}
|
||||
|
||||
|
||||
public void setSortConfig(ScriptList.SortConfig sortConfig) {
|
||||
mScriptList.setSortConfig(sortConfig);
|
||||
public void enterChildPage(ExplorerPage childItemGroup) {
|
||||
mPageStateHistory.push(mCurrentPageState);
|
||||
mCurrentPageState = new ExplorerPageState(childItemGroup);
|
||||
loadItemList();
|
||||
}
|
||||
|
||||
public ScriptList.SortConfig getSortConfig() {
|
||||
return mScriptList.getSortConfig();
|
||||
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
|
||||
mOnItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
public void setStorageFileProvider(StorageFileProvider fileProvider, ScriptFile currentDirectory) {
|
||||
if (mStorageFileProvider != null)
|
||||
mStorageFileProvider.unregisterDirectoryChangeListener(this);
|
||||
mStorageFileProvider = fileProvider;
|
||||
setCurrentDirectory(currentDirectory);
|
||||
mStorageFileProvider.registerDirectoryChangeListener(this);
|
||||
public void setSortConfig(ExplorerItemList.SortConfig sortConfig) {
|
||||
mExplorerItemList.setSortConfig(sortConfig);
|
||||
}
|
||||
|
||||
public ExplorerItemList.SortConfig getSortConfig() {
|
||||
return mExplorerItemList.getSortConfig();
|
||||
}
|
||||
|
||||
public void setExplorer(Explorer explorer, ExplorerPage rootPage) {
|
||||
if (mExplorer != null)
|
||||
mExplorer.unregisterChangeListener(this);
|
||||
mExplorer = explorer;
|
||||
setRootPage(rootPage);
|
||||
mExplorer.registerChangeListener(this);
|
||||
}
|
||||
|
||||
public void setExplorer(Explorer explorer, ExplorerPage rootPage, ExplorerPage currentPage) {
|
||||
if (mExplorer != null)
|
||||
mExplorer.unregisterChangeListener(this);
|
||||
mExplorer = explorer;
|
||||
mPageStateHistory.clear();
|
||||
mCurrentPageState = new ExplorerPageState(rootPage);
|
||||
mExplorer.registerChangeListener(this);
|
||||
enterChildPage(currentPage);
|
||||
}
|
||||
|
||||
public void setOnItemOperatedListener(OnItemOperatedListener onItemOperatedListener) {
|
||||
@@ -129,35 +144,36 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
}
|
||||
|
||||
public boolean canGoBack() {
|
||||
return !mCurrentDirectory.equals(mStorageFileProvider.getInitialDirectory());
|
||||
return !mPageStateHistory.empty();
|
||||
}
|
||||
|
||||
public void goBack() {
|
||||
setCurrentDirectory(mCurrentDirectory.getParentFile());
|
||||
mCurrentPageState = mPageStateHistory.pop();
|
||||
loadItemList();
|
||||
}
|
||||
|
||||
public void setDirectorySpanSize(int directorySpanSize) {
|
||||
mDirectorySpanSize = directorySpanSize;
|
||||
}
|
||||
|
||||
public void setFilter(Function<PFile, Boolean> filter) {
|
||||
public void setFilter(Function<ExplorerItem, Boolean> filter) {
|
||||
mFilter = filter;
|
||||
reload();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
loadScriptList();
|
||||
loadItemList();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setOnRefreshListener(this);
|
||||
mScriptListView = new RecyclerView(getContext());
|
||||
addView(mScriptListView);
|
||||
initScriptListRecyclerView();
|
||||
mExplorerItemListView = new RecyclerView(getContext());
|
||||
addView(mExplorerItemListView);
|
||||
initExplorerItemListView();
|
||||
}
|
||||
|
||||
private void initScriptListRecyclerView() {
|
||||
mScriptListView.setAdapter(mScriptListAdapter);
|
||||
private void initExplorerItemListView() {
|
||||
mExplorerItemListView.setAdapter(mExplorerAdapter);
|
||||
GridLayoutManager manager = new GridLayoutManager(getContext(), 2);
|
||||
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||
@Override
|
||||
@@ -170,102 +186,105 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
mScriptListView.setLayoutManager(manager);
|
||||
mExplorerItemListView.setLayoutManager(manager);
|
||||
}
|
||||
|
||||
private int positionOfCategoryFile() {
|
||||
if (mDirsCollapsed)
|
||||
if (mCurrentPageState.dirsCollapsed)
|
||||
return 1;
|
||||
return mScriptList.directoryCount() + 1;
|
||||
return mExplorerItemList.groupCount() + 1;
|
||||
}
|
||||
|
||||
private void loadScriptList() {
|
||||
@SuppressLint("CheckResult")
|
||||
private void loadItemList() {
|
||||
setRefreshing(true);
|
||||
mStorageFileProvider.getDirectoryFiles(mCurrentDirectory)
|
||||
mExplorer.fetchChildren(mCurrentPageState.page)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.filter(f -> mFilter == null ? true : mFilter.apply(f))
|
||||
.collectInto(mScriptList.cloneConfig(), (list, file) -> {
|
||||
if (file instanceof ScriptFile) {
|
||||
list.add((ScriptFile) file);
|
||||
} else {
|
||||
list.add(new ScriptFile(file));
|
||||
}
|
||||
.flatMapObservable(page -> {
|
||||
mCurrentPageState.page = page;
|
||||
return Observable.fromIterable(page);
|
||||
})
|
||||
.filter(f -> mFilter == null ? true : mFilter.apply(f))
|
||||
.collectInto(mExplorerItemList.cloneConfig(), ExplorerItemList::add)
|
||||
.observeOn(Schedulers.computation())
|
||||
.doOnSuccess(ScriptList::sort)
|
||||
.doOnSuccess(ExplorerItemList::sort)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(list -> {
|
||||
mScriptList = list;
|
||||
mScriptListAdapter.notifyDataSetChanged();
|
||||
mExplorerItemList = list;
|
||||
mExplorerAdapter.notifyDataSetChanged();
|
||||
setRefreshing(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDirectoryChange(StorageFileProvider.DirectoryChangeEvent event) {
|
||||
if (!event.getDir().equals(mCurrentDirectory)) {
|
||||
return;
|
||||
public void onExplorerChange(ExplorerChangeEvent event) {
|
||||
if (event.getAction() == ExplorerChangeEvent.ALL
|
||||
|| mCurrentPageState.page.equals(event.getItemGroup())) {
|
||||
loadItemList();
|
||||
}
|
||||
loadScriptList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
mStorageFileProvider.notifyDirectoryChanged(mCurrentDirectory);
|
||||
mExplorer.notifyChildrenChanged(mCurrentPageState.page);
|
||||
}
|
||||
|
||||
|
||||
public ScriptFile getCurrentDirectory() {
|
||||
return getCurrentPage().toScriptFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.rename:
|
||||
new ScriptOperations(getContext(), this, getCurrentDirectory())
|
||||
.rename(mSelectedScriptFile)
|
||||
new ScriptOperations(getContext(), this, getCurrentPage())
|
||||
.rename(mSelectedItem.toScriptFile())
|
||||
.subscribe();
|
||||
break;
|
||||
case R.id.delete:
|
||||
new ScriptOperations(getContext(), this, getCurrentDirectory())
|
||||
.delete(mSelectedScriptFile);
|
||||
new ScriptOperations(getContext(), this, getCurrentPage())
|
||||
.delete(mSelectedItem.toScriptFile());
|
||||
break;
|
||||
case R.id.run_repeatedly:
|
||||
new ScriptLoopDialog(getContext(), mSelectedScriptFile)
|
||||
new ScriptLoopDialog(getContext(), mSelectedItem.toScriptFile())
|
||||
.show();
|
||||
notifyOperated();
|
||||
break;
|
||||
case R.id.create_shortcut:
|
||||
new ScriptOperations(getContext(), this, getCurrentDirectory())
|
||||
.createShortcut(mSelectedScriptFile);
|
||||
new ScriptOperations(getContext(), this, getCurrentPage())
|
||||
.createShortcut(mSelectedItem.toScriptFile());
|
||||
break;
|
||||
case R.id.open_by_other_apps:
|
||||
Scripts.openByOtherApps(mSelectedScriptFile);
|
||||
Scripts.openByOtherApps(mSelectedItem.toScriptFile());
|
||||
notifyOperated();
|
||||
break;
|
||||
case R.id.send:
|
||||
Scripts.send(mSelectedScriptFile);
|
||||
Scripts.send(mSelectedItem.toScriptFile());
|
||||
notifyOperated();
|
||||
break;
|
||||
case R.id.timed_task:
|
||||
new ScriptOperations(getContext(), this, getCurrentDirectory())
|
||||
.timedTask(mSelectedScriptFile);
|
||||
new ScriptOperations(getContext(), this, getCurrentPage())
|
||||
.timedTask(mSelectedItem.toScriptFile());
|
||||
notifyOperated();
|
||||
break;
|
||||
case R.id.action_build_apk:
|
||||
BuildActivity_.intent(getContext())
|
||||
.extra(BuildActivity.EXTRA_SOURCE_FILE, mSelectedScriptFile.getPath())
|
||||
.extra(BuildActivity.EXTRA_SOURCE_FILE, mSelectedItem.getPath())
|
||||
.start();
|
||||
notifyOperated();
|
||||
break;
|
||||
case R.id.action_sort_by_date:
|
||||
sort(ScriptList.SORT_TYPE_DATE, mDirSortMenuShowing);
|
||||
sort(ExplorerItemList.SORT_TYPE_DATE, mDirSortMenuShowing);
|
||||
break;
|
||||
case R.id.action_sort_by_type:
|
||||
sort(ScriptList.SORT_TYPE_TYPE, mDirSortMenuShowing);
|
||||
sort(ExplorerItemList.SORT_TYPE_TYPE, mDirSortMenuShowing);
|
||||
break;
|
||||
case R.id.action_sort_by_name:
|
||||
sort(ScriptList.SORT_TYPE_NAME, mDirSortMenuShowing);
|
||||
sort(ExplorerItemList.SORT_TYPE_NAME, mDirSortMenuShowing);
|
||||
break;
|
||||
case R.id.action_sort_by_size:
|
||||
sort(ScriptList.SORT_TYPE_SIZE, mDirSortMenuShowing);
|
||||
sort(ExplorerItemList.SORT_TYPE_SIZE, mDirSortMenuShowing);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@@ -275,7 +294,7 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
|
||||
protected void notifyOperated() {
|
||||
if (mOnItemOperatedListener != null) {
|
||||
mOnItemOperatedListener.OnItemOperated(mSelectedScriptFile);
|
||||
mOnItemOperatedListener.OnItemOperated(mSelectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,17 +303,17 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
setRefreshing(true);
|
||||
Observable.fromCallable(() -> {
|
||||
if (isDir) {
|
||||
mScriptList.sortDir(sortType);
|
||||
mExplorerItemList.sortItemGroup(sortType);
|
||||
} else {
|
||||
mScriptList.sortFile(sortType);
|
||||
mExplorerItemList.sortFile(sortType);
|
||||
}
|
||||
return mScriptList;
|
||||
return mExplorerItemList;
|
||||
})
|
||||
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(o -> {
|
||||
mScriptListAdapter.notifyDataSetChanged();
|
||||
mExplorerAdapter.notifyDataSetChanged();
|
||||
setRefreshing(false);
|
||||
});
|
||||
}
|
||||
@@ -303,38 +322,38 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (mStorageFileProvider != null)
|
||||
mStorageFileProvider.registerDirectoryChangeListener(this);
|
||||
if (mExplorer != null)
|
||||
mExplorer.registerChangeListener(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mStorageFileProvider.unregisterDirectoryChangeListener(this);
|
||||
mExplorer.unregisterChangeListener(this);
|
||||
}
|
||||
|
||||
|
||||
protected BindableViewHolder<?> onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
|
||||
if (viewType == VIEW_TYPE_FILE) {
|
||||
return new ScriptFileViewHolder(inflater.inflate(R.layout.script_file_list_file, parent, false));
|
||||
} else if (viewType == VIEW_TYPE_DIRECTORY) {
|
||||
return new DirectoryViewHolder(inflater.inflate(R.layout.script_file_list_directory, parent, false));
|
||||
if (viewType == VIEW_TYPE_ITEM) {
|
||||
return new ExplorerItemViewHolder(inflater.inflate(R.layout.script_file_list_file, parent, false));
|
||||
} else if (viewType == VIEW_TYPE_PAGE) {
|
||||
return new ExplorerPageViewHolder(inflater.inflate(R.layout.script_file_list_directory, parent, false));
|
||||
} else {
|
||||
return new CategoryViewHolder(inflater.inflate(R.layout.script_file_list_category, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
protected RecyclerView getScriptListView() {
|
||||
return mScriptListView;
|
||||
protected RecyclerView getExplorerItemListView() {
|
||||
return mExplorerItemListView;
|
||||
}
|
||||
|
||||
private class ScriptListAdapter extends RecyclerView.Adapter<BindableViewHolder<?>> {
|
||||
private class ExplorerAdapter extends RecyclerView.Adapter<BindableViewHolder<?>> {
|
||||
|
||||
@Override
|
||||
public BindableViewHolder<?> onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
return ScriptListView.this.onCreateViewHolder(inflater, parent, viewType);
|
||||
return ExplorerView.this.onCreateViewHolder(inflater, parent, viewType);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -343,15 +362,14 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
int positionOfCategoryFile = positionOfCategoryFile();
|
||||
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
|
||||
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
|
||||
// FIXME: 2017/10/20 java.lang.ClassCastException: java.lang.Boolean cannot be cast to org.autojs.autojs.model.script.ScriptFile
|
||||
bindableViewHolder.bind(position == positionOfCategoryDir, position);
|
||||
return;
|
||||
}
|
||||
if (position < positionOfCategoryFile) {
|
||||
bindableViewHolder.bind(mScriptList.getDir(position - 1), position);
|
||||
bindableViewHolder.bind(mExplorerItemList.getItemGroup(position - 1), position);
|
||||
return;
|
||||
}
|
||||
bindableViewHolder.bind(mScriptList.getFile(position - positionOfCategoryFile - 1), position);
|
||||
bindableViewHolder.bind(mExplorerItemList.getItem(position - positionOfCategoryFile - 1), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -360,27 +378,26 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
|
||||
return VIEW_TYPE_CATEGORY;
|
||||
} else if (position < positionOfCategoryFile) {
|
||||
return VIEW_TYPE_DIRECTORY;
|
||||
return VIEW_TYPE_PAGE;
|
||||
} else {
|
||||
return VIEW_TYPE_FILE;
|
||||
return VIEW_TYPE_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int count = 0;
|
||||
if (!mDirsCollapsed) {
|
||||
count += mScriptList.directoryCount();
|
||||
if (!mCurrentPageState.dirsCollapsed) {
|
||||
count += mExplorerItemList.groupCount();
|
||||
}
|
||||
if (!mFilesCollapsed) {
|
||||
count += mScriptList.fileCount();
|
||||
if (!mCurrentPageState.filesCollapsed) {
|
||||
count += mExplorerItemList.itemCount();
|
||||
}
|
||||
return count + 2;
|
||||
}
|
||||
}
|
||||
|
||||
protected class ScriptFileViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
|
||||
protected class ExplorerItemViewHolder extends BindableViewHolder<ExplorerItem> {
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
@@ -392,92 +409,95 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
View mOptions;
|
||||
@BindView(R.id.edit)
|
||||
View mEdit;
|
||||
GradientDrawable mFirstCharBackground;
|
||||
private ScriptFile mScriptFile;
|
||||
@BindView(R.id.run)
|
||||
View mRun;
|
||||
|
||||
ScriptFileViewHolder(View itemView) {
|
||||
GradientDrawable mFirstCharBackground;
|
||||
private ExplorerItem mExplorerItem;
|
||||
|
||||
ExplorerItemViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile file, int position) {
|
||||
mScriptFile = file;
|
||||
mName.setText(file.getSimplifiedName());
|
||||
mDesc.setText(PFiles.getHumanReadableSize(file.length()));
|
||||
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
|
||||
mFirstChar.setText("J");
|
||||
mFirstCharBackground.setColor(ResourcesCompat.getColor(getResources(), R.color.color_j, getContext().getTheme()));
|
||||
mEdit.setVisibility(VISIBLE);
|
||||
} else {
|
||||
mFirstChar.setText("R");
|
||||
mFirstCharBackground.setColor(ResourcesCompat.getColor(getResources(), R.color.color_r, getContext().getTheme()));
|
||||
mEdit.setVisibility(GONE);
|
||||
}
|
||||
public void bind(ExplorerItem item, int position) {
|
||||
mExplorerItem = item;
|
||||
mName.setText(ExplorerViewHelper.getDisplayName(item));
|
||||
mDesc.setText(PFiles.getHumanReadableSize(item.getSize()));
|
||||
mFirstChar.setText(ExplorerViewHelper.getIconText(item));
|
||||
mFirstCharBackground.setColor(ExplorerViewHelper.getIconColor(item));
|
||||
mEdit.setVisibility(item.isEditable() ? VISIBLE : GONE);
|
||||
mRun.setVisibility(item.isExecutable() ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
@OnClick(R.id.item)
|
||||
void onItemClick() {
|
||||
if (mOnScriptFileClickListener != null) {
|
||||
mOnScriptFileClickListener.onScriptFileClick(itemView, mScriptFile);
|
||||
if (mOnItemClickListener != null) {
|
||||
mOnItemClickListener.onItemClick(itemView, mExplorerItem);
|
||||
}
|
||||
notifyOperated();
|
||||
}
|
||||
|
||||
@OnClick(R.id.run)
|
||||
void run() {
|
||||
Scripts.run(mScriptFile);
|
||||
Scripts.run(new ScriptFile(mExplorerItem.getPath()));
|
||||
notifyOperated();
|
||||
}
|
||||
|
||||
@OnClick(R.id.edit)
|
||||
void edit() {
|
||||
Scripts.edit(mScriptFile);
|
||||
Scripts.edit(new ScriptFile(mExplorerItem.getPath()));
|
||||
notifyOperated();
|
||||
}
|
||||
|
||||
@OnClick(R.id.more)
|
||||
void showOptionMenu() {
|
||||
mSelectedScriptFile = mScriptFile;
|
||||
mSelectedItem = mExplorerItem;
|
||||
PopupMenu popupMenu = new PopupMenu(getContext(), mOptions);
|
||||
popupMenu.inflate(R.menu.menu_script_options);
|
||||
popupMenu.setOnMenuItemClickListener(ScriptListView.this);
|
||||
popupMenu.setOnMenuItemClickListener(ExplorerView.this);
|
||||
popupMenu.show();
|
||||
}
|
||||
}
|
||||
|
||||
protected class DirectoryViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
protected class ExplorerPageViewHolder extends BindableViewHolder<ExplorerPage> {
|
||||
|
||||
@BindView(R.id.name)
|
||||
public TextView mName;
|
||||
|
||||
@BindView(R.id.more)
|
||||
public View mOptions;
|
||||
|
||||
private ScriptFile mScriptFile;
|
||||
@BindView(R.id.icon)
|
||||
public ImageView mIcon;
|
||||
|
||||
DirectoryViewHolder(View itemView) {
|
||||
private ExplorerPage mExplorerPage;
|
||||
|
||||
ExplorerPageViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile data, int position) {
|
||||
mName.setText(data.getSimplifiedName());
|
||||
mScriptFile = data;
|
||||
public void bind(ExplorerPage data, int position) {
|
||||
mName.setText(ExplorerViewHelper.getDisplayName(data));
|
||||
mIcon.setImageResource(ExplorerViewHelper.getIcon(data));
|
||||
mExplorerPage = data;
|
||||
}
|
||||
|
||||
@OnClick(R.id.item)
|
||||
void onItemClick() {
|
||||
setCurrentDirectory(mScriptFile);
|
||||
enterChildPage(mExplorerPage);
|
||||
}
|
||||
|
||||
@OnClick(R.id.more)
|
||||
void showOptionMenu() {
|
||||
mSelectedScriptFile = mScriptFile;
|
||||
mSelectedItem = mExplorerPage;
|
||||
PopupMenu popupMenu = new PopupMenu(getContext(), mOptions);
|
||||
popupMenu.inflate(R.menu.menu_dir_options);
|
||||
popupMenu.setOnMenuItemClickListener(ScriptListView.this);
|
||||
popupMenu.setOnMenuItemClickListener(ExplorerView.this);
|
||||
popupMenu.show();
|
||||
}
|
||||
}
|
||||
@@ -516,12 +536,12 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
mGoBack.setVisibility(GONE);
|
||||
}
|
||||
if (isDirCategory) {
|
||||
mArrow.setRotation(mDirsCollapsed ? -90 : 0);
|
||||
mSortOrder.setImageResource(mScriptList.isDirSortedAscending() ?
|
||||
mArrow.setRotation(mCurrentPageState.dirsCollapsed ? -90 : 0);
|
||||
mSortOrder.setImageResource(mExplorerItemList.isDirSortedAscending() ?
|
||||
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
|
||||
} else {
|
||||
mArrow.setRotation(mFilesCollapsed ? -90 : 0);
|
||||
mSortOrder.setImageResource(mScriptList.isFileSortedAscending() ?
|
||||
mArrow.setRotation(mCurrentPageState.filesCollapsed ? -90 : 0);
|
||||
mSortOrder.setImageResource(mExplorerItemList.isFileSortedAscending() ?
|
||||
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
|
||||
}
|
||||
}
|
||||
@@ -529,15 +549,15 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
@OnClick(R.id.order)
|
||||
void changeSortOrder() {
|
||||
if (mIsDir) {
|
||||
mSortOrder.setImageResource(mScriptList.isDirSortedAscending() ?
|
||||
mSortOrder.setImageResource(mExplorerItemList.isDirSortedAscending() ?
|
||||
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
|
||||
mScriptList.setDirSortedAscending(!mScriptList.isDirSortedAscending());
|
||||
sort(mScriptList.getDirSortType(), mIsDir);
|
||||
mExplorerItemList.setDirSortedAscending(!mExplorerItemList.isDirSortedAscending());
|
||||
sort(mExplorerItemList.getDirSortType(), mIsDir);
|
||||
} else {
|
||||
mSortOrder.setImageResource(mScriptList.isFileSortedAscending() ?
|
||||
mSortOrder.setImageResource(mExplorerItemList.isFileSortedAscending() ?
|
||||
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
|
||||
mScriptList.setFileSortedAscending(!mScriptList.isFileSortedAscending());
|
||||
sort(mScriptList.getFileSortType(), mIsDir);
|
||||
mExplorerItemList.setFileSortedAscending(!mExplorerItemList.isFileSortedAscending());
|
||||
sort(mExplorerItemList.getFileSortType(), mIsDir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,7 +565,7 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
void showSortOptions() {
|
||||
PopupMenu popupMenu = new PopupMenu(getContext(), mSort);
|
||||
popupMenu.inflate(R.menu.menu_sort_options);
|
||||
popupMenu.setOnMenuItemClickListener(ScriptListView.this);
|
||||
popupMenu.setOnMenuItemClickListener(ExplorerView.this);
|
||||
mDirSortMenuShowing = mIsDir;
|
||||
popupMenu.show();
|
||||
|
||||
@@ -561,11 +581,27 @@ public class ScriptListView extends ThemeColorSwipeRefreshLayout implements Swip
|
||||
@OnClick(R.id.title_container)
|
||||
void collapseOrExpand() {
|
||||
if (mIsDir) {
|
||||
mDirsCollapsed = !mDirsCollapsed;
|
||||
mCurrentPageState.dirsCollapsed = !mCurrentPageState.dirsCollapsed;
|
||||
} else {
|
||||
mFilesCollapsed = !mFilesCollapsed;
|
||||
mCurrentPageState.filesCollapsed = !mCurrentPageState.filesCollapsed;
|
||||
}
|
||||
mScriptListAdapter.notifyDataSetChanged();
|
||||
mExplorerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ExplorerPageState {
|
||||
|
||||
ExplorerPage page;
|
||||
|
||||
boolean dirsCollapsed;
|
||||
|
||||
boolean filesCollapsed;
|
||||
|
||||
ExplorerPageState() {
|
||||
}
|
||||
|
||||
ExplorerPageState(ExplorerPage page) {
|
||||
this.page = page;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,22 @@ import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
|
||||
import com.stardust.autojs.script.AutoFileSource;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.tool.SimpleObserver;
|
||||
import org.autojs.autojs.ui.common.ScriptOperations;
|
||||
import org.autojs.autojs.ui.main.FloatingActionMenu;
|
||||
import org.autojs.autojs.ui.main.QueryEvent;
|
||||
import org.autojs.autojs.ui.main.ViewPagerFragment;
|
||||
import org.autojs.autojs.ui.viewmodel.ScriptList;
|
||||
import com.stardust.util.BackPressedHandler;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.EFragment;
|
||||
import org.androidannotations.annotations.ViewById;
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.explorer.ExplorerDirPage;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.tool.SimpleObserver;
|
||||
import org.autojs.autojs.ui.common.ScriptOperations;
|
||||
import org.autojs.autojs.ui.main.FloatingActionMenu;
|
||||
import org.autojs.autojs.ui.main.QueryEvent;
|
||||
import org.autojs.autojs.ui.main.ViewPagerFragment;
|
||||
import org.autojs.autojs.ui.viewmodel.ExplorerItemList;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
@@ -40,7 +40,7 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
|
||||
}
|
||||
|
||||
@ViewById(R.id.script_file_list)
|
||||
ScriptListView mScriptFileList;
|
||||
ExplorerView mExplorerView;
|
||||
|
||||
private FloatingActionMenu mFloatingActionMenu;
|
||||
|
||||
@@ -52,12 +52,12 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
|
||||
|
||||
@AfterViews
|
||||
void setUpViews() {
|
||||
ScriptList.SortConfig sortConfig = ScriptList.SortConfig.from(PreferenceManager.getDefaultSharedPreferences(getContext()));
|
||||
mScriptFileList.setSortConfig(sortConfig);
|
||||
mScriptFileList.setStorageFileProvider(StorageFileProvider.getDefault());
|
||||
mScriptFileList.setOnScriptFileClickListener((view, file) -> {
|
||||
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
|
||||
Scripts.edit(file);
|
||||
ExplorerItemList.SortConfig sortConfig = ExplorerItemList.SortConfig.from(PreferenceManager.getDefaultSharedPreferences(getContext()));
|
||||
mExplorerView.setSortConfig(sortConfig);
|
||||
mExplorerView.setExplorer(Explorers.workspace(), ExplorerDirPage.createRoot(Pref.getScriptDirPath()));
|
||||
mExplorerView.setOnItemClickListener((view, item) -> {
|
||||
if (item.isEditable()) {
|
||||
Scripts.edit(item.toScriptFile());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -113,8 +113,8 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
|
||||
mFloatingActionMenu.collapse();
|
||||
return true;
|
||||
}
|
||||
if (mScriptFileList.canGoBack()) {
|
||||
mScriptFileList.goBack();
|
||||
if (mExplorerView.canGoBack()) {
|
||||
mExplorerView.goBack();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -134,17 +134,17 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
|
||||
return;
|
||||
}
|
||||
if (event == QueryEvent.CLEAR) {
|
||||
mScriptFileList.setFilter(null);
|
||||
mExplorerView.setFilter(null);
|
||||
return;
|
||||
}
|
||||
String query = event.getQuery();
|
||||
mScriptFileList.setFilter((file -> file.getSimplifiedName().contains(query)));
|
||||
mExplorerView.setFilter((item -> item.getName().contains(query)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mScriptFileList.getSortConfig().saveInto(PreferenceManager.getDefaultSharedPreferences(getContext()));
|
||||
mExplorerView.getSortConfig().saveInto(PreferenceManager.getDefaultSharedPreferences(getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -163,19 +163,19 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
|
||||
|
||||
@Override
|
||||
public void onClick(FloatingActionButton button, int pos) {
|
||||
if (mScriptFileList == null)
|
||||
if (mExplorerView == null)
|
||||
return;
|
||||
switch (pos) {
|
||||
case 0:
|
||||
new ScriptOperations(getContext(), mScriptFileList, mScriptFileList.getCurrentDirectory())
|
||||
new ScriptOperations(getContext(), mExplorerView, mExplorerView.getCurrentPage())
|
||||
.newDirectory();
|
||||
break;
|
||||
case 1:
|
||||
new ScriptOperations(getContext(), mScriptFileList, mScriptFileList.getCurrentDirectory())
|
||||
new ScriptOperations(getContext(), mExplorerView, mExplorerView.getCurrentPage())
|
||||
.newScriptFile();
|
||||
break;
|
||||
case 2:
|
||||
new ScriptOperations(getContext(), mScriptFileList, mScriptFileList.getCurrentDirectory())
|
||||
new ScriptOperations(getContext(), mExplorerView, mExplorerView.getCurrentPage())
|
||||
.importFile();
|
||||
break;
|
||||
|
||||
|
||||
@@ -13,9 +13,10 @@ import android.widget.Toast;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.afollestad.materialdialogs.prefs.MaterialEditTextPreference;
|
||||
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.storage.file.FileObservable;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import org.autojs.autojs.tool.SimpleObserver;
|
||||
|
||||
@@ -55,18 +56,18 @@ public class ScriptDirPathPreference extends MaterialEditTextPreference {
|
||||
|
||||
@Override
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
String oldPath = StorageFileProvider.getDefaultDirectoryPath();
|
||||
String oldPath = Pref.getScriptDirPath();
|
||||
super.onDialogClosed(positiveResult);
|
||||
if (!positiveResult) {
|
||||
return;
|
||||
}
|
||||
String newPath = StorageFileProvider.getDefaultDirectoryPath();
|
||||
String newPath = Pref.getScriptDirPath();
|
||||
if (TextUtils.equals(oldPath, newPath)) {
|
||||
return;
|
||||
}
|
||||
int id = mRadioGroup.getCheckedRadioButtonId();
|
||||
if (id == R.id.none) {
|
||||
StorageFileProvider.getDefault().refreshAll();
|
||||
Explorers.workspace().refreshAll();
|
||||
return;
|
||||
}
|
||||
Observable<File> fileObservable;
|
||||
@@ -99,7 +100,7 @@ public class ScriptDirPathPreference extends MaterialEditTextPreference {
|
||||
public void onError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
dialog.dismiss();
|
||||
StorageFileProvider.getDefault().refreshAll();
|
||||
Explorers.workspace().refreshAll();
|
||||
Toast.makeText(getContext(), getContext().getString(R.string.text_error_copy_file,
|
||||
e.getMessage()), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
@@ -107,7 +108,7 @@ public class ScriptDirPathPreference extends MaterialEditTextPreference {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
dialog.dismiss();
|
||||
StorageFileProvider.getDefault().refreshAll();
|
||||
Explorers.workspace().refreshAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,13 +18,15 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.util.IntentUtil;
|
||||
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.network.download.DownloadManager;
|
||||
import org.autojs.autojs.network.entity.VersionInfo;
|
||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||
import org.autojs.autojs.tool.IntentTool;
|
||||
import org.autojs.autojs.ui.widget.CommonMarkdownView;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
||||
/**
|
||||
@@ -113,7 +115,7 @@ public class UpdateInfoDialogBuilder extends MaterialDialog.Builder {
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void directlyDownload(String downloadUrl) {
|
||||
final String path = StorageFileProvider.getDefaultDirectoryPath() + "AutoJs.apk";
|
||||
final String path = new File(Pref.getScriptDirPath(), "AutoJs.apk").getPath();
|
||||
DownloadManager.getInstance().downloadWithProgress(getContext(), downloadUrl, path)
|
||||
.subscribeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(file -> IntentUtil.installApk(getContext(), file.getPath()),
|
||||
|
||||
@@ -2,11 +2,10 @@ package org.autojs.autojs.ui.viewmodel;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.ui.main.scripts.ScriptListView;
|
||||
import com.stardust.util.FileSorter;
|
||||
import org.autojs.autojs.model.explorer.ExplorerItem;
|
||||
import org.autojs.autojs.model.explorer.ExplorerPage;
|
||||
import org.autojs.autojs.model.explorer.ExplorerSorter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
|
||||
@@ -14,7 +13,7 @@ import java.util.Comparator;
|
||||
* Created by Stardust on 2017/9/30.
|
||||
*/
|
||||
|
||||
public class ScriptList {
|
||||
public class ExplorerItemList {
|
||||
|
||||
public static class SortConfig {
|
||||
|
||||
@@ -83,8 +82,8 @@ public class ScriptList {
|
||||
public static final int SORT_TYPE_DATE = 0x40;
|
||||
|
||||
private SortConfig mSortConfig = new SortConfig();
|
||||
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
|
||||
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
|
||||
private ArrayList<ExplorerItem> mItems = new ArrayList<>();
|
||||
private ArrayList<ExplorerPage> mItemGroups = new ArrayList<>();
|
||||
|
||||
|
||||
public boolean isDirSortedAscending() {
|
||||
@@ -111,66 +110,66 @@ public class ScriptList {
|
||||
mSortConfig.mFileSortedAscending = fileSortedAscending;
|
||||
}
|
||||
|
||||
private Comparator<File> getComparator(int sortType) {
|
||||
private Comparator<ExplorerItem> getComparator(int sortType) {
|
||||
switch (sortType) {
|
||||
case SORT_TYPE_NAME:
|
||||
return FileSorter.NAME;
|
||||
return ExplorerSorter.NAME;
|
||||
case SORT_TYPE_DATE:
|
||||
return FileSorter.DATE;
|
||||
return ExplorerSorter.DATE;
|
||||
case SORT_TYPE_SIZE:
|
||||
return FileSorter.SIZE;
|
||||
return ExplorerSorter.SIZE;
|
||||
case SORT_TYPE_TYPE:
|
||||
return FileSorter.TYPE;
|
||||
return ExplorerSorter.TYPE;
|
||||
}
|
||||
throw new IllegalArgumentException("unknown type " + sortType);
|
||||
}
|
||||
|
||||
public int directoryCount() {
|
||||
return mDirectories.size();
|
||||
public int groupCount() {
|
||||
return mItemGroups.size();
|
||||
}
|
||||
|
||||
public int fileCount() {
|
||||
return mScriptFiles.size();
|
||||
public int itemCount() {
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mScriptFiles.clear();
|
||||
mDirectories.clear();
|
||||
mItems.clear();
|
||||
mItemGroups.clear();
|
||||
}
|
||||
|
||||
public void add(ScriptFile file) {
|
||||
if (file.isDirectory()) {
|
||||
mDirectories.add(file);
|
||||
public void add(ExplorerItem item) {
|
||||
if (item instanceof ExplorerPage) {
|
||||
mItemGroups.add((ExplorerPage) item);
|
||||
} else {
|
||||
mScriptFiles.add(file);
|
||||
mItems.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptFile getDir(int i) {
|
||||
return mDirectories.get(i);
|
||||
public ExplorerPage getItemGroup(int i) {
|
||||
return mItemGroups.get(i);
|
||||
}
|
||||
|
||||
public ScriptFile getFile(int i) {
|
||||
return mScriptFiles.get(i);
|
||||
public ExplorerItem getItem(int i) {
|
||||
return mItems.get(i);
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return mScriptFiles.size() + mDirectories.size();
|
||||
return mItems.size() + mItemGroups.size();
|
||||
}
|
||||
|
||||
public void sortDir(int sortType) {
|
||||
public void sortItemGroup(int sortType) {
|
||||
mSortConfig.mDirSortType = sortType;
|
||||
FileSorter.sort(mDirectories, getComparator(sortType), mSortConfig.mDirSortedAscending);
|
||||
ExplorerSorter.sort(mItemGroups, getComparator(sortType), mSortConfig.mDirSortedAscending);
|
||||
}
|
||||
|
||||
public void sortFile(int sortType) {
|
||||
mSortConfig.mFileSortType = sortType;
|
||||
FileSorter.sort(mScriptFiles, getComparator(sortType), mSortConfig.mFileSortedAscending);
|
||||
ExplorerSorter.sort(mItems, getComparator(sortType), mSortConfig.mFileSortedAscending);
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
FileSorter.sort(mDirectories, getComparator(mSortConfig.mDirSortType), mSortConfig.mDirSortedAscending);
|
||||
FileSorter.sort(mScriptFiles, getComparator(mSortConfig.mFileSortType), mSortConfig.mFileSortedAscending);
|
||||
ExplorerSorter.sort(mItemGroups, getComparator(mSortConfig.mDirSortType), mSortConfig.mDirSortedAscending);
|
||||
ExplorerSorter.sort(mItems, getComparator(mSortConfig.mFileSortType), mSortConfig.mFileSortedAscending);
|
||||
}
|
||||
|
||||
public SortConfig getSortConfig() {
|
||||
@@ -181,8 +180,8 @@ public class ScriptList {
|
||||
mSortConfig = sortConfig;
|
||||
}
|
||||
|
||||
public ScriptList cloneConfig() {
|
||||
ScriptList list = new ScriptList();
|
||||
public ExplorerItemList cloneConfig() {
|
||||
ExplorerItemList list = new ExplorerItemList();
|
||||
list.mSortConfig = mSortConfig;
|
||||
return list;
|
||||
}
|
||||
BIN
app/src/main/res/drawable-xhdpi/ic_sample_dir.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_sample_dir.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
@@ -24,7 +24,7 @@
|
||||
</com.stardust.theme.widget.ThemeColorToolbar>
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<org.autojs.autojs.ui.main.scripts.ScriptListView
|
||||
<org.autojs.autojs.ui.main.scripts.ExplorerView
|
||||
android:id="@+id/script_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<org.autojs.autojs.ui.main.scripts.ScriptListView
|
||||
<org.autojs.autojs.ui.main.scripts.ExplorerView
|
||||
android:id="@+id/script_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<org.autojs.autojs.ui.main.sample.SampleListView
|
||||
android:id="@+id/sample_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
@@ -4,7 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<org.autojs.autojs.ui.main.scripts.ScriptListView
|
||||
<org.autojs.autojs.ui.main.scripts.ExplorerView
|
||||
android:id="@+id/script_file_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
@@ -21,13 +21,12 @@
|
||||
android:paddingTop="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:src="@drawable/ic_folder_yellow_100px"
|
||||
android:tint="#ffda93"/>
|
||||
android:layout_marginRight="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
<string name="text_registering">注册中</string>
|
||||
<string name="text_register_fail">注册失败</string>
|
||||
<string name="text_register_succeed">注册成功</string>
|
||||
<string name="text_sample">示例</string>
|
||||
<string name="text_sample">示例代码</string>
|
||||
<string name="text_copy_to_my_script">导入到我的脚本</string>
|
||||
<string name="text_reset_to_initial_content">重置为初始内容</string>
|
||||
<string name="text_reset_fail">重置失败</string>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module.exports = function(__runtime__, scope){
|
||||
function RootAutomator(nonBlockingForReady){
|
||||
this.__ra__ = Object.create(new com.stardust.autojs.core.inputevent.RootAutomator(scope.context, !nonBlockingForReady));
|
||||
function RootAutomator(inputDevice, nonBlockingForReady){
|
||||
inputDevice = inputDevice == undefined ? null : inputDevice;
|
||||
this.__ra__ = Object.create(new com.stardust.autojs.core.inputevent.RootAutomator(scope.context, inputDevice, !nonBlockingForReady));
|
||||
var methods = ["sendEvent", "touch", "setScreenMetrics", "touchX", "touchY", "sendSync", "sendMtSync", "tap",
|
||||
"swipe", "press", "longPress", "touchDown", "touchUp", "touchMove", "getDefaultId", "setDefaultId", "exit"];
|
||||
for(var i = 0; i < methods.length; i++){
|
||||
|
||||
@@ -9,6 +9,10 @@ package com.stardust.autojs.core.inputevent;
|
||||
|
||||
public class InputEventCodes {
|
||||
|
||||
|
||||
public static final int UP = 0x00;
|
||||
public static final int DOWN = 0x01;
|
||||
|
||||
|
||||
/*
|
||||
* Device properties and quirks
|
||||
|
||||
@@ -41,9 +41,15 @@ public class RootAutomator implements Shell.Callback {
|
||||
private final Object mReadyLock = new Object();
|
||||
private volatile boolean mReady = false;
|
||||
private final Context mContext;
|
||||
private String mInputDevice;
|
||||
|
||||
public RootAutomator(Context context, boolean waitForReady) throws IOException {
|
||||
public RootAutomator(Context context, String inputDevice, boolean waitForReady) throws IOException {
|
||||
mContext = context;
|
||||
if (inputDevice == null) {
|
||||
mInputDevice = RootAutomatorEngine.getDeviceNameOrPath(mContext, InputDevices.getTouchDeviceName());
|
||||
} else {
|
||||
mInputDevice = inputDevice;
|
||||
}
|
||||
mShell = new Shell(true);
|
||||
mShell.setCallback(this);
|
||||
if (waitForReady) {
|
||||
@@ -180,19 +186,21 @@ public class RootAutomator implements Shell.Callback {
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_X, scaleX(x));
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_Y, scaleY(y));
|
||||
sendEvent(EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0x00000000);
|
||||
sendEvent(EV_ABS, ABS_MT_WIDTH_MAJOR, 5);
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
private void touchDown0(int x, int y, int id) throws IOException {
|
||||
mSlotIdMap.put(id, 0);
|
||||
sendEvent(EV_ABS, ABS_MT_TRACKING_ID, mTracingId.getAndIncrement());
|
||||
sendEvent(EV_KEY, BTN_TOUCH, 0x00000001);
|
||||
sendEvent(EV_KEY, BTN_TOOL_FINGER, 0x00000001);
|
||||
sendEvent(EV_KEY, BTN_TOUCH, DOWN);
|
||||
//sendEvent(EV_KEY, BTN_TOOL_FINGER, 0x00000001);
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_X, scaleX(x));
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_Y, scaleY(y));
|
||||
//sendEvent(EV_ABS, ABS_MT_PRESSURE, 200);
|
||||
sendEvent(EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0x00000000);
|
||||
sendEvent(EV_ABS, ABS_MT_WIDTH_MAJOR, 5);
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
public void touchDown(int x, int y) throws IOException {
|
||||
@@ -211,8 +219,8 @@ public class RootAutomator implements Shell.Callback {
|
||||
sendEvent(EV_ABS, ABS_MT_SLOT, slotId);
|
||||
sendEvent(EV_ABS, ABS_MT_TRACKING_ID, 0xffffffff);
|
||||
if (mSlotIdMap.size() == 0) {
|
||||
sendEvent(EV_KEY, BTN_TOUCH, 0x00000000);
|
||||
sendEvent(EV_KEY, BTN_TOOL_FINGER, 0x00000000);
|
||||
sendEvent(EV_KEY, BTN_TOUCH, UP);
|
||||
//sendEvent(EV_KEY, BTN_TOOL_FINGER, 0x00000000);
|
||||
}
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0x00000000);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
||||
private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator";
|
||||
|
||||
private Context mContext;
|
||||
private String mDeviceNameOrPath;
|
||||
private final String mDeviceNameOrPath;
|
||||
private Thread mThread;
|
||||
private String mExecutablePath;
|
||||
private String mPid;
|
||||
|
||||
@@ -1 +1 @@
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":415},"path":"commonRelease-4.0.2 Alpha10.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":416},"path":"commonRelease-4.0.2 Alpha11.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
|
||||
Reference in New Issue
Block a user