add: uploaded script options
This commit is contained in:
@@ -126,6 +126,10 @@ dependencies {
|
||||
// RxJava
|
||||
compile "io.reactivex.rxjava2:rxjava:2.1.0"
|
||||
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
|
||||
// RxDownload
|
||||
compile('zlc.season:rxdownload3:1.0.8', {
|
||||
exclude group: 'com.android.support'
|
||||
})
|
||||
// Retrofit
|
||||
compile 'com.squareup.retrofit2:retrofit:2.3.0'
|
||||
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
|
||||
|
||||
@@ -7,12 +7,11 @@ import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.external.CommonUtils;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.main.scripts.ScriptListView;
|
||||
import com.twofortyfouram.locale.sdk.client.ui.activity.AbstractAppCompatPluginActivity;
|
||||
@@ -45,7 +44,7 @@ public class TaskPrefEditActivity extends AbstractAppCompatPluginActivity {
|
||||
mStorageFileProvider = StorageFileProvider.getExternalStorageProvider();
|
||||
ScriptListView scriptList = (ScriptListView) findViewById(R.id.script_list);
|
||||
scriptList.setStorageFileProvider(mStorageFileProvider);
|
||||
scriptList.setCurrentDirectory(StorageFileProvider.DEFAULT_DIRECTORY);
|
||||
scriptList.setCurrentDirectory(new ScriptFile(StorageFileProvider.DEFAULT_DIRECTORY));
|
||||
scriptList.setOnScriptFileClickListener((view, file) -> {
|
||||
mSelectedScriptFilePath = file.getPath();
|
||||
finish();
|
||||
|
||||
@@ -6,11 +6,10 @@ import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.main.scripts.ScriptListView;
|
||||
|
||||
@@ -45,7 +44,7 @@ public class ScriptWidgetSettingsActivity extends BaseActivity {
|
||||
mStorageFileProvider = StorageFileProvider.getExternalStorageProvider();
|
||||
ScriptListView scriptList = (ScriptListView) findViewById(R.id.script_list);
|
||||
scriptList.setStorageFileProvider(mStorageFileProvider);
|
||||
scriptList.setCurrentDirectory(StorageFileProvider.DEFAULT_DIRECTORY);
|
||||
scriptList.setCurrentDirectory(new ScriptFile(StorageFileProvider.DEFAULT_DIRECTORY));
|
||||
scriptList.setOnScriptFileClickListener((view, file) -> {
|
||||
mSelectedScriptFilePath = file.getPath();
|
||||
finish();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.stardust.scriptdroid.model.script;
|
||||
package com.stardust.scriptdroid.io;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class StorageFileProvider {
|
||||
public static final int CHANGE = 2;
|
||||
public static final int ALL = 3;
|
||||
public static final String DEFAULT_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + App.getApp().getString(R.string.folder_name);
|
||||
public static final ScriptFile DEFAULT_DIRECTORY = new ScriptFile(DEFAULT_DIRECTORY_PATH);
|
||||
public static final PFile DEFAULT_DIRECTORY = new PFile(DEFAULT_DIRECTORY_PATH);
|
||||
|
||||
public static class DirectoryChangeEvent {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.stardust.scriptdroid.io;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/21.
|
||||
*/
|
||||
|
||||
public class TmpScriptFiles {
|
||||
|
||||
|
||||
public static File create(Context context) throws IOException {
|
||||
ensureTmpDir(context);
|
||||
File tmp = new File(getTmpDir(context), "tmp-" + System.currentTimeMillis() + ".js");
|
||||
tmp.createNewFile();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public static void clearTmpDir(Context context) {
|
||||
File dir = getTmpDir(context);
|
||||
PFiles.deleteRecursively(dir);
|
||||
}
|
||||
|
||||
public static File getTmpDir(Context context) {
|
||||
return new File(context.getCacheDir(), "tmp_scripts/");
|
||||
}
|
||||
|
||||
private static void ensureTmpDir(Context context) {
|
||||
File dir = getTmpDir(context);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,37 +59,6 @@ public class ScriptFile extends PFile {
|
||||
return new ScriptFile(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptFile[] listFiles() {
|
||||
return listFiles(file -> (file.getName().endsWith(".js") || file.getName().endsWith(".auto") ||
|
||||
file.isDirectory()) && !file.getName().startsWith("."));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptFile[] listFiles(FilenameFilter filter) {
|
||||
String ss[] = list();
|
||||
if (ss == null) return null;
|
||||
ArrayList<ScriptFile> files = new ArrayList<>();
|
||||
for (String s : ss)
|
||||
if ((filter == null) || filter.accept(this, s))
|
||||
files.add(new ScriptFile(this, s));
|
||||
return files.toArray(new ScriptFile[files.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptFile[] listFiles(FileFilter filter) {
|
||||
String ss[] = list();
|
||||
if (ss == null) return null;
|
||||
ArrayList<ScriptFile> files = new ArrayList<>();
|
||||
for (String s : ss) {
|
||||
ScriptFile f = new ScriptFile(this, s);
|
||||
if ((filter == null) || filter.accept(f))
|
||||
files.add(f);
|
||||
}
|
||||
return files.toArray(new ScriptFile[files.size()]);
|
||||
|
||||
}
|
||||
|
||||
public ScriptSource toSource() {
|
||||
if (getType() == TYPE_JAVA_SCRIPT) {
|
||||
return new JavaScriptFileSource(this);
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.external.CommonUtils;
|
||||
import com.stardust.scriptdroid.external.shortcut.Shortcut;
|
||||
import com.stardust.scriptdroid.external.shortcut.ShortcutActivity;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.model.sample.Sample;
|
||||
import com.stardust.scriptdroid.ui.edit.EditActivity;
|
||||
import com.stardust.util.AssetsCache;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.stardust.scriptdroid.network.download;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/20.
|
||||
*/
|
||||
|
||||
public class DownloadFailedException extends Throwable {
|
||||
private final String mUrl;
|
||||
private final String mPath;
|
||||
|
||||
public DownloadFailedException(String url, String path) {
|
||||
mUrl = url;
|
||||
mPath = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DownloadFailedException{" +
|
||||
"url='" + mUrl + '\'' +
|
||||
", path='" + mPath + '\'' +
|
||||
"} " + super.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package com.stardust.scriptdroid.network.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
import zlc.season.rxdownload3.RxDownload;
|
||||
import zlc.season.rxdownload3.core.Failed;
|
||||
import zlc.season.rxdownload3.core.Mission;
|
||||
import zlc.season.rxdownload3.core.Status;
|
||||
import zlc.season.rxdownload3.core.Succeed;
|
||||
|
||||
import static android.app.DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR;
|
||||
import static android.app.DownloadManager.COLUMN_STATUS;
|
||||
import static android.app.DownloadManager.COLUMN_TOTAL_SIZE_BYTES;
|
||||
import static android.app.DownloadManager.STATUS_FAILED;
|
||||
import static android.app.DownloadManager.STATUS_RUNNING;
|
||||
import static android.app.DownloadManager.STATUS_SUCCESSFUL;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/20.
|
||||
*/
|
||||
|
||||
public class DownloadManager {
|
||||
|
||||
private static DownloadManager sInstance;
|
||||
|
||||
private android.app.DownloadManager mManager;
|
||||
private Context mContext;
|
||||
private Handler mHandler;
|
||||
|
||||
|
||||
public DownloadManager(Context context) {
|
||||
mContext = context;
|
||||
mHandler = new Handler();
|
||||
mManager = (android.app.DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
}
|
||||
|
||||
public static DownloadManager getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new DownloadManager(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
|
||||
public static String parseFileNameLocally(String url) {
|
||||
int i = url.lastIndexOf('-');
|
||||
if (i < 0) {
|
||||
i = url.lastIndexOf('/');
|
||||
}
|
||||
return url.substring(i + 1);
|
||||
}
|
||||
|
||||
public Observable<Integer> download(String url, String path) {
|
||||
File file = new File(path);
|
||||
Mission mission = new Mission(url, file.getName(), file.getParent());
|
||||
PublishSubject<Integer> progress = PublishSubject.create();
|
||||
RxDownload.INSTANCE.create(mission)
|
||||
.subscribe(status -> {
|
||||
int p = (int) Math.floor((float) status.getDownloadSize() / status.getTotalSize() * 100);
|
||||
progress.onNext(p);
|
||||
if (status instanceof Succeed) {
|
||||
progress.onComplete();
|
||||
RxDownload.INSTANCE.delete(mission);
|
||||
} else if (status instanceof Failed) {
|
||||
progress.onError(((Failed) status).getThrowable());
|
||||
}
|
||||
});
|
||||
RxDownload.INSTANCE.start(mission).subscribe();
|
||||
return progress;
|
||||
}
|
||||
|
||||
public Observable<Integer> download$(String url, String path) {
|
||||
android.app.DownloadManager.Request request = new android.app.DownloadManager.Request(Uri.parse(url));
|
||||
request.setDestinationUri(Uri.parse("file://" + path));
|
||||
long id = mManager.enqueue(request);
|
||||
PublishSubject<Integer> downloadProgress = PublishSubject.create();
|
||||
Disposable disposable = Observable.interval(0, 200, TimeUnit.MILLISECONDS)
|
||||
.subscribe(t -> {
|
||||
int progress = getDownloadProgress(id);
|
||||
if (progress < 0) {
|
||||
downloadProgress.onError(new DownloadFailedException(url, path));
|
||||
}
|
||||
downloadProgress.onNext(progress);
|
||||
if (progress == 100) {
|
||||
downloadProgress.onComplete();
|
||||
}
|
||||
});
|
||||
downloadProgress.doOnComplete(disposable::dispose);
|
||||
return downloadProgress;
|
||||
}
|
||||
|
||||
private int getDownloadProgress(long id) {
|
||||
Cursor cursor = mManager.query(new android.app.DownloadManager.Query()
|
||||
.setFilterById(id));
|
||||
if (!cursor.moveToFirst()) {
|
||||
return -1;
|
||||
}
|
||||
int total = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_TOTAL_SIZE_BYTES));
|
||||
int downloaded = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BYTES_DOWNLOADED_SO_FAR));
|
||||
int status = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_STATUS));
|
||||
if (status == STATUS_SUCCESSFUL) {
|
||||
return 100;
|
||||
} else if (status == STATUS_FAILED) {
|
||||
return -1;
|
||||
}
|
||||
return (int) Math.floor((float) downloaded / total * 100);
|
||||
}
|
||||
|
||||
public void cancelDownload(String url) {
|
||||
RxDownload.INSTANCE.stop(url);
|
||||
RxDownload.INSTANCE.delete(url);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.model.script.Scripts;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/11.
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.stardust.scriptdroid.ui.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/20.
|
||||
*/
|
||||
|
||||
public class OptionListView extends LinearLayout {
|
||||
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private OptionListView mOptionListView;
|
||||
private Context mContext;
|
||||
|
||||
public Builder(Context context) {
|
||||
mContext = context;
|
||||
mOptionListView = (OptionListView) View.inflate(context, R.layout.option_list_view, null);
|
||||
}
|
||||
|
||||
public Builder item(int id, int iconRes, int textRes) {
|
||||
return item(id, iconRes, mContext.getString(textRes));
|
||||
}
|
||||
|
||||
public Builder item(int id, int iconRes, String text) {
|
||||
mOptionListView.mIds.add(id);
|
||||
mOptionListView.mIcons.add(iconRes);
|
||||
mOptionListView.mTexts.add(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder bindItemClick(Object target) {
|
||||
mOptionListView.mOnItemClickTarget = target;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder title(String title) {
|
||||
mOptionListView.mTitleView.setVisibility(VISIBLE);
|
||||
mOptionListView.mTitleView.setText(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder title(int title) {
|
||||
return title(mContext.getString(title));
|
||||
}
|
||||
|
||||
public OptionListView build() {
|
||||
return mOptionListView;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ArrayList<Integer> mIds = new ArrayList<>();
|
||||
private ArrayList<Integer> mIcons = new ArrayList<>();
|
||||
private ArrayList<String> mTexts = new ArrayList<>();
|
||||
private Object mOnItemClickTarget;
|
||||
private RecyclerView mOptionList;
|
||||
private TextView mTitleView;
|
||||
|
||||
public OptionListView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public OptionListView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mTitleView = (TextView) findViewById(R.id.title);
|
||||
mOptionList = (RecyclerView) findViewById(R.id.list);
|
||||
mOptionList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
mOptionList.setAdapter(new Adapter());
|
||||
}
|
||||
|
||||
private class Adapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.operation_dialog_item, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
holder.itemView.setId(mIds.get(position));
|
||||
holder.text.setText(mTexts.get(position));
|
||||
holder.icon.setImageResource(mIcons.get(position));
|
||||
if (mOnItemClickTarget != null) {
|
||||
ButterKnife.bind(mOnItemClickTarget, holder.itemView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mIds.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@BindView(R.id.icon)
|
||||
ImageView icon;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ 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;
|
||||
@@ -18,10 +19,13 @@ import com.stardust.pio.PFiles;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.io.TmpScriptFiles;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.model.script.Scripts;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.model.sample.Sample;
|
||||
import com.stardust.scriptdroid.network.download.DownloadManager;
|
||||
import com.stardust.scriptdroid.ui.filechooser.FileChooserDialogBuilder;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
@@ -30,6 +34,7 @@ import org.reactivestreams.Subscriber;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
@@ -38,12 +43,14 @@ import io.reactivex.functions.Function;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/7/31.
|
||||
*/
|
||||
|
||||
public class ScriptOperations {
|
||||
|
||||
private static final String LOG_TAG = "ScriptOperations";
|
||||
private Context mContext;
|
||||
private View mView;
|
||||
private ScriptFile mCurrentDirectory;
|
||||
@@ -57,7 +64,7 @@ public class ScriptOperations {
|
||||
}
|
||||
|
||||
public ScriptOperations(Context context, View view) {
|
||||
this(context, view, StorageFileProvider.DEFAULT_DIRECTORY);
|
||||
this(context, view, new ScriptFile(StorageFileProvider.DEFAULT_DIRECTORY));
|
||||
}
|
||||
|
||||
public void newScriptFileForScript(final String script) {
|
||||
@@ -240,16 +247,61 @@ public class ScriptOperations {
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<Boolean>() {
|
||||
@Override
|
||||
public void accept(@io.reactivex.annotations.NonNull Boolean deleted) throws Exception {
|
||||
showMessage(deleted ? R.string.text_already_delete : R.string.text_delete_failed);
|
||||
if (deleted)
|
||||
mStorageFileProvider.notifyFileRemoved(mCurrentDirectory, scriptFile);
|
||||
}
|
||||
.subscribe(deleted -> {
|
||||
showMessage(deleted ? R.string.text_already_delete : R.string.text_delete_failed);
|
||||
if (deleted)
|
||||
mStorageFileProvider.notifyFileRemoved(mCurrentDirectory, scriptFile);
|
||||
});
|
||||
}
|
||||
|
||||
public Observable<ScriptFile> download(String url) {
|
||||
String fileName = DownloadManager.parseFileNameLocally(url);
|
||||
MaterialDialog progressDialog = createDownloadProgressDialog(url, fileName);
|
||||
return new FileChooserDialogBuilder(mContext)
|
||||
.title(R.string.text_select_save_path)
|
||||
.chooseDir()
|
||||
.singleChoice()
|
||||
.map(saveDir -> new File(saveDir, fileName).getPath())
|
||||
.flatMap(savePath -> download(url, savePath, progressDialog));
|
||||
}
|
||||
|
||||
private MaterialDialog createDownloadProgressDialog(String url, String fileName) {
|
||||
return new MaterialDialog.Builder(mContext)
|
||||
.progress(false, 100)
|
||||
.title(fileName)
|
||||
.cancelable(false)
|
||||
.positiveText(R.string.text_cancel_download)
|
||||
.onPositive((dialog, which) -> DownloadManager.getInstance(mContext).cancelDownload(url))
|
||||
.show();
|
||||
}
|
||||
|
||||
public Observable<ScriptFile> download(String url, String path, MaterialDialog progressDialog) {
|
||||
PublishSubject<ScriptFile> subject = PublishSubject.create();
|
||||
DownloadManager.getInstance(mContext).download(url, path)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext(progressDialog::setProgress)
|
||||
.doOnComplete(() -> {
|
||||
progressDialog.dismiss();
|
||||
subject.onNext(new ScriptFile(path));
|
||||
subject.onComplete();
|
||||
})
|
||||
.doOnError(error -> {
|
||||
Log.e(LOG_TAG, "Download failed", error);
|
||||
progressDialog.dismiss();
|
||||
showMessage(R.string.text_download_failed);
|
||||
subject.onError(error);
|
||||
})
|
||||
.subscribe();
|
||||
return subject;
|
||||
}
|
||||
|
||||
public Observable<ScriptFile> temporarilyDownload(String url) {
|
||||
String fileName = DownloadManager.parseFileNameLocally(url);
|
||||
return Observable.fromCallable(() -> TmpScriptFiles.create(mContext))
|
||||
.flatMap(tmpFile ->
|
||||
download(url, tmpFile.getPath(), createDownloadProgressDialog(url, fileName)));
|
||||
}
|
||||
|
||||
|
||||
private class InputCallback implements MaterialDialog.InputCallback {
|
||||
|
||||
|
||||
@@ -2,17 +2,21 @@ package com.stardust.scriptdroid.ui.filechooser;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/19.
|
||||
*/
|
||||
@@ -87,5 +91,25 @@ public class FileChooserDialogBuilder extends ThemeColorMaterialDialogBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Observable<PFile> singleChoice() {
|
||||
PublishSubject<PFile> result = PublishSubject.create();
|
||||
singleChoice(file -> {
|
||||
result.onNext(file);
|
||||
result.onComplete();
|
||||
});
|
||||
show();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileChooserDialogBuilder title(@NonNull CharSequence title) {
|
||||
super.title(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileChooserDialogBuilder title(@StringRes int titleRes) {
|
||||
super.title(titleRes);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
@@ -17,7 +16,6 @@ import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.qq.e.comm.DownloadService;
|
||||
import com.stardust.app.FragmentPagerAdapterBuilder;
|
||||
@@ -29,9 +27,9 @@ import com.stardust.scriptdroid.Pref;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.ui.common.NotAskAgainDialog;
|
||||
import com.stardust.scriptdroid.ui.filechooser.FileChooserDialogBuilder;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.ui.main.community.CommunityFragment_;
|
||||
import com.stardust.scriptdroid.ui.main.doc.OnlineDocsFragment_;
|
||||
import com.stardust.scriptdroid.ui.main.scripts.MyScriptListFragment_;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class CommunityFragment extends ViewPagerFragment implements BackPressedH
|
||||
private static final String POSTS_PAGE_PATTERN = "[\\S\\s]+/topic/[0-9]+/[\\S\\s]+";
|
||||
|
||||
@ViewById(R.id.eweb_view)
|
||||
EWebView mEWebView;
|
||||
CommunityWebView mEWebView;
|
||||
WebView mWebView;
|
||||
|
||||
public CommunityFragment() {
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.stardust.scriptdroid.ui.main.community;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.design.widget.BottomSheetDialog;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.util.AttributeSet;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.model.script.Scripts;
|
||||
import com.stardust.scriptdroid.network.download.DownloadManager;
|
||||
import com.stardust.scriptdroid.ui.common.OptionListView;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.widget.EWebView;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Optional;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/19.
|
||||
*/
|
||||
|
||||
public class CommunityWebView extends EWebView {
|
||||
|
||||
private String mUrl;
|
||||
private BottomSheetDialog mBottomSheetDialog;
|
||||
|
||||
public CommunityWebView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public CommunityWebView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
getWebView().setWebViewClient(new MyWebViewClient());
|
||||
}
|
||||
|
||||
private void shouldScriptOptionsDialog(String url) {
|
||||
mUrl = url;
|
||||
String fileName = DownloadManager.parseFileNameLocally(url);
|
||||
mBottomSheetDialog = new BottomSheetDialog(getContext());
|
||||
mBottomSheetDialog.setContentView(new OptionListView.Builder(getContext())
|
||||
.title(fileName)
|
||||
.item(R.id.save, R.drawable.ic_file_download_black_48dp, R.string.text_download)
|
||||
.item(R.id.run, R.drawable.ic_play_arrow_white_48dp, R.string.text_run)
|
||||
.item(R.id.edit, R.drawable.ic_edit_white_24dp, R.string.text_save_and_edit)
|
||||
.bindItemClick(this)
|
||||
.build());
|
||||
mBottomSheetDialog.show();
|
||||
}
|
||||
|
||||
@Optional
|
||||
@OnClick(R.id.save)
|
||||
void save() {
|
||||
dismissBottomSheetDialog();
|
||||
new ScriptOperations(getContext(), CommunityWebView.this)
|
||||
.download(mUrl)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(file ->
|
||||
Snackbar.make(CommunityWebView.this, getResources().getString(R.string.format_file_downloaded, file.getPath())
|
||||
, Snackbar.LENGTH_SHORT).show());
|
||||
}
|
||||
|
||||
@Optional
|
||||
@OnClick(R.id.edit)
|
||||
void saveAndEdit() {
|
||||
dismissBottomSheetDialog();
|
||||
new ScriptOperations(getContext(), CommunityWebView.this)
|
||||
.download(mUrl)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Scripts::edit);
|
||||
}
|
||||
|
||||
@Optional
|
||||
@OnClick(R.id.run)
|
||||
void run() {
|
||||
dismissBottomSheetDialog();
|
||||
new ScriptOperations(getContext(), CommunityWebView.this)
|
||||
.temporarilyDownload(mUrl)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(file -> {
|
||||
Snackbar.make(CommunityWebView.this, R.string.text_start_running, Snackbar.LENGTH_SHORT).show();
|
||||
Scripts.run(file);
|
||||
});
|
||||
}
|
||||
|
||||
private void dismissBottomSheetDialog() {
|
||||
mBottomSheetDialog.dismiss();
|
||||
mBottomSheetDialog = null;
|
||||
}
|
||||
|
||||
|
||||
private class MyWebViewClient extends EWebView.MyWebViewClient {
|
||||
|
||||
private final Pattern UPLOAD_FILE_PATTERN = Pattern.compile("http://www.autojs.org/assets/uploads/files/.+(\\.js|\\.auto)");
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
if (UPLOAD_FILE_PATTERN.matcher(url).matches()) {
|
||||
shouldScriptOptionsDialog(url);
|
||||
return true;
|
||||
}
|
||||
return super.shouldOverrideUrlLoading(view, url);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import android.view.View;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.model.script.Scripts;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.tool.SimpleObserver;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.main.FloatingActionMenu;
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.stardust.pio.PFiles;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.model.script.Scripts;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.viewmodel.ScriptList;
|
||||
@@ -181,7 +181,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
loadScriptList();
|
||||
mStorageFileProvider.notifyDirectoryChanged(mCurrentDirectory);
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
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 com.stardust.scriptdroid.model.script.ScriptFile
|
||||
bindableViewHolder.bind(position == positionOfCategoryDir, position);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.scriptdroid.BuildConfig;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.network.entity.VersionInfo;
|
||||
import com.stardust.scriptdroid.model.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.io.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.tool.IntentTool;
|
||||
import com.stardust.util.DownloadTask;
|
||||
import com.stardust.util.IntentUtil;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
|
||||
mWebView.reload();
|
||||
}
|
||||
|
||||
private class MyWebChromeClient extends WebChromeClient {
|
||||
protected class MyWebChromeClient extends WebChromeClient {
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(WebView view, int newProgress) {
|
||||
@@ -82,7 +82,7 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
|
||||
}
|
||||
}
|
||||
|
||||
private class MyWebViewClient extends WebViewClient {
|
||||
protected class MyWebViewClient extends WebViewClient {
|
||||
|
||||
@Override
|
||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_file_download_black_48dp.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_file_download_black_48dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 173 B |
BIN
app/src/main/res/drawable-mdpi/ic_file_download_black_48dp.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_file_download_black_48dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 144 B |
BIN
app/src/main/res/drawable-xhdpi/ic_file_download_black_48dp.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_file_download_black_48dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 209 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_file_download_black_48dp.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_file_download_black_48dp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 264 B |
Binary file not shown.
|
After Width: | Height: | Size: 305 B |
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.stardust.widget.EWebView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.stardust.scriptdroid.ui.main.community.CommunityWebView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/eweb_view"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
27
app/src/main/res/layout/option_list_view.xml
Normal file
27
app/src/main/res/layout/option_list_view.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.stardust.scriptdroid.ui.common.OptionListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:textColor="#77000000"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone"
|
||||
tools:text="标题"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</com.stardust.scriptdroid.ui.common.OptionListView>
|
||||
@@ -132,7 +132,7 @@
|
||||
<string name="text_download_url">下载地址</string>
|
||||
<string name="text_directly_download">直接下载</string>
|
||||
<string name="text_downloading">下载中</string>
|
||||
<string name="text_download_failed">下载失败~请到应用商店下载</string>
|
||||
<string name="text_download_failed">下载失败</string>
|
||||
<string name="text_do_not_ask_again_for_this_version">此版本不再提示</string>
|
||||
<string name="text_code_beautify">格式化代码</string>
|
||||
<string name="text_processing">处理中</string>
|
||||
@@ -237,6 +237,11 @@
|
||||
<string name="text_close">关闭</string>
|
||||
<string name="text_adjust">调整</string>
|
||||
<string name="text_exit_floating_window">退出悬浮窗</string>
|
||||
<string name="text_save_and_edit">下载并编辑</string>
|
||||
<string name="text_select_save_path">保存到</string>
|
||||
<string name="text_cancel_download">取消下载</string>
|
||||
<string name="text_download">下载</string>
|
||||
<string name="format_file_downloaded" formatted="true">文件已保存到 %s</string>
|
||||
|
||||
|
||||
<string-array name="ad_showing_mode_keys">
|
||||
|
||||
@@ -94,11 +94,13 @@ public class PFile extends File {
|
||||
public PFile[] listFiles() {
|
||||
String ss[] = list();
|
||||
if (ss == null) return null;
|
||||
PFile[] files = new PFile[ss.length];
|
||||
ArrayList<PFile> files = new ArrayList<>();
|
||||
for (int i = 0; i < ss.length; i++) {
|
||||
files[i] = new PFile(ss[i]);
|
||||
if (!ss[i].startsWith(".")) {
|
||||
files.add(new PFile(ss[i]));
|
||||
}
|
||||
}
|
||||
return files;
|
||||
return files.toArray(new PFile[files.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,7 +109,7 @@ public class PFile extends File {
|
||||
if (ss == null) return null;
|
||||
ArrayList<PFile> files = new ArrayList<>();
|
||||
for (String s : ss)
|
||||
if ((filter == null) || filter.accept(this, s))
|
||||
if (!s.startsWith(".") && (filter == null || filter.accept(this, s)))
|
||||
files.add(new PFile(this, s));
|
||||
return files.toArray(new PFile[files.size()]);
|
||||
}
|
||||
@@ -119,7 +121,7 @@ public class PFile extends File {
|
||||
ArrayList<PFile> files = new ArrayList<>();
|
||||
for (String s : ss) {
|
||||
PFile f = new PFile(this, s);
|
||||
if ((filter == null) || filter.accept(f))
|
||||
if (!f.isHidden() && (filter == null || filter.accept(f)))
|
||||
files.add(f);
|
||||
}
|
||||
return files.toArray(new PFile[files.size()]);
|
||||
|
||||
Reference in New Issue
Block a user