Commit 9b4e67c3 authored by Javier Romero's avatar Javier Romero

Merge branch 'feature/query-redesign' into 'master'

Query Redesign

See merge request !15
parents 54f4af3b 8551adf8
Pipeline #32871144 passed with stages
in 66 minutes and 33 seconds
...@@ -32,18 +32,20 @@ android { ...@@ -32,18 +32,20 @@ android {
compileSdkVersion 28 compileSdkVersion 28
buildToolsVersion '28.0.2' buildToolsVersion '28.0.2'
androidExtensions {
experimental = true
}
defaultConfig { defaultConfig {
applicationId "app.devlife.connect2sql" applicationId "app.devlife.connect2sql"
/* format: [ M].[00m].[00p] */
versionCode 4000012
versionName "4.0.12"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 28
manifestPlaceholders = [fabricApiKey: fabricApiKey] manifestPlaceholders = [fabricApiKey: fabricApiKey]
project.version = versionName project.version = versionName
targetSdkVersion 28
/* format: [ M].[00m].[00p] */
versionCode 4000012
versionName "4.0.12"
} }
testOptions { testOptions {
...@@ -101,6 +103,7 @@ android { ...@@ -101,6 +103,7 @@ android {
} }
detekt { detekt {
version = '1.0.0.RC8'
defaultProfile { defaultProfile {
config = file("$projectDir/detekt.yml") config = file("$projectDir/detekt.yml")
output = file("$buildDir/reports/") output = file("$buildDir/reports/")
...@@ -110,6 +113,7 @@ android { ...@@ -110,6 +113,7 @@ android {
} }
ext { ext {
version_arch = '1.1.1'
version_answers = '1.4.3' version_answers = '1.4.3'
version_constraint_layout = '1.1.3' version_constraint_layout = '1.1.3'
version_crashlytcs = '2.9.5' version_crashlytcs = '2.9.5'
...@@ -117,6 +121,7 @@ ext { ...@@ -117,6 +121,7 @@ ext {
version_jsr250 = '1.0' version_jsr250 = '1.0'
version_jsch = '0.1.54' version_jsch = '0.1.54'
version_logback_android = '1.1.1-12' version_logback_android = '1.1.1-12'
version_expandable_rv = '1.3'
version_mariadb = '1.7.4' version_mariadb = '1.7.4'
version_dexmaker_mockito = '2.19.0' version_dexmaker_mockito = '2.19.0'
version_patternlock = '2.1.2' version_patternlock = '2.1.2'
...@@ -124,11 +129,13 @@ ext { ...@@ -124,11 +129,13 @@ ext {
version_saripaar = '1.0.3' version_saripaar = '1.0.3'
version_sqlcipher = '3.5.9' version_sqlcipher = '3.5.9'
version_slf4j = '1.7.25' version_slf4j = '1.7.25'
version_support = '28.0.0-rc01' version_support = '28.0.0'
} }
dependencies { dependencies {
implementation fileTree(include: '*.jar', dir: 'libs') implementation fileTree(include: '*.jar', dir: 'libs')
implementation "android.arch.lifecycle:extensions:${version_arch}"
implementation "android.arch.lifecycle:viewmodel:${version_arch}"
implementation "com.android.support:support-v4:${version_support}" implementation "com.android.support:support-v4:${version_support}"
implementation "com.android.support:support-annotations:${version_support}" implementation "com.android.support:support-annotations:${version_support}"
implementation "com.android.support:appcompat-v7:${version_support}" implementation "com.android.support:appcompat-v7:${version_support}"
...@@ -152,6 +159,7 @@ dependencies { ...@@ -152,6 +159,7 @@ dependencies {
implementation "com.jcraft:jsch:${version_jsch}" implementation "com.jcraft:jsch:${version_jsch}"
implementation "com.linkedin.dexmaker:dexmaker-mockito:${version_dexmaker_mockito}" implementation "com.linkedin.dexmaker:dexmaker-mockito:${version_dexmaker_mockito}"
implementation "com.mobsandgeeks:android-saripaar:${version_saripaar}" implementation "com.mobsandgeeks:android-saripaar:${version_saripaar}"
implementation "com.thoughtbot:expandablerecyclerview:${version_expandable_rv}"
implementation "javax.annotation:jsr250-api:${version_jsr250}" implementation "javax.annotation:jsr250-api:${version_jsr250}"
implementation "io.reactivex:rxandroid:${version_rx}" implementation "io.reactivex:rxandroid:${version_rx}"
implementation "io.reactivex:rxjava:${version_rx}" implementation "io.reactivex:rxjava:${version_rx}"
......
...@@ -48,16 +48,8 @@ ...@@ -48,16 +48,8 @@
android:label="@string/activity_host_keys" /> android:label="@string/activity_host_keys" />
<activity <activity
android:name="app.devlife.connect2sql.ui.query.QueryActivity" android:name="app.devlife.connect2sql.ui.query.QueryActivity"
android:configChanges="orientation|uiMode|screenSize|smallestScreenSize|keyboardHidden"
android:label="@string/activity_query" android:label="@string/activity_query"
android:uiOptions="splitActionBarWhenNarrow" android:theme="@style/Theme.C2SQL.NoActionBar" />
android:windowSoftInputMode="adjustResize" />
<activity
android:name="app.devlife.connect2sql.ui.savedqueries.SavedQueriesActivity"
android:label="@string/activity_saved_queries" />
<activity
android:name="app.devlife.connect2sql.ui.history.QueryHistoryActivity"
android:label="@string/activity_query_history" />
<activity <activity
android:name="app.devlife.connect2sql.ui.results.ResultsActivity" android:name="app.devlife.connect2sql.ui.results.ResultsActivity"
android:configChanges="orientation|uiMode|screenSize|smallestScreenSize|keyboardHidden" android:configChanges="orientation|uiMode|screenSize|smallestScreenSize|keyboardHidden"
......
package app.devlife.connect2sql;
import android.app.Activity;
import android.app.Application;
import java.lang.ref.WeakReference;
import javax.inject.Inject;
import app.devlife.connect2sql.activity.LaunchActivity;
import app.devlife.connect2sql.data.LockManager;
import app.devlife.connect2sql.di.AnalyticsModule;
import app.devlife.connect2sql.di.ApplicationComponent;
import app.devlife.connect2sql.di.ApplicationModule;
import app.devlife.connect2sql.di.ConnectionModule;
import app.devlife.connect2sql.di.DaggerApplicationComponent;
import app.devlife.connect2sql.di.DatabaseModule;
import app.devlife.connect2sql.di.PreferencesModule;
import app.devlife.connect2sql.di.SecurityModule;
import app.devlife.connect2sql.log.EzLogger;
import io.fabric.sdk.android.Fabric;
/**
*
*/
public class Connect2SqlApplication extends Application {
private ApplicationComponent mApplicationComponent;
@Inject
ApplicationFocusManager mApplicationFocusManager;
@Inject
LockManager mLockManager;
@Inject
Fabric mFabric;
@Override
public void onCreate() {
super.onCreate();
mApplicationComponent = DaggerApplicationComponent.builder()
.analyticsModule(new AnalyticsModule(this))
.applicationModule(new ApplicationModule(this))
.connectionModule(new ConnectionModule(this))
.databaseModule(new DatabaseModule(this))
.preferencesModule(new PreferencesModule(this))
.securityModule(new SecurityModule(this))
.build();
mApplicationComponent.inject(this);
mApplicationFocusManager.addOnFocusChangeListener(mOnFocusChangeListener);
EzLogger.i("Fabric version: " + mFabric.getVersion());
}
public ApplicationComponent getApplicationComponent() {
return mApplicationComponent;
}
private ApplicationFocusManager.OnFocusChangeListener mOnFocusChangeListener = new ApplicationFocusManager.OnFocusChangeListener() {
@Override
public void onApplicationFocusChange(boolean focused) {
if (focused) {
WeakReference<Activity> lastFocusedActivity = mApplicationFocusManager.getLastFocusedActivity();
if (lastFocusedActivity != null) {
if (lastFocusedActivity.get() != null) {
Activity activity = lastFocusedActivity.get();
EzLogger.d("Last focused activity: " + activity);
if (!activity.getClass().equals(LaunchActivity.class)) {
if (!mLockManager.isSetLockActivity(activity) &&
!mLockManager.isUnlockActivity(activity) &&
!mLockManager.isForgotLockActivity(activity)) {
mLockManager.startUnlockActivity(activity, 0);
} else {
EzLogger.d("Activity is a lock specific activity.");
}
} else {
EzLogger.d("Last focused activity was the Launch activity.");
}
} else {
EzLogger.d("Last focused activity has gone away.");
}
} else {
EzLogger.d("No reference to last focused activity");
}
}
}
};
}
package app.devlife.connect2sql
import android.app.Activity
import android.app.Application
import app.devlife.connect2sql.activity.LaunchActivity
import app.devlife.connect2sql.data.LockManager
import app.devlife.connect2sql.di.AnalyticsModule
import app.devlife.connect2sql.di.ApplicationComponent
import app.devlife.connect2sql.di.ApplicationModule
import app.devlife.connect2sql.di.ConnectionModule
import app.devlife.connect2sql.di.DaggerApplicationComponent
import app.devlife.connect2sql.di.DatabaseModule
import app.devlife.connect2sql.di.PreferencesModule
import app.devlife.connect2sql.di.SecurityModule
import app.devlife.connect2sql.log.EzLogger
import io.fabric.sdk.android.Fabric
import javax.inject.Inject
/**
*
*/
class Connect2SqlApplication : Application() {
lateinit var applicationComponent: ApplicationComponent
@Inject
lateinit var applicationFocusManager: ApplicationFocusManager
@Inject
lateinit var lockManager: LockManager
@Inject
lateinit var fabric: Fabric
private val mOnFocusChangeListener = ApplicationFocusManager.OnFocusChangeListener { focused ->
if (focused) {
val lastFocusedActivity = applicationFocusManager.lastFocusedActivity
if (lastFocusedActivity != null) {
if (lastFocusedActivity.get() != null) {
val activity = lastFocusedActivity.get()
EzLogger.d("Last focused activity: $activity")
if (activity !is LaunchActivity) {
if (!lockManager.isSetLockActivity(activity) &&
!lockManager.isUnlockActivity(activity) &&
!lockManager.isForgotLockActivity(activity)) {
lockManager.startUnlockActivity(activity, 0)
} else {
EzLogger.d("Activity is a lock specific activity.")
}
} else {
EzLogger.d("Last focused activity was the Launch activity.")
}
} else {
EzLogger.d("Last focused activity has gone away.")
}
} else {
EzLogger.d("No reference to last focused activity")
}
}
}
override fun onCreate() {
super.onCreate()
applicationComponent = DaggerApplicationComponent.builder()
.analyticsModule(AnalyticsModule(this))
.applicationModule(ApplicationModule(this))
.connectionModule(ConnectionModule(this))
.databaseModule(DatabaseModule(this))
.preferencesModule(PreferencesModule(this))
.securityModule(SecurityModule(this))
.build()
.also { it.inject(this) }
applicationFocusManager.addOnFocusChangeListener(mOnFocusChangeListener)
EzLogger.i("Fabric version: " + fabric.version)
}
}
package app.devlife.connect2sql.adapter;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
import com.gitlab.connect2sql.R;
public class QuickKeysAdapter extends BaseExpandableListAdapter {
public static final int SECTION_SNIPPETS = 0;
public static final int SECTION_OPERATORS = 1;
public static final int SECTION_DATABASES = 2;
public static final int SECTION_TABLES = 3;
public static final int SECTION_COLUMNS = 4;
private List<List<String>> mData = new ArrayList<List<String>>();
private Context mContext;
private int mListItemLayout = android.R.layout.simple_expandable_list_item_1;
public int getListItemLayout() {
return mListItemLayout;
}
public void setListItemLayout(int mListItemLayout) {
this.mListItemLayout = mListItemLayout;
}
public QuickKeysAdapter(Context context) {
mContext = context;
for (int i = 0; i < 5; i++) {
mData.add(new ArrayList<String>());
}
}
public void clearSection(int section) {
mData.get(section).clear();
}
public void addChild(String value, int section) {
mData.get(section).add(value);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return ((List<?>) getGroup(groupPosition)).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
// if no view present build it
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mListItemLayout, null);
convertView.setBackgroundColor(Color.TRANSPARENT);
}
TextView textView = (TextView) convertView
.findViewById(android.R.id.text1);
//textView.setPadding(10, 30, 10, 30);
textView.setText(getChild(groupPosition, childPosition).toString());
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
return ((List<?>) getGroup(groupPosition)).size();
}
@Override
public Object getGroup(int groupPosition) {
return mData.get(groupPosition);
}
@Override
public int getGroupCount() {
return mData.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
// if no view present build it
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mListItemLayout, null);
}
TextView textView = (TextView) convertView
.findViewById(android.R.id.text1);
//textView.setPadding(10, 30, 10, 30);
switch (groupPosition) {
case SECTION_COLUMNS:
textView.setText(R.string.qk_section_column);
break;
case SECTION_DATABASES:
textView.setText(R.string.qk_section_databases);
break;
case SECTION_TABLES:
textView.setText(R.string.qk_section_tables);
break;
case SECTION_SNIPPETS:
textView.setText(R.string.qk_section_snippets);
break;
case SECTION_OPERATORS:
textView.setText(R.string.qk_section_operators);
break;
default:
textView.setText("");
break;
}
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
package app.devlife.connect2sql.adapter package app.devlife.connect2sql.adapter
import app.devlife.connect2sql.db.model.query.BaseNamedQuery
import app.devlife.connect2sql.db.model.query.BuiltInQuery
import com.gitlab.connect2sql.R
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.BaseExpandableListAdapter import android.widget.BaseExpandableListAdapter
import android.widget.TextView import android.widget.TextView
import app.devlife.connect2sql.db.model.query.BaseNamedQuery
import app.devlife.connect2sql.db.model.query.BuiltInQuery
import app.devlife.connect2sql.db.model.query.SavedQuery import app.devlife.connect2sql.db.model.query.SavedQuery
import com.gitlab.connect2sql.R
class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdapter() { class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdapter() {
var titleOnly = false var titleOnly = false
...@@ -30,6 +30,10 @@ class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdap ...@@ -30,6 +30,10 @@ class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdap
queries[GROUP_SAVED].remove(query) queries[GROUP_SAVED].remove(query)
} }
fun clearSavedQueries() {
queries[GROUP_SAVED].clear()
}
fun clear() { fun clear() {
queries[GROUP_BUILTIN].clear() queries[GROUP_BUILTIN].clear()
queries[GROUP_SAVED].clear() queries[GROUP_SAVED].clear()
...@@ -52,11 +56,7 @@ class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdap ...@@ -52,11 +56,7 @@ class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdap
): View { ): View {
val view: View = when (convertView) { val view: View = when (convertView) {
null -> { null -> inflator.inflate(R.layout.item_query_list_child, null)
val view = inflator.inflate(R.layout.item_query_list_child, null)
view.setPadding(80, 10, 2, 10)
view
}
else -> convertView else -> convertView
} }
...@@ -92,15 +92,11 @@ class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdap ...@@ -92,15 +92,11 @@ class SavedQueriesAdapter(private val context: Context) : BaseExpandableListAdap
parent: ViewGroup parent: ViewGroup
): View { ): View {
val view: View = when (convertView) { val view: View = when (convertView) {
null -> { null -> inflator.inflate(R.layout.item_expandable_group, null)
val view = inflator.inflate(android.R.layout.simple_expandable_list_item_1, null)
view.setPadding(80, 15, 2, 15)
view
}
else -> convertView else -> convertView
} }
val textView = view.findViewById(android.R.id.text1) as TextView val textView = view.findViewById(R.id.text1) as TextView
when (groupPosition) { when (groupPosition) {
GROUP_BUILTIN -> textView.text = builtInText GROUP_BUILTIN -> textView.text = builtInText
else -> textView.text = savedText else -> textView.text = savedText
......
...@@ -9,7 +9,7 @@ data class ConnectionInfo( ...@@ -9,7 +9,7 @@ data class ConnectionInfo(
val host: String, val host: String,
val port: Int, val port: Int,
val username: String, val username: String,
val password: String?, val password: String,
val database: String?, val database: String?,
val sshConfig: SshConfig?, val sshConfig: SshConfig?,
val options: Map<String, String> val options: Map<String, String>
......
...@@ -6,7 +6,7 @@ import app.devlife.connect2sql.db.model.SqlModel; ...@@ -6,7 +6,7 @@ import app.devlife.connect2sql.db.model.SqlModel;
import android.net.Uri; import android.net.Uri;
public class ContentUriHelper { public class ContentUriHelper {
private static HashMap<String, HashMap<Class<? extends SqlModel>, Uri>> sCachedUris = new HashMap<String, HashMap<Class<? extends SqlModel>, Uri>>(); private static HashMap<String, HashMap<Class<? extends SqlModel>, Uri>> sCachedUris = new HashMap<>();
public static Uri getContentUri(Class<? extends SqlModel> clazz) throws BaseUriNotFoundException { public static Uri getContentUri(Class<? extends SqlModel> clazz) throws BaseUriNotFoundException {
return getContentUri(AppContentProvider.AUTHORITY, clazz); return getContentUri(AppContentProvider.AUTHORITY, clazz);
......
...@@ -5,14 +5,16 @@ import javax.inject.Singleton; ...@@ -5,14 +5,16 @@ import javax.inject.Singleton;
import app.devlife.connect2sql.Connect2SqlApplication; import app.devlife.connect2sql.Connect2SqlApplication;
import app.devlife.connect2sql.activity.DashboardActivity; import app.devlife.connect2sql.activity.DashboardActivity;
import app.devlife.connect2sql.activity.LaunchActivity; import app.devlife.connect2sql.activity.LaunchActivity;
import app.devlife.connect2sql.ui.browse.BrowseFragment;
import app.devlife.connect2sql.ui.connection.ConnectionInfoEditorActivity; import app.devlife.connect2sql.ui.connection.ConnectionInfoEditorActivity;
import app.devlife.connect2sql.ui.history.QueryHistoryActivity; import app.devlife.connect2sql.ui.history.HistoryFragment;
import app.devlife.connect2sql.ui.hostkeys.HostKeysActivity; import app.devlife.connect2sql.ui.hostkeys.HostKeysActivity;
import app.devlife.connect2sql.ui.lock.SetLockActivity; import app.devlife.connect2sql.ui.lock.SetLockActivity;
import app.devlife.connect2sql.ui.lock.UnlockActivity; import app.devlife.connect2sql.ui.lock.UnlockActivity;
import app.devlife.connect2sql.ui.query.QueryActivity; import app.devlife.connect2sql.ui.query.QueryActivity;
import app.devlife.connect2sql.ui.quickkeys.QuickKeysFragment;
import app.devlife.connect2sql.ui.results.ResultsActivity; import app.devlife.connect2sql.ui.results.ResultsActivity;
import app.devlife.connect2sql.ui.savedqueries.SavedQueriesActivity; import app.devlife.connect2sql.ui.savedqueries.SavedQueryFragment;
import dagger.Component; import dagger.Component;
@Singleton @Singleton
...@@ -22,31 +24,36 @@ import dagger.Component; ...@@ -22,31 +24,36 @@ import dagger.Component;
ConnectionModule.class, ConnectionModule.class,
DatabaseModule.class, DatabaseModule.class,
PreferencesModule.class, PreferencesModule.class,
SecurityModule.class SecurityModule.class,
ViewModelModule.class
}) })
public interface ApplicationComponent { public interface ApplicationComponent {
// application // application
void inject(Connect2SqlApplication application); void inject(Connect2SqlApplication application);
// activities // activities / fragments
void inject(BrowseFragment fragment);
void inject(ConnectionInfoEditorActivity activity); void inject(ConnectionInfoEditorActivity activity);
void inject(DashboardActivity activity); void inject(DashboardActivity activity);
void inject(HistoryFragment fragment);
void inject(HostKeysActivity activity); void inject(HostKeysActivity activity);
void inject(LaunchActivity activity); void inject(LaunchActivity activity);
void inject(QueryActivity activity); void inject(QueryActivity activity);
void inject(QueryHistoryActivity activity); void inject(QuickKeysFragment fragment);
void inject(ResultsActivity activity); void inject(ResultsActivity activity);
void inject(SetLockActivity activity); void inject(SavedQueryFragment fragment);
void inject(SavedQueriesActivity activity); void inject(SetLockActivity activity);
void inject(UnlockActivity activity); void inject(UnlockActivity activity);
}