Add: commonjs support, Fix: editor auto line break

This commit is contained in:
hyb1996
2017-03-25 15:49:23 +08:00
parent feff05e11c
commit 3f7dacad2a
38 changed files with 800 additions and 496 deletions

View File

@@ -0,0 +1,81 @@
package com.stardust.app;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.Fragment;
import android.util.SparseArray;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/3/24.
*/
public class FragmentPagerAdapterBuilder {
private List<Fragment> mFragments = new ArrayList<>();
private List<String> mTitles = new ArrayList<>();
private FragmentActivity mActivity;
public FragmentPagerAdapterBuilder(FragmentActivity activity) {
mActivity = activity;
}
public FragmentPagerAdapterBuilder add(Fragment fragment, String title) {
mFragments.add(fragment);
mTitles.add(title);
return this;
}
public FragmentPagerAdapterBuilder add(Fragment fragment, int titleResId) {
return add(fragment, mActivity.getString(titleResId));
}
public StoredFragmentPagerAdapter build() {
return new StoredFragmentPagerAdapter(mActivity.getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
};
}
public abstract static class StoredFragmentPagerAdapter extends FragmentPagerAdapter {
private SparseArray<Fragment> mStoredFragments = new SparseArray<>();
public StoredFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
mStoredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
mStoredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getStoredFragment(int position) {
return mStoredFragments.get(position);
}
}
}

View File

@@ -16,9 +16,9 @@ import static com.jecelyin.common.utils.StringUtils.md5;
* Created by Stardust on 2017/1/30.
*/
public class NotRemindAgainDialog extends MaterialDialog {
public class NotAskAgainDialog extends MaterialDialog {
protected NotRemindAgainDialog(Builder builder) {
protected NotAskAgainDialog(Builder builder) {
super(builder);
}

View File

@@ -289,7 +289,6 @@ public class DroidRuntime {
public ThemeColorMaterialDialogBuilder dialog() {
if (App.currentActivity() == null) {
Toast.makeText(App.getApp(), R.string.text_cannot_create_dialog_when_app_invisible, Toast.LENGTH_SHORT).show();
throw new ScriptStopException(App.getApp().getString(R.string.text_cannot_create_dialog_when_app_invisible));
}
return new ThemeColorMaterialDialogBuilder(App.currentActivity()) {

View File

@@ -1,17 +1,29 @@
package com.stardust.scriptdroid.droid.script;
import android.net.Uri;
import com.stardust.scriptdroid.droid.Droid;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
import com.stardust.scriptdroid.droid.runtime.ScriptStopException;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.commonjs.module.RequireBuilder;
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider;
import org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -63,11 +75,23 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
for (Map.Entry<String, Object> variable : mVariableMap.entrySet()) {
ScriptableObject.putProperty(scope, variable.getKey(), variable.getValue());
}
initRequireBuilder(context, scope);
context.evaluateString(scope, Init.getInitScript(), "<init>", 1, null);
mThreads.add(Thread.currentThread());
}
private void initRequireBuilder(Context context, Scriptable scope) {
List<URI> paths = Collections.singletonList(new File(ScriptFile.DEFAULT_FOLDER).toURI());
new RequireBuilder()
.setModuleScriptProvider(new SoftCachingModuleScriptProvider(
new UrlModuleSourceProvider(paths, null)))
.setSandboxed(true)
.createRequire(context, scope)
.install(scope);
}
@Override
public int stopAll() {

View File

@@ -29,6 +29,8 @@ public abstract class ScriptFileList {
public abstract int size();
public boolean deleteFromFileSystem(int i) {
if (i < 0 || i >= size())
return false;
File file = new File(get(i).path);
remove(i);
return file.delete();

View File

@@ -129,7 +129,6 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
private void startRecord() {
mRecorder = mRecordedByRootSwitch.isChecked() ? new TouchRecorder() : AccessibilityActionRecorder.getInstance();
AccessibilityActionRecorder.getInstance().setRecordMessageEnabled(mRecordToastSwitch.isChecked());
mRecorder.setOnStateChangedListener(this);
mRecorder.start();
setState(Recorder.STATE_RECORDING);

View File

@@ -1,170 +0,0 @@
package com.stardust.scriptdroid.external.notification.record;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.record.Recorder;
import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder;
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.service.VolumeChangeObverseService;
import com.stardust.scriptdroid.ui.main.MainActivity;
/**
* Created by Stardust on 2017/2/14.
*/
public class AccessibilityActionRecordNotification {
private static final String INTENT_ACTION = " com.stardust.scriptdroid.Record";
private static final String EXTRA_ACTION = "action";
private static final int ACTION_STOP = 17771;
private static final int ACTION_START_OR_PAUSE = 17772;
private static final int ACTION_DELETE = 17773;
private static final int ACTION_REDO = 17774;
private static final int NOTIFY_ID = 22236;
private static NotificationCompat.Builder builder;
private static BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int action = intent.getIntExtra(EXTRA_ACTION, 0);
switch (action) {
case ACTION_STOP:
stopRecord(context);
collapseNotificationBar(context);
break;
case ACTION_START_OR_PAUSE:
startOrPauseRecord(context);
collapseNotificationBar(context);
break;
case ACTION_DELETE:
AccessibilityActionRecordNotification.cancelNotification();
stopRecordIfNeeded(context);
break;
case ACTION_REDO:
redoRecord(context);
break;
}
}
};
static PendingIntent getStartOrPauseIntent() {
Intent intent = new Intent(INTENT_ACTION)
.putExtra(EXTRA_ACTION, ACTION_START_OR_PAUSE);
return PendingIntent.getBroadcast(App.getApp(), ACTION_START_OR_PAUSE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
static PendingIntent getStopIntent() {
Intent intent = new Intent(INTENT_ACTION)
.putExtra(EXTRA_ACTION, ACTION_STOP);
return PendingIntent.getBroadcast(App.getApp(), ACTION_STOP, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
static PendingIntent getDeleteIntent() {
Intent intent = new Intent(INTENT_ACTION)
.putExtra(EXTRA_ACTION, ACTION_DELETE);
return PendingIntent.getBroadcast(App.getApp(), ACTION_DELETE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
static PendingIntent getRedoIntent() {
Intent intent = new Intent(INTENT_ACTION)
.putExtra(EXTRA_ACTION, ACTION_REDO);
return PendingIntent.getService(App.getApp(), ACTION_REDO, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void showOrUpdateNotification() {
if (builder == null) {
builder = new NotificationCompat.Builder(App.getApp())
.setAutoCancel(false)
.setSmallIcon(R.drawable.ic_robot_head)
.setDeleteIntent(getDeleteIntent())
.setCustomContentView(AccessibilityActionRecordSwitchView.getInstance());
}
showNotification(builder.build());
App.getApp().startService(new Intent(App.getApp(), VolumeChangeObverseService.class));
}
private static void showNotification(Notification notification) {
NotificationManager notificationManager = (NotificationManager) App.getApp().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFY_ID, notification);
App.getApp().registerReceiver(broadcastReceiver, new IntentFilter(INTENT_ACTION));
}
public static void cancelNotification() {
NotificationManager notificationManager = (NotificationManager) App.getApp().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFY_ID);
App.getApp().unregisterReceiver(broadcastReceiver);
}
private static void collapseNotificationBar(Context context) {
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
}
private static void stopRecordIfNeeded(Context context) {
int state = AccessibilityActionRecorder.getInstance().getState();
if (state == Recorder.STATE_RECORDING || state == Recorder.STATE_PAUSED) {
stopRecord(context);
}
}
private static void startOrPauseRecord(Context context) {
int state = AccessibilityActionRecorder.getInstance().getState();
if (state == Recorder.STATE_PAUSED) {
resumeRecord(context);
} else if (state == Recorder.STATE_RECORDING) {
pauseRecord(context);
} else {
//state == STOPPED
startRecord(context);
}
}
public static void startRecord(Context context) {
if (AccessibilityWatchDogService.getInstance() == null) {
Toast.makeText(context, R.string.text_need_enable_accessibility_service_to_record, Toast.LENGTH_SHORT).show();
return;
}
AccessibilityActionRecorder.getInstance().start();
AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_RECORDING);
Toast.makeText(context, R.string.text_start_record, Toast.LENGTH_SHORT).show();
}
private static void pauseRecord(Context context) {
AccessibilityActionRecorder.getInstance().pause();
AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_PAUSED);
}
private static void resumeRecord(Context context) {
AccessibilityActionRecorder.getInstance().resume();
AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_RECORDING);
}
public static void stopRecord(Context context) {
if (AccessibilityActionRecorder.getInstance().getState() != Recorder.STATE_STOPPED) {
AccessibilityActionRecorder.getInstance().stop();
String script = AccessibilityActionRecorder.getInstance().getCode();
AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_STOPPED);
MainActivity.onActionRecordStopped(context, script);
} else {
Toast.makeText(App.getApp(), R.string.text_not_recording, Toast.LENGTH_SHORT).show();
}
}
private static void redoRecord(Context context) {
if (AccessibilityActionRecorder.getInstance().getState() != Recorder.STATE_STOPPED) {
AccessibilityActionRecorder.getInstance().stop();
AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_STOPPED);
}
}
}

View File

@@ -1,53 +0,0 @@
package com.stardust.scriptdroid.external.notification.record;
import android.widget.RemoteViews;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.record.Recorder;
/**
* Created by Stardust on 2017/2/14.
*/
public class AccessibilityActionRecordSwitchView extends RemoteViews {
private static AccessibilityActionRecordSwitchView instance;
public static AccessibilityActionRecordSwitchView getInstance() {
if (instance == null) {
instance = new AccessibilityActionRecordSwitchView();
}
return instance;
}
private AccessibilityActionRecordSwitchView() {
super(App.getApp().getPackageName(), R.layout.remote_views_record_switch);
setUpOnClick();
}
public void setState(int state) {
switch (state) {
case Recorder.STATE_STOPPED:
setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_play_arrow_grey600_48dp);
setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_start_record));
break;
case Recorder.STATE_RECORDING:
setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_pause_grey600_48dp);
setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_pause_record));
break;
case Recorder.STATE_PAUSED:
setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_play_arrow_grey600_48dp);
setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_resume_record));
break;
}
AccessibilityActionRecordNotification.showOrUpdateNotification();
}
private void setUpOnClick() {
setOnClickPendingIntent(R.id.stop, AccessibilityActionRecordNotification.getStopIntent());
setOnClickPendingIntent(R.id.start_or_pause, AccessibilityActionRecordNotification.getStartOrPauseIntent());
setOnClickPendingIntent(R.id.close, AccessibilityActionRecordNotification.getDeleteIntent());
setOnClickPendingIntent(R.id.redo, AccessibilityActionRecordNotification.getRedoIntent());
}
}

View File

@@ -87,9 +87,4 @@ public class AccessibilityActionRecorder extends Recorder.DefaultIMPL implements
mShouldIgnoreFirstAction = shouldIgnoreFirstAction;
}
public void setRecordMessageEnabled(boolean recordMessageEnabled) {
// TODO: 2017/3/16 添加录制提示
mRecordMessageEnabled = recordMessageEnabled;
}
}

View File

@@ -7,8 +7,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v7.widget.SwitchCompat;
import com.stardust.scriptdroid.external.notification.record.AccessibilityActionRecordNotification;
import com.stardust.scriptdroid.record.Recorder;
import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder;
import com.stardust.scriptdroid.Pref;

View File

@@ -1,6 +1,8 @@
package com.stardust.scriptdroid.tool;
import android.app.Activity;
import android.support.v4.widget.DrawerLayout;
import android.view.Gravity;
import android.widget.Toast;
import com.stardust.scriptdroid.R;
@@ -13,7 +15,27 @@ import java.util.List;
*/
public interface BackPressedHandler {
boolean onBackPressed();
boolean onBackPressed(Activity activity);
class Observer implements BackPressedHandler {
private List<BackPressedHandler> mBackPressedHandlers = new ArrayList<>();
@Override
public boolean onBackPressed(Activity activity) {
for (BackPressedHandler handler : mBackPressedHandlers) {
if (handler.onBackPressed(activity)) {
return true;
}
}
return false;
}
public void registerHandler(BackPressedHandler handler) {
mBackPressedHandlers.add(handler);
}
}
class DoublePressExit implements BackPressedHandler {
@@ -31,7 +53,7 @@ public interface BackPressedHandler {
}
@Override
public boolean onBackPressed() {
public boolean onBackPressed(Activity activity) {
if (System.currentTimeMillis() - mLastPressedMillis < mDoublePressInterval) {
mActivity.finish();
} else {
@@ -42,22 +64,23 @@ public interface BackPressedHandler {
}
}
class Observer implements BackPressedHandler {
class DrawerAutoClose implements BackPressedHandler {
private List<BackPressedHandler> mBackPressedHandlers = new ArrayList<>();
private DrawerLayout mDrawerLayout;
private int mGravity;
public DrawerAutoClose(DrawerLayout drawerLayout, int gravity){
mDrawerLayout = drawerLayout;
mGravity = gravity;
}
@Override
public boolean onBackPressed() {
for (BackPressedHandler handler : mBackPressedHandlers) {
if (handler.onBackPressed()) {
return true;
}
public boolean onBackPressed(Activity activity) {
if (mDrawerLayout.isDrawerOpen(mGravity)) {
mDrawerLayout.closeDrawer(mGravity);
return true;
}
return false;
}
public void registerHandler(BackPressedHandler handler) {
mBackPressedHandlers.add(handler);
}
}
}

View File

@@ -17,7 +17,7 @@ public class IntentTool {
public static boolean goToQQ(Context context, String qq) {
try {
String url = "mqqwpa://im/chat?chat_type=wpa&uin=" + qq;
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
} catch (Exception exception) {
exception.printStackTrace();
@@ -33,7 +33,7 @@ public class IntentTool {
* @return 返回true表示呼起手Q成功返回false表示呼起失败
******************/
public static boolean joinQQGroup(Context context, String key) {
Intent intent = new Intent();
Intent intent = new Intent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key));
// 此Flag可根据具体产品需要自定义如设置则在加群界面按返回返回手Q主界面不设置按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
@@ -48,7 +48,7 @@ public class IntentTool {
public static void goToMail(Context context, String sendTo, @Nullable String title, @Nullable String content) {
Uri uri = Uri.parse("mailto:" + sendTo);
String[] email = {sendTo};
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
Intent intent = new Intent(Intent.ACTION_SENDTO, uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_CC, email);
if (title != null)
intent.putExtra(Intent.EXTRA_SUBJECT, title);
@@ -62,7 +62,7 @@ public class IntentTool {
}
public static void goToLink(Context context, String link) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}

View File

@@ -10,6 +10,7 @@ import android.view.View;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.tool.BackPressedHandler;
import com.stardust.theme.ThemeColorManager;
import com.stardust.theme.app.ThemeColorAppCompatActivity;
@@ -27,6 +28,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class BaseActivity extends AppCompatActivity {
protected static final int PERMISSION_REQUEST_CODE = 11186;
private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -83,4 +85,15 @@ public class BaseActivity extends AppCompatActivity {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
public void registerBackPressedHandler(BackPressedHandler handler) {
mBackPressObserver.registerHandler(handler);
}
@Override
public void onBackPressed() {
if (!mBackPressObserver.onBackPressed(this)) {
super.onBackPressed();
}
}
}

View File

@@ -185,6 +185,7 @@ public class EditActivity extends Editor920Activity {
final EditorView editorView = (EditorView) findViewById(R.id.editor);
mEditorDelegate.setEditorView(editorView);
editorView.getEditText().setReadOnly(mReadOnly);
editorView.getEditText().setHorizontallyScrolling(true);
InputMethodEnhanceBar inputMethodEnhanceBar = (InputMethodEnhanceBar) findViewById(R.id.input_method_enhance_bar);
if (mReadOnly) {
inputMethodEnhanceBar.setVisibility(View.GONE);

View File

@@ -0,0 +1,26 @@
package com.stardust.scriptdroid.ui.edit;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.stardust.scriptdroid.ui.BaseActivity;
import xyz.iridiumion.iridiumhighlightingeditor.editor.HighlightingDefinition;
import xyz.iridiumion.iridiumhighlightingeditor.editor.IridiumHighlightingEditorJ;
import xyz.iridiumion.iridiumhighlightingeditor.highlightingdefinitions.definitions.JavaScriptHighlightingDefinition;
/**
* Created by Stardust on 2017/3/22.
*/
public class IridiumEditActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IridiumHighlightingEditorJ editorJ = new IridiumHighlightingEditorJ(this);
editorJ.setText("1234567");
editorJ.loadHighlightingDefinition(new JavaScriptHighlightingDefinition());
setContentView(editorJ);
}
}

View File

@@ -57,7 +57,8 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio
@Override
public void onClick(View v) {
int position = getChildViewHolder(v).getAdapterPosition();
mEditTextBridge.appendText(mCodeCompletionList.get(position).getAppendText());
if (position >= 0 && position < mCodeCompletionList.size())
mEditTextBridge.appendText(mCodeCompletionList.get(position).getAppendText());
}
};
@@ -65,6 +66,8 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio
@Override
public boolean onLongClick(View v) {
int position = getChildViewHolder(v).getAdapterPosition();
if (position < 0 || position >= mCodeCompletionList.size())
return false;
((ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("", mCodeCompletionList.get(position).getDisplayText()));
Toast.makeText(getContext(), R.string.text_copied, Toast.LENGTH_SHORT).show();
return true;

View File

@@ -0,0 +1,39 @@
package com.stardust.scriptdroid.ui.main;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.stardust.scriptdroid.R;
/**
* Created by Stardust on 2017/3/23.
*/
public abstract class AppbarWithTabFragment extends BottomNavigationFragment {
@Nullable
@Override
public View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_app_bar_tab, container, false);
FrameLayout contentContainer = (FrameLayout) view.findViewById(R.id.content);
contentContainer.addView(createContentView(inflater, contentContainer));
return view;
}
@CallSuper
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
protected abstract View createContentView(LayoutInflater inflater, @Nullable ViewGroup container);
}

View File

@@ -0,0 +1,78 @@
package com.stardust.scriptdroid.ui.main;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import com.ashokvarma.bottomnavigation.BottomNavigationBar;
import com.ashokvarma.bottomnavigation.BottomNavigationItem;
import com.stardust.app.Fragment;
import com.stardust.theme.ThemeColor;
import com.stardust.theme.ThemeColorManager;
import com.stardust.theme.ThemeColorMutable;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/3/23.
*/
public abstract class BottomNavigationFragment extends Fragment {
public static class Builder implements BottomNavigationBar.OnTabSelectedListener, ThemeColorMutable {
private int mFragmentId;
private BottomNavigationBar mBottomNavigationBar;
private FragmentManager mFragmentManager;
private List<BottomNavigationFragment> mFragments = new ArrayList<>();
public Builder(int fragmentId, BottomNavigationBar bottomNavigationBar, FragmentManager fragmentManager) {
mFragmentId = fragmentId;
mBottomNavigationBar = bottomNavigationBar;
mFragmentManager = fragmentManager;
mBottomNavigationBar.setTabSelectedListener(this);
ThemeColorManager.add(this);
}
public Builder add(BottomNavigationFragment fragment) {
mFragments.add(fragment);
mBottomNavigationBar.addItem(new BottomNavigationItem(fragment.getIconResId(), fragment.getTitle()));
return this;
}
public void build() {
mBottomNavigationBar.setFirstSelectedPosition(0);
mBottomNavigationBar.initialise();
mFragmentManager.beginTransaction().replace(mFragmentId, mFragments.get(0)).commit();
}
@Override
public void onTabSelected(int position) {
BottomNavigationFragment fragment = mFragments.get(position);
mFragmentManager.beginTransaction().replace(mFragmentId, fragment).commit();
}
@Override
public void onTabUnselected(int position) {
}
@Override
public void onTabReselected(int position) {
}
@Override
public void setThemeColor(ThemeColor themeColor) {
mBottomNavigationBar.setActiveColor("#" + Integer.toHexString(themeColor.colorPrimary).substring(2));
}
}
protected abstract String getTitle();
protected abstract int getIconResId();
}

View File

@@ -2,6 +2,7 @@ package com.stardust.scriptdroid.ui.main;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -12,7 +13,6 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
@@ -27,20 +27,19 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.folderselector.FileChooserDialog;
import com.stardust.app.NotRemindAgainDialog;
import com.stardust.app.FragmentPagerAdapterBuilder;
import com.stardust.app.NotAskAgainDialog;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.external.notification.record.AccessibilityActionRecordNotification;
import com.stardust.scriptdroid.record.inputevent.InputEventRecorder;
import com.stardust.scriptdroid.record.inputevent.InputEventToJsRecorder;
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
import com.stardust.scriptdroid.tool.ImageSelector;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.my_script_list.MyScriptListFragment;
import com.stardust.scriptdroid.ui.main.sample_list.SampleScriptListFragment;
import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment;
import com.stardust.scriptdroid.ui.settings.SettingsActivity;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.MessageEvent;
@@ -50,7 +49,6 @@ import com.stardust.scriptdroid.BuildConfig;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.tool.FileUtils;
import com.stardust.scriptdroid.tool.BackPressedHandler;
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
import com.stardust.view.ViewBinder;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
@@ -65,39 +63,46 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
private static final String ACTION_ON_ACTION_RECORD_STOPPED = "ACTION_ON_ACTION_RECORD_STOPPED";
private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT";
private static final String ACTION_ON_ROOT_RECORD_STOPPED = "ACTION_ON_ROOT_RECORD_STOPPED";
private ScriptFileList mScriptFileList;
private DrawerLayout mDrawerLayout;
@ViewBinding.Id(R.id.bottom_menu)
private SlidingUpPanel mAddBottomMenuPanel;
private FragmentPagerAdapterBuilder.StoredFragmentPagerAdapter mPagerAdapter;
private MyScriptListFragment mMyScriptListFragment;
private SampleScriptListFragment mSampleScriptListFragment;
private OnActivityResultDelegate.Intermediary mActivityResultIntermediary = new OnActivityResultDelegate.Intermediary();
private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setUpUI();
checkPermissions();
registerBackPressHandler();
registerBackPressHandlers();
handleIntent(getIntent());
}
private void registerBackPressHandler() {
mBackPressObserver.registerHandler(new BackPressedHandler.DoublePressExit(this));
private void registerBackPressHandlers() {
registerBackPressedHandler(new BackPressedHandler() {
@Override
public boolean onBackPressed(Activity activity) {
if (mAddBottomMenuPanel.isShowing()) {
mAddBottomMenuPanel.dismiss();
return true;
}
return false;
}
});
registerBackPressedHandler(new BackPressedHandler.DrawerAutoClose(mDrawerLayout, Gravity.START));
registerBackPressedHandler(new BackPressedHandler.DoublePressExit(this));
}
private void checkPermissions() {
checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
goToAccessibilityPermissionSettingIfDisabled();
showAccessibilitySettingPromptIfDisabled();
}
private void goToAccessibilityPermissionSettingIfDisabled() {
private void showAccessibilitySettingPromptIfDisabled() {
if (!AccessibilityServiceUtils.isAccessibilityServiceEnabled(this, AccessibilityWatchDogService.class)) {
new NotRemindAgainDialog.Builder(this, "goToAccessibilityPermissionSettingIfDisabled")
new NotAskAgainDialog.Builder(this, "showAccessibilitySettingPromptIfDisabled")
.title(R.string.text_need_to_enable_accessibility_service)
.content(R.string.explain_accessibility_permission)
.positiveText(R.string.text_go_to_setting)
@@ -123,33 +128,23 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
}
private void addScriptFile(String name, String path) {
mScriptFileList.add(new ScriptFile(name, path));
ScriptFileList.getImpl().add(new ScriptFile(name, path));
EventBus.getDefault().post(new MessageEvent(MyScriptListFragment.MESSAGE_SCRIPT_FILE_ADDED));
}
private void setUpUI() {
mDrawerLayout = (DrawerLayout) View.inflate(this, R.layout.activity_main, null);
setContentView(mDrawerLayout);
setUpFragment();
setUpToolbar();
setUpTabLayout();
setUpTabViewPager();
setUpDrawerHeader();
setUpFragment();
ViewBinder.bind(this);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
private void setUpFragment() {
SlideMenuFragment.setFragment(this, R.id.fragment_slide_menu);
mMyScriptListFragment = new MyScriptListFragment();
mScriptFileList = ScriptFileList.getImpl();
mSampleScriptListFragment = new SampleScriptListFragment();
}
private void setUpTabLayout() {
TabLayout tabLayout = $(R.id.tab);
ViewPager viewPager = $(R.id.viewpager);
viewPager.setAdapter(new FragmentPagerAdapter());
tabLayout.setupWithViewPager(viewPager);
}
@SuppressLint("SetTextI18n")
@@ -164,7 +159,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
if (path != null) {
setAppBarImage(path);
}
$(R.id.drawer).setFitsSystemWindows(false);
}
private void setDrawerHeaderImage(String path) {
@@ -178,13 +172,23 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
Toolbar toolbar = $(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle(R.string._app_name);
ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.text_drawer_open,
R.string.text_drawer_close);
drawerToggle.syncState();
mDrawerLayout.addDrawerListener(drawerToggle);
}
private void setUpTabViewPager() {
TabLayout tabLayout = $(R.id.tab);
ViewPager viewPager = $(R.id.viewpager);
mPagerAdapter = new FragmentPagerAdapterBuilder(this)
.add(new MyScriptListFragment(), R.string.text_my_script)
.add(new SampleScriptListFragment(), R.string.text_sample_script)
.add(new TaskManagerFragment(), R.string.text_task_manage)
.build();
viewPager.setAdapter(mPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
@ViewBinding.Click(R.id.add)
private void showAddFilePanel() {
@@ -218,7 +222,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
}
}
addScriptFile(name, path);
new ScriptFileOperation.Edit().operate(mMyScriptListFragment.getScriptListRecyclerView(), mScriptFileList, mScriptFileList.size() - 1);
((MyScriptListFragment) mPagerAdapter.getStoredFragment(0)).editLatest();
} else {
Snackbar.make(mDrawerLayout, R.string.text_file_create_fail, Snackbar.LENGTH_LONG).show();
}
@@ -232,27 +236,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
.show();
}
@ViewBinding.Click(R.id.record)
private void startScriptRecord() {
if (AccessibilityWatchDogService.getInstance() == null) {
Snackbar.make(mDrawerLayout, R.string.text_need_enable_accessibility_service_to_record, Snackbar.LENGTH_SHORT).show();
return;
}
AccessibilityActionRecordNotification.showOrUpdateNotification();
Snackbar.make(mDrawerLayout, R.string.hint_start_record, Snackbar.LENGTH_SHORT).show();
}
private InputEventRecorder mInputEventRecorder;
@ViewBinding.Click(R.id.root_record)
private void startRootRecord() {
if (mInputEventRecorder == null) {
mInputEventRecorder = new InputEventToJsRecorder();
mInputEventRecorder.listen();
}
Snackbar.make(mDrawerLayout, R.string.hint_start_root_record, Snackbar.LENGTH_SHORT).show();
}
@ViewBinding.Click(R.id.setting)
private void startSettingActivity() {
startActivity(new Intent(this, SettingsActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
@@ -294,13 +277,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
case ACTION_ON_ACTION_RECORD_STOPPED:
handleRecordedScript(intent.getStringExtra(ARGUMENT_SCRIPT));
break;
case ACTION_ON_ROOT_RECORD_STOPPED:
if (mInputEventRecorder != null) {
mInputEventRecorder.stop();
handleRecordedScript(mInputEventRecorder.getCode());
mInputEventRecorder = null;
}
break;
}
}
@@ -329,19 +305,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
})
.canceledOnTouchOutside(false)
.show();
}
@Override
public void onBackPressed() {
if (mAddBottomMenuPanel.isShowing()) {
mAddBottomMenuPanel.dismiss();
} else if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(Gravity.START);
} else {
mBackPressObserver.onBackPressed();
}
}
@Override
@@ -362,14 +325,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
context.startActivity(intent);
}
public static void onRootRecordStopped(Context context) {
Intent intent = new Intent(context, MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(EXTRA_ACTION, ACTION_ON_ROOT_RECORD_STOPPED);
context.startActivity(intent);
}
@ViewBinding.Click(R.id.toolbar)
public void OnToolbarClick() {
new ImageSelector(this, mActivityResultIntermediary, new ImageSelector.ImageSelectorCallback() {
@@ -385,29 +340,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
private void setAppBarImage(String path) {
Drawable d = BitmapDrawable.createFromPath(path);
if (d != null) {
$(R.id.app_bar).setBackground(d);
}
}
private class FragmentPagerAdapter extends android.support.v4.app.FragmentPagerAdapter {
FragmentPagerAdapter() {
super(MainActivity.this.getSupportFragmentManager());
}
@Override
public Fragment getItem(int position) {
return position == 0 ? mMyScriptListFragment : mSampleScriptListFragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
return getString(position == 0 ? R.string.text_my_script : R.string.text_sample_script);
((ImageView) $(R.id.app_bar_bg)).setImageDrawable(d);
}
}

View File

@@ -4,6 +4,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SwitchCompat;
import android.view.LayoutInflater;
@@ -33,7 +34,7 @@ import org.greenrobot.eventbus.Subscribe;
public class SlideMenuFragment extends Fragment {
public static void setFragment(AppCompatActivity activity, int viewId) {
public static void setFragment(FragmentActivity activity, int viewId) {
SlideMenuFragment fragment = new SlideMenuFragment();
activity.getSupportFragmentManager().beginTransaction().replace(viewId, fragment).commit();
}

View File

@@ -1,5 +1,6 @@
package com.stardust.scriptdroid.ui.main.my_script_list;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
@@ -12,6 +13,8 @@ import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
import com.stardust.scriptdroid.tool.BackPressedHandler;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
import com.stardust.util.MessageEvent;
import com.stardust.widget.SimpleAdapterDataObserver;
@@ -30,10 +33,14 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler
private ScriptFileList mScriptFileList;
private View mNoScriptHint;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
if(!(getActivity() instanceof BaseActivity)){
throw new IllegalArgumentException("The fragment can only be used in BaseActivity");
}
}
@Nullable
@@ -61,8 +68,9 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler
mScriptListRecyclerView.setScriptFileList(mScriptFileList);
}
//// FIXME: 2017/3/24
@Override
public boolean onBackPressed() {
public boolean onBackPressed(Activity activity) {
if (mScriptListRecyclerView.getScriptFileOperationPopupMenu().isShowing()) {
mScriptListRecyclerView.getScriptFileOperationPopupMenu().dismiss();
return true;
@@ -98,4 +106,8 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler
super.onDestroy();
EventBus.getDefault().unregister(this);
}
public void editLatest() {
ScriptFileOperation.Edit.getInstance().operate(mScriptListRecyclerView, mScriptFileList, mScriptFileList.size() - 1);
}
}

View File

@@ -12,6 +12,7 @@ import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.external.shortcut.Shortcut;
import com.stardust.scriptdroid.external.shortcut.ShortcutActivity;
import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.scriptdroid.ui.edit.IridiumEditActivity;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
@@ -67,14 +68,28 @@ public abstract class ScriptFileOperation {
public static class Edit extends ScriptFileOperation {
private static Edit instance = new Edit();
public Edit() {
super(App.getApp().getString(R.string.text_edit), R.drawable.ic_edit_green_48dp);
}
public static Edit getInstance() {
return instance;
}
public static void setInstance(Edit instance) {
Edit.instance = instance;
}
@Override
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
ScriptFile scriptFile = scriptFileList.get(position);
EditActivity.editFile(App.getApp(), scriptFile.name, scriptFile.path);
//脚本
//任务&控制台
//教程
//
}
}
@@ -88,7 +103,7 @@ public abstract class ScriptFileOperation {
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
ScriptFile scriptFile = scriptFileList.get(position);
Uri uri = Uri.parse("file://" + scriptFile.path);
App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain"));
App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}
@@ -156,7 +171,8 @@ public abstract class ScriptFileOperation {
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
boolean succeed = scriptFileList.deleteFromFileSystem(position);
EventBus.getDefault().post(new ShowMessageEvent(succeed ? R.string.text_already_delete : R.string.text_delete_failed));
recyclerView.getAdapter().notifyItemRemoved(position);
if (succeed)
recyclerView.getAdapter().notifyItemRemoved(position);
}
}

View File

@@ -0,0 +1,21 @@
package com.stardust.scriptdroid.ui.main.task;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.stardust.app.Fragment;
/**
* Created by Stardust on 2017/3/24.
*/
public class TaskManagerFragment extends Fragment {
@Nullable
@Override
public View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return null;
}
}

View File

@@ -0,0 +1,8 @@
package com.stardust.scriptdroid.ui.main.task;
/**
* Created by Stardust on 2017/3/24.
*/
public class TaskManagerRecyclerView {
}

View File

@@ -57,13 +57,13 @@ public class CommonMarkdownView extends WebView {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(request.getUrl()));
getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(request.getUrl()).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)));
getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
}