Create android-base module

pull/87/merge
Alinson S. Xavier 8 years ago
parent 382b52e5b2
commit fc4b610d59

@ -0,0 +1 @@
/build

@ -0,0 +1,46 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'com.google.dagger:dagger:2.9'
implementation 'com.android.support:design:25.3.1'
implementation 'com.android.support:appcompat-v7:25.3.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.9'
androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:2.9'
androidTestImplementation 'com.google.dagger:dagger:2.9'
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.9'
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testImplementation 'junit:junit:4.12'
}

@ -0,0 +1,25 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /gemini-b/opt/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,2 @@
<manifest package="org.isoron.androidbase"
xmlns:android="http://schemas.android.com/apk/res/android"/>

@ -22,110 +22,31 @@ package org.isoron.androidbase;
import android.content.*; import android.content.*;
import android.os.*; import android.os.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.v4.content.*;
import android.util.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*;
import org.isoron.uhabits.core.ui.screens.habits.show.*;
import org.isoron.uhabits.core.utils.*;
import java.io.*; import java.io.*;
import java.lang.Process; import java.text.*;
import java.util.*; import java.util.*;
import javax.inject.*; import javax.inject.*;
/** public class AndroidBugReporter
* Base class for all systems class in the application.
* <p>
* Classes derived from BaseSystem are responsible for handling events and
* sending requests to the Android operating system. Examples include capturing
* a bug report, obtaining device information, or requesting runtime
* permissions.
*/
@AppScope
public class BaseSystem implements CACertSSLContextProvider,
ListHabitsBehavior.System,
ShowHabitMenuBehavior.System
{ {
private Context context; private final Context context;
@Override
public Context getContext()
{
return context;
}
@Inject @Inject
public BaseSystem(@AppContext Context context) public AndroidBugReporter(@NonNull @AppContext Context context)
{ {
this.context = context; this.context = context;
} }
@Nullable
public File getFilesDir(@Nullable String relativePath)
{
File externalFilesDirs[] = ContextCompat.getExternalFilesDirs(context, null);
if (externalFilesDirs == null)
{
Log.e("BaseSystem", "getFilesDir: getExternalFilesDirs returned null");
return null;
}
return FileUtils.getDir(externalFilesDirs, relativePath);
}
/** /**
* Captures a bug report and saves it to a file in the SD card. * Captures and returns a bug report. The bug report contains some device
* <p> * information and the logcat.
* The contents of the file are generated by the method {@link
* #getBugReport()}. The file is saved in the apps's external private
* storage.
*
* @return the generated file.
* @throws IOException when I/O errors occur.
*/
@Override
@NonNull
public void dumpBugReportToFile()
{
try
{
String date = DateFormats
.getBackupDateFormat()
.format(DateUtils.getLocalTime());
if (context == null) throw new IllegalStateException();
File dir = getFilesDir("Logs");
if (dir == null)
throw new IOException("log dir should not be null");
File logFile =
new File(String.format("%s/Log %s.txt", dir.getPath(), date));
FileWriter output = new FileWriter(logFile);
output.write(getBugReport());
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* Captures and returns a bug report.
* <p>
* The bug report contains some device information and the logcat.
* *
* @return a String containing the bug report. * @return a String containing the bug report.
* @throws IOException when any I/O error occur. * @throws IOException when any I/O error occur.
*/ */
@Override
@NonNull @NonNull
public String getBugReport() throws IOException public String getBugReport() throws IOException
{ {
@ -139,10 +60,30 @@ public class BaseSystem implements CACertSSLContextProvider,
return log; return log;
} }
@Override public String getDeviceInfo()
public File getCSVOutputDir()
{ {
return getFilesDir("CSV"); if (context == null) return "null context\n";
WindowManager wm =
(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
return
String.format("App Version Name: %s\n", BuildConfig.VERSION_NAME) +
String.format("App Version Code: %s\n", BuildConfig.VERSION_CODE) +
String.format("OS Version: %s (%s)\n",
System.getProperty("os.version"), Build.VERSION.INCREMENTAL) +
String.format("OS API Level: %s\n", Build.VERSION.SDK) +
String.format("Device: %s\n", Build.DEVICE) +
String.format("Model (Product): %s (%s)\n", Build.MODEL,
Build.PRODUCT) +
String.format("Manufacturer: %s\n", Build.MANUFACTURER) +
String.format("Other tags: %s\n", Build.TAGS) +
String.format("Screen Width: %s\n",
wm.getDefaultDisplay().getWidth()) +
String.format("Screen Height: %s\n",
wm.getDefaultDisplay().getHeight()) +
String.format("External storage state: %s\n\n",
Environment.getExternalStorageState());
} }
public String getLogcat() throws IOException public String getLogcat() throws IOException
@ -151,7 +92,7 @@ public class BaseSystem implements CACertSSLContextProvider,
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
String[] command = new String[]{ "logcat", "-d" }; String[] command = new String[]{ "logcat", "-d" };
Process process = Runtime.getRuntime().exec(command); java.lang.Process process = Runtime.getRuntime().exec(command);
InputStreamReader in = new InputStreamReader(process.getInputStream()); InputStreamReader in = new InputStreamReader(process.getInputStream());
BufferedReader bufferedReader = new BufferedReader(in); BufferedReader bufferedReader = new BufferedReader(in);
@ -174,29 +115,41 @@ public class BaseSystem implements CACertSSLContextProvider,
return builder.toString(); return builder.toString();
} }
private String getDeviceInfo() /**
* Captures a bug report and saves it to a file in the SD card.
* <p>
* The contents of the file are generated by the method {@link
* #getBugReport()}. The file is saved in the apps's external private
* storage.
*
* @return the generated file.
* @throws IOException when I/O errors occur.
*/
@NonNull
public void dumpBugReportToFile()
{
try
{ {
if (context == null) return "null context\n";
WindowManager wm = String date =
(WindowManager) context.getSystemService(Context.WINDOW_SERVICE); new SimpleDateFormat("yyyy-MM-dd HHmmss", Locale.US).format(
new Date());
return if (context == null) throw new IllegalStateException();
String.format("App Version Name: %s\n", BuildConfig.VERSION_NAME) +
String.format("App Version Code: %s\n", BuildConfig.VERSION_CODE) + File dir = new AndroidDirFinder(context).getFilesDir("Logs");
String.format("OS Version: %s (%s)\n", if (dir == null)
System.getProperty("os.version"), Build.VERSION.INCREMENTAL) + throw new IOException("log dir should not be null");
String.format("OS API Level: %s\n", Build.VERSION.SDK) +
String.format("Device: %s\n", Build.DEVICE) + File logFile =
String.format("Model (Product): %s (%s)\n", Build.MODEL, new File(String.format("%s/Log %s.txt", dir.getPath(), date));
Build.PRODUCT) + FileWriter output = new FileWriter(logFile);
String.format("Manufacturer: %s\n", Build.MANUFACTURER) + output.write(getBugReport());
String.format("Other tags: %s\n", Build.TAGS) + output.close();
String.format("Screen Width: %s\n", }
wm.getDefaultDisplay().getWidth()) + catch (IOException e)
String.format("Screen Height: %s\n", {
wm.getDefaultDisplay().getHeight()) + e.printStackTrace();
String.format("External storage state: %s\n\n", }
Environment.getExternalStorageState());
} }
} }

@ -0,0 +1,58 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.androidbase;
import android.content.*;
import android.support.annotation.*;
import android.support.v4.content.*;
import android.util.*;
import org.isoron.androidbase.utils.*;
import java.io.*;
import javax.inject.*;
public class AndroidDirFinder
{
@NonNull
private Context context;
@Inject
public AndroidDirFinder(@NonNull @AppContext Context context)
{
this.context = context;
}
@Nullable
public File getFilesDir(@Nullable String relativePath)
{
File externalFilesDirs[] =
ContextCompat.getExternalFilesDirs(context, null);
if (externalFilesDirs == null)
{
Log.e("BaseSystem",
"getFilesDir: getExternalFilesDirs returned null");
return null;
}
return FileUtils.getDir(externalFilesDirs, relativePath);
}
}

@ -24,11 +24,11 @@ import android.content.*;
import dagger.*; import dagger.*;
@Module @Module
public class AppModule public class AppContextModule
{ {
private final Context context; private final Context context;
public AppModule(@AppContext Context context) public AppContextModule(@AppContext Context context)
{ {
this.context = context; this.context = context;
} }

@ -17,14 +17,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.androidbase.activities; package org.isoron.androidbase;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.models.sqlite.*;
public class BaseExceptionHandler implements Thread.UncaughtExceptionHandler public class BaseExceptionHandler implements Thread.UncaughtExceptionHandler
{ {
@ -49,20 +46,20 @@ public class BaseExceptionHandler implements Thread.UncaughtExceptionHandler
try try
{ {
ex.printStackTrace(); ex.printStackTrace();
new BaseSystem(activity).dumpBugReportToFile(); new AndroidBugReporter(activity).dumpBugReportToFile();
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
if (ex.getCause() instanceof InconsistentDatabaseException) // if (ex.getCause() instanceof InconsistentDatabaseException)
{ // {
HabitsApplication app = (HabitsApplication) activity.getApplication(); // HabitsApplication app = (HabitsApplication) activity.getApplication();
HabitList habits = app.getComponent().getHabitList(); // HabitList habits = app.getComponent().getHabitList();
habits.repair(); // habits.repair();
System.exit(0); // System.exit(0);
} // }
if (originalHandler != null) if (originalHandler != null)
originalHandler.uncaughtException(thread, ex); originalHandler.uncaughtException(thread, ex);

@ -20,22 +20,34 @@
package org.isoron.androidbase; package org.isoron.androidbase;
import android.content.*; import android.content.*;
import android.support.annotation.*;
import org.isoron.androidbase.*;
import java.io.*; import java.io.*;
import java.security.*; import java.security.*;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.*; import java.security.cert.*;
import javax.inject.*;
import javax.net.ssl.*; import javax.net.ssl.*;
public interface CACertSSLContextProvider public class SSLContextProvider
{ {
default SSLContext getCACertSSLContext() private Context context;
@Inject
public SSLContextProvider(@NonNull @AppContext Context context)
{
this.context = context;
}
public SSLContext getCACertSSLContext()
{ {
try try
{ {
CertificateFactory cf = CertificateFactory.getInstance("X.509"); CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getContext().getAssets().open("cacert.pem"); InputStream caInput = context.getAssets().open("cacert.pem");
Certificate ca = cf.generateCertificate(caInput); Certificate ca = cf.generateCertificate(caInput);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
@ -56,6 +68,4 @@ public interface CACertSSLContextProvider
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
Context getContext();
} }

@ -21,9 +21,6 @@ package org.isoron.androidbase.activities;
import android.content.*; import android.content.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.core.ui.*;
import dagger.*; import dagger.*;
@Module @Module
@ -48,11 +45,4 @@ public class ActivityModule
{ {
return activity; return activity;
} }
@Provides
@ActivityScope
public static ThemeSwitcher getThemeSwitcher(AndroidThemeSwitcher t)
{
return t;
}
} }

@ -25,8 +25,7 @@ import android.support.annotation.*;
import android.support.v7.app.*; import android.support.v7.app.*;
import android.view.*; import android.view.*;
import org.isoron.uhabits.*; import org.isoron.androidbase.*;
import org.isoron.uhabits.activities.*;
import static android.R.anim.fade_in; import static android.R.anim.fade_in;
import static android.R.anim.fade_out; import static android.R.anim.fade_out;
@ -53,13 +52,6 @@ abstract public class BaseActivity extends AppCompatActivity
@Nullable @Nullable
private BaseScreen screen; private BaseScreen screen;
private ActivityComponent component;
public ActivityComponent getComponent()
{
return component;
}
@Override @Override
public boolean onCreateOptionsMenu(@Nullable Menu menu) public boolean onCreateOptionsMenu(@Nullable Menu menu)
{ {
@ -120,16 +112,6 @@ abstract public class BaseActivity extends AppCompatActivity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(getExceptionHandler()); Thread.setDefaultUncaughtExceptionHandler(getExceptionHandler());
HabitsApplication app = (HabitsApplication) getApplicationContext();
component = DaggerActivityComponent
.builder()
.activityModule(new ActivityModule(this))
.habitsComponent(app.getComponent())
.build();
component.getThemeSwitcher().apply();
} }
protected Thread.UncaughtExceptionHandler getExceptionHandler() protected Thread.UncaughtExceptionHandler getExceptionHandler()

@ -22,8 +22,6 @@ package org.isoron.androidbase.activities;
import android.support.annotation.*; import android.support.annotation.*;
import android.view.*; import android.view.*;
import javax.annotation.*;
/** /**
* Base class for all the menus in the application. * Base class for all the menus in the application.
* <p> * <p>
@ -76,8 +74,7 @@ public abstract class BaseMenu
* @param inflater a menu inflater, for creating the menu * @param inflater a menu inflater, for creating the menu
* @param menu the menu that is being created. * @param menu the menu that is being created.
*/ */
public void onCreate(@NonNull MenuInflater inflater, public void onCreate(@NonNull MenuInflater inflater, @NonNull Menu menu)
@NonNull Menu menu)
{ {
menu.clear(); menu.clear();
inflater.inflate(getMenuResourceId(), menu); inflater.inflate(getMenuResourceId(), menu);
@ -100,6 +97,6 @@ public abstract class BaseMenu
* *
* @return id of the menu resource. * @return id of the menu resource.
*/ */
@Resource @MenuRes
protected abstract int getMenuResourceId(); protected abstract int getMenuResourceId();
} }

@ -21,17 +21,15 @@ package org.isoron.androidbase.activities;
import android.content.*; import android.content.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.v4.content.res.*;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import org.isoron.uhabits.*; import org.isoron.androidbase.*;
import org.isoron.uhabits.core.ui.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.utils.*;
import static android.os.Build.VERSION.*; import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.*; import static android.os.Build.VERSION_CODES.LOLLIPOP;
/** /**
* Base class for all root views in the application. * Base class for all root views in the application.
@ -46,16 +44,12 @@ public abstract class BaseRootView extends FrameLayout
@NonNull @NonNull
private final Context context; private final Context context;
private final ThemeSwitcher themeSwitcher; protected boolean shouldDisplayHomeAsUp = false;
boolean shouldDisplayHomeAsUp = false;
public BaseRootView(@NonNull Context context) public BaseRootView(@NonNull Context context)
{ {
super(context); super(context);
this.context = context; this.context = context;
BaseActivity activity = (BaseActivity) context;
themeSwitcher = activity.getComponent().getThemeSwitcher();
} }
public boolean getDisplayHomeAsUp() public boolean getDisplayHomeAsUp()
@ -80,12 +74,6 @@ public abstract class BaseRootView extends FrameLayout
public int getToolbarColor() public int getToolbarColor()
{ {
if (SDK_INT < LOLLIPOP && !themeSwitcher.isNightMode())
{
return ResourcesCompat.getColor(context.getResources(),
R.color.grey_900, context.getTheme());
}
StyledResources res = new StyledResources(context); StyledResources res = new StyledResources(context);
return res.getColor(R.attr.colorPrimary); return res.getColor(R.attr.colorPrimary);
} }

@ -24,10 +24,8 @@ import android.graphics.*;
import android.graphics.drawable.*; import android.graphics.drawable.*;
import android.net.*; import android.net.*;
import android.os.*; import android.os.*;
import android.provider.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.design.widget.*; import android.support.design.widget.*;
import android.support.v4.app.*;
import android.support.v4.content.res.*; import android.support.v4.content.res.*;
import android.support.v7.app.*; import android.support.v7.app.*;
import android.support.v7.view.ActionMode; import android.support.v7.view.ActionMode;
@ -35,22 +33,14 @@ import android.support.v7.widget.Toolbar;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import org.isoron.uhabits.*; import org.isoron.androidbase.*;
import org.isoron.uhabits.notifications.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.utils.*;
import java.io.*; import java.io.*;
import static android.media.RingtoneManager.ACTION_RINGTONE_PICKER; import static android.os.Build.VERSION.SDK_INT;
import static android.media.RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI; import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.media.RingtoneManager.EXTRA_RINGTONE_EXISTING_URI; import static android.support.v4.content.FileProvider.getUriForFile;
import static android.media.RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT;
import static android.media.RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT;
import static android.media.RingtoneManager.EXTRA_RINGTONE_TYPE;
import static android.media.RingtoneManager.TYPE_NOTIFICATION;
import static android.os.Build.VERSION.*;
import static android.os.Build.VERSION_CODES.*;
import static android.support.v4.content.FileProvider.*;
/** /**
* Base class for all screens in the application. * Base class for all screens in the application.
@ -61,8 +51,6 @@ import static android.support.v4.content.FileProvider.*;
*/ */
public class BaseScreen public class BaseScreen
{ {
public static final int REQUEST_CREATE_DOCUMENT = 1;
protected BaseActivity activity; protected BaseActivity activity;
@Nullable @Nullable
@ -78,6 +66,21 @@ public class BaseScreen
this.activity = activity; this.activity = activity;
} }
@Deprecated
public static int getDefaultActionBarColor(Context context)
{
if (SDK_INT < LOLLIPOP)
{
return ResourcesCompat.getColor(context.getResources(),
R.color.grey_900, context.getTheme());
}
else
{
StyledResources res = new StyledResources(context);
return res.getColor(R.attr.colorPrimary);
}
}
@Deprecated @Deprecated
public static void setupActionBarColor(@NonNull AppCompatActivity activity, public static void setupActionBarColor(@NonNull AppCompatActivity activity,
int color) int color)
@ -93,7 +96,6 @@ public class BaseScreen
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
ColorDrawable drawable = new ColorDrawable(color); ColorDrawable drawable = new ColorDrawable(color);
actionBar.setBackgroundDrawable(drawable); actionBar.setBackgroundDrawable(drawable);
@ -112,36 +114,6 @@ public class BaseScreen
} }
} }
@Deprecated
public static int getDefaultActionBarColor(Context context)
{
if (SDK_INT < LOLLIPOP)
{
return ResourcesCompat.getColor(context.getResources(),
R.color.grey_900, context.getTheme());
}
else
{
StyledResources res = new StyledResources(context);
return res.getColor(R.attr.colorPrimary);
}
}
public static void showRingtonePicker(Fragment fragment,
int requestCode)
{
Uri existingRingtoneUri = RingtoneManager.getRingtoneUri(fragment.getContext());
Uri defaultRingtoneUri = Settings.System.DEFAULT_NOTIFICATION_URI;
Intent intent = new Intent(ACTION_RINGTONE_PICKER);
intent.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
intent.putExtra(EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true);
intent.putExtra(EXTRA_RINGTONE_DEFAULT_URI, defaultRingtoneUri);
intent.putExtra(EXTRA_RINGTONE_EXISTING_URI, existingRingtoneUri);
fragment.startActivityForResult(intent, requestCode);
}
/** /**
* Notifies the screen that its contents should be updated. * Notifies the screen that its contents should be updated.
*/ */
@ -155,7 +127,8 @@ public class BaseScreen
{ {
if (rootView == null) return; if (rootView == null) return;
activity.runOnUiThread(() -> { activity.runOnUiThread(() ->
{
Toolbar toolbar = rootView.getToolbar(); Toolbar toolbar = rootView.getToolbar();
activity.setSupportActionBar(toolbar); activity.setSupportActionBar(toolbar);
ActionBar actionBar = activity.getSupportActionBar(); ActionBar actionBar = activity.getSupportActionBar();

@ -17,71 +17,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.utils; package org.isoron.androidbase.utils;
import android.content.*;
import android.graphics.*; import android.graphics.*;
import android.util.*;
public abstract class ColorUtils public abstract class ColorUtils
{ {
public static int colorToPaletteIndex(Context context, int color)
{
StyledResources res = new StyledResources(context);
int[] palette = res.getPalette();
for (int k = 0; k < palette.length; k++)
if (palette[k] == color) return k;
return -1;
}
public static int getAndroidTestColor(int index)
{
int palette[] = {
Color.parseColor("#D32F2F"), // 0 red
Color.parseColor("#E64A19"), // 1 deep orange
Color.parseColor("#F57C00"), // 2 orange
Color.parseColor("#FF8F00"), // 3 amber
Color.parseColor("#F9A825"), // 4 yellow
Color.parseColor("#AFB42B"), // 5 lime
Color.parseColor("#7CB342"), // 6 light green
Color.parseColor("#388E3C"), // 7 green
Color.parseColor("#00897B"), // 8 teal
Color.parseColor("#00ACC1"), // 9 cyan
Color.parseColor("#039BE5"), // 10 light blue
Color.parseColor("#1976D2"), // 11 blue
Color.parseColor("#303F9F"), // 12 indigo
Color.parseColor("#5E35B1"), // 13 deep purple
Color.parseColor("#8E24AA"), // 14 purple
Color.parseColor("#D81B60"), // 15 pink
Color.parseColor("#5D4037"), // 16 brown
Color.parseColor("#303030"), // 17 dark grey
Color.parseColor("#757575"), // 18 grey
Color.parseColor("#aaaaaa") // 19 light grey
};
return palette[index];
}
public static int getColor(Context context, int paletteColor)
{
if (context == null)
throw new IllegalArgumentException("Context is null");
StyledResources res = new StyledResources(context);
int palette[] = res.getPalette();
if (paletteColor < 0 || paletteColor >= palette.length)
{
Log.w("ColorHelper",
String.format("Invalid color: %d. Returning default.",
paletteColor));
paletteColor = 0;
}
return palette[paletteColor];
}
public static int mixColors(int color1, int color2, float amount) public static int mixColors(int color1, int color2, float amount)
{ {
final byte ALPHA_CHANNEL = 24; final byte ALPHA_CHANNEL = 24;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.utils; package org.isoron.androidbase.utils;
import android.content.*; import android.content.*;
import android.content.res.*; import android.content.res.*;

@ -17,14 +17,14 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.utils; package org.isoron.androidbase.utils;
import android.content.*; import android.content.*;
import android.content.res.*; import android.content.res.*;
import android.graphics.drawable.*; import android.graphics.drawable.*;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.uhabits.*; import org.isoron.androidbase.*;
public class StyledResources public class StyledResources
{ {

@ -0,0 +1,6 @@
<resources>
<item name="toolbar" type="id" />
<item name="toolbarShadow" type="id" />
<item name="headerShadow" type="id" />
<attr name="palette" format="reference"/>
</resources>

@ -0,0 +1,300 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="red_50">#FFEBEE</color>
<color name="red_100">#FFCDD2</color>
<color name="red_200">#EF9A9A</color>
<color name="red_300">#E57373</color>
<color name="red_400">#EF5350</color>
<color name="red_500">#F44336</color>
<color name="red_600">#E53935</color>
<color name="red_700">#D32F2F</color>
<color name="red_800">#C62828</color>
<color name="red_900">#B71C1C</color>
<color name="red_A100">#FF8A80</color>
<color name="red_A200">#FF5252</color>
<color name="red_A400">#FF1744</color>
<color name="red_A700">#D50000</color>
<color name="deep_purple_50">#EDE7F6</color>
<color name="deep_purple_100">#D1C4E9</color>
<color name="deep_purple_200">#B39DDB</color>
<color name="deep_purple_300">#9575CD</color>
<color name="deep_purple_400">#7E57C2</color>
<color name="deep_purple_500">#673AB7</color>
<color name="deep_purple_600">#5E35B1</color>
<color name="deep_purple_700">#512DA8</color>
<color name="deep_purple_800">#4527A0</color>
<color name="deep_purple_900">#311B92</color>
<color name="deep_purple_A100">#B388FF</color>
<color name="deep_purple_A200">#7C4DFF</color>
<color name="deep_purple_A400">#651FFF</color>
<color name="deep_purple_A700">#6200EA</color>
<color name="light_blue_50">#E1F5FE</color>
<color name="light_blue_100">#B3E5FC</color>
<color name="light_blue_200">#81D4FA</color>
<color name="light_blue_300">#4FC3F7</color>
<color name="light_blue_400">#29B6F6</color>
<color name="light_blue_500">#03A9F4</color>
<color name="light_blue_600">#039BE5</color>
<color name="light_blue_700">#0288D1</color>
<color name="light_blue_800">#0277BD</color>
<color name="light_blue_900">#01579B</color>
<color name="light_blue_A100">#80D8FF</color>
<color name="light_blue_A200">#40C4FF</color>
<color name="light_blue_A400">#00B0FF</color>
<color name="light_blue_A700">#0091EA</color>
<color name="green_50">#E8F5E9</color>
<color name="green_100">#C8E6C9</color>
<color name="green_200">#A5D6A7</color>
<color name="green_300">#81C784</color>
<color name="green_400">#66BB6A</color>
<color name="green_500">#4CAF50</color>
<color name="green_600">#43A047</color>
<color name="green_700">#388E3C</color>
<color name="green_800">#2E7D32</color>
<color name="green_900">#1B5E20</color>
<color name="green_A100">#B9F6CA</color>
<color name="green_A200">#69F0AE</color>
<color name="green_A400">#00E676</color>
<color name="green_A700">#00C853</color>
<color name="yellow_50">#FFFDE7</color>
<color name="yellow_100">#FFF9C4</color>
<color name="yellow_200">#FFF59D</color>
<color name="yellow_300">#FFF176</color>
<color name="yellow_400">#FFEE58</color>
<color name="yellow_500">#FFEB3B</color>
<color name="yellow_600">#FDD835</color>
<color name="yellow_700">#FBC02D</color>
<color name="yellow_800">#F9A825</color>
<color name="yellow_900">#F57F17</color>
<color name="yellow_A100">#FFFF8D</color>
<color name="yellow_A200">#FFFF00</color>
<color name="yellow_A400">#FFEA00</color>
<color name="yellow_A700">#FFD600</color>
<color name="deep_orange_50">#FBE9E7</color>
<color name="deep_orange_100">#FFCCBC</color>
<color name="deep_orange_200">#FFAB91</color>
<color name="deep_orange_300">#FF8A65</color>
<color name="deep_orange_400">#FF7043</color>
<color name="deep_orange_500">#FF5722</color>
<color name="deep_orange_600">#F4511E</color>
<color name="deep_orange_700">#E64A19</color>
<color name="deep_orange_800">#D84315</color>
<color name="deep_orange_900">#BF360C</color>
<color name="deep_orange_A100">#FF9E80</color>
<color name="deep_orange_A200">#FF6E40</color>
<color name="deep_orange_A400">#FF3D00</color>
<color name="deep_orange_A700">#DD2C00</color>
<color name="blue_grey_50">#ECEFF1</color>
<color name="blue_grey_100">#CFD8DC</color>
<color name="blue_grey_200">#B0BEC5</color>
<color name="blue_grey_300">#90A4AE</color>
<color name="blue_grey_400">#78909C</color>
<color name="blue_grey_500">#607D8B</color>
<color name="blue_grey_600">#546E7A</color>
<color name="blue_grey_700">#455A64</color>
<color name="blue_grey_800">#37474F</color>
<color name="blue_grey_900">#263238</color>
<color name="pink_50">#FCE4EC</color>
<color name="pink_100">#F8BBD0</color>
<color name="pink_200">#F48FB1</color>
<color name="pink_300">#F06292</color>
<color name="pink_400">#EC407A</color>
<color name="pink_500">#E91E63</color>
<color name="pink_600">#D81B60</color>
<color name="pink_700">#C2185B</color>
<color name="pink_800">#AD1457</color>
<color name="pink_900">#880E4F</color>
<color name="pink_A100">#FF80AB</color>
<color name="pink_A200">#FF4081</color>
<color name="pink_A400">#F50057</color>
<color name="pink_A700">#C51162</color>
<color name="indigo_50">#E8EAF6</color>
<color name="indigo_100">#C5CAE9</color>
<color name="indigo_200">#9FA8DA</color>
<color name="indigo_300">#7986CB</color>
<color name="indigo_400">#5C6BC0</color>
<color name="indigo_500">#3F51B5</color>
<color name="indigo_600">#3949AB</color>
<color name="indigo_700">#303F9F</color>
<color name="indigo_800">#283593</color>
<color name="indigo_900">#1A237E</color>
<color name="indigo_A100">#8C9EFF</color>
<color name="indigo_A200">#536DFE</color>
<color name="indigo_A400">#3D5AFE</color>
<color name="indigo_A700">#304FFE</color>
<color name="cyan_50">#E0F7FA</color>
<color name="cyan_100">#B2EBF2</color>
<color name="cyan_200">#80DEEA</color>
<color name="cyan_300">#4DD0E1</color>
<color name="cyan_400">#26C6DA</color>
<color name="cyan_500">#00BCD4</color>
<color name="cyan_600">#00ACC1</color>
<color name="cyan_700">#0097A7</color>
<color name="cyan_800">#00838F</color>
<color name="cyan_900">#006064</color>
<color name="cyan_A100">#84FFFF</color>
<color name="cyan_A200">#18FFFF</color>
<color name="cyan_A400">#00E5FF</color>
<color name="cyan_A700">#00B8D4</color>
<color name="light_green_50">#F1F8E9</color>
<color name="light_green_100">#DCEDC8</color>
<color name="light_green_200">#C5E1A5</color>
<color name="light_green_300">#AED581</color>
<color name="light_green_400">#9CCC65</color>
<color name="light_green_500">#8BC34A</color>
<color name="light_green_600">#7CB342</color>
<color name="light_green_700">#689F38</color>
<color name="light_green_800">#558B2F</color>
<color name="light_green_900">#33691E</color>
<color name="light_green_A100">#CCFF90</color>
<color name="light_green_A200">#B2FF59</color>
<color name="light_green_A400">#76FF03</color>
<color name="light_green_A700">#64DD17</color>
<color name="amber_50">#FFF8E1</color>
<color name="amber_100">#FFECB3</color>
<color name="amber_200">#FFE082</color>
<color name="amber_300">#FFD54F</color>
<color name="amber_400">#FFCA28</color>
<color name="amber_500">#FFC107</color>
<color name="amber_600">#FFB300</color>
<color name="amber_700">#FFA000</color>
<color name="amber_800">#FF8F00</color>
<color name="amber_900">#FF6F00</color>
<color name="amber_A100">#FFE57F</color>
<color name="amber_A200">#FFD740</color>
<color name="amber_A400">#FFC400</color>
<color name="amber_A700">#FFAB00</color>
<color name="brown_50">#EFEBE9</color>
<color name="brown_100">#D7CCC8</color>
<color name="brown_200">#BCAAA4</color>
<color name="brown_300">#A1887F</color>
<color name="brown_400">#8D6E63</color>
<color name="brown_500">#795548</color>
<color name="brown_600">#6D4C41</color>
<color name="brown_700">#5D4037</color>
<color name="brown_800">#4E342E</color>
<color name="brown_900">#3E2723</color>
<color name="purple_50">#F3E5F5</color>
<color name="purple_100">#E1BEE7</color>
<color name="purple_200">#CE93D8</color>
<color name="purple_300">#BA68C8</color>
<color name="purple_400">#AB47BC</color>
<color name="purple_500">#9C27B0</color>
<color name="purple_600">#8E24AA</color>
<color name="purple_700">#7B1FA2</color>
<color name="purple_800">#6A1B9A</color>
<color name="purple_900">#4A148C</color>
<color name="purple_A100">#EA80FC</color>
<color name="purple_A200">#E040FB</color>
<color name="purple_A400">#D500F9</color>
<color name="purple_A700">#AA00FF</color>
<color name="blue_50">#E3F2FD</color>
<color name="blue_100">#BBDEFB</color>
<color name="blue_200">#90CAF9</color>
<color name="blue_300">#64B5F6</color>
<color name="blue_400">#42A5F5</color>
<color name="blue_500">#2196F3</color>
<color name="blue_600">#1E88E5</color>
<color name="blue_700">#1976D2</color>
<color name="blue_800">#1565C0</color>
<color name="blue_900">#0D47A1</color>
<color name="blue_A100">#82B1FF</color>
<color name="blue_A200">#448AFF</color>
<color name="blue_A400">#2979FF</color>
<color name="blue_A700">#2962FF</color>
<color name="teal_50">#E0F2F1</color>
<color name="teal_100">#B2DFDB</color>
<color name="teal_200">#80CBC4</color>
<color name="teal_300">#4DB6AC</color>
<color name="teal_400">#26A69A</color>
<color name="teal_500">#009688</color>
<color name="teal_600">#00897B</color>
<color name="teal_700">#00796B</color>
<color name="teal_800">#00695C</color>
<color name="teal_900">#004D40</color>
<color name="teal_A100">#A7FFEB</color>
<color name="teal_A200">#64FFDA</color>
<color name="teal_A400">#1DE9B6</color>
<color name="teal_A700">#00BFA5</color>
<color name="lime_50">#F9FBE7</color>
<color name="lime_100">#F0F4C3</color>
<color name="lime_200">#E6EE9C</color>
<color name="lime_300">#DCE775</color>
<color name="lime_400">#D4E157</color>
<color name="lime_500">#CDDC39</color>
<color name="lime_600">#C0CA33</color>
<color name="lime_700">#AFB42B</color>
<color name="lime_800">#9E9D24</color>
<color name="lime_900">#827717</color>
<color name="lime_A100">#F4FF81</color>
<color name="lime_A200">#EEFF41</color>
<color name="lime_A400">#C6FF00</color>
<color name="lime_A700">#AEEA00</color>
<color name="orange_50">#FFF3E0</color>
<color name="orange_100">#FFE0B2</color>
<color name="orange_200">#FFCC80</color>
<color name="orange_300">#FFB74D</color>
<color name="orange_400">#FFA726</color>
<color name="orange_500">#FF9800</color>
<color name="orange_600">#FB8C00</color>
<color name="orange_700">#F57C00</color>
<color name="orange_800">#EF6C00</color>
<color name="orange_900">#E65100</color>
<color name="orange_A100">#FFD180</color>
<color name="orange_A200">#FFAB40</color>
<color name="orange_A400">#FF9100</color>
<color name="orange_A700">#FF6D00</color>
<color name="grey_50">#FAFAFA</color>
<color name="grey_100">#F5F5F5</color>
<color name="grey_200">#EEEEEE</color>
<color name="grey_300">#E0E0E0</color>
<color name="grey_400">#BDBDBD</color>
<color name="grey_500">#9E9E9E</color>
<color name="grey_600">#757575</color>
<color name="grey_700">#616161</color>
<color name="grey_750">#525252</color>
<color name="grey_800">#424242</color>
<color name="grey_850">#303030</color>
<color name="grey_875">#282828</color>
<color name="grey_900">#212121</color>
<color name="grey_950">#101010</color>
<color name="white">#ffffff</color>
<color name="black">#000000</color>
<color name="black_ae">#ef000000</color>
<color name="black_ac">#cf000000</color>
<color name="black_aa">#af000000</color>
<color name="black_a8">#8f000000</color>
<color name="black_a6">#6f000000</color>
<color name="black_a4">#4f000000</color>
<color name="black_a2">#2f000000</color>
<color name="black_a0">#0f000000</color>
<color name="white_ae">#efffffff</color>
<color name="white_ac">#cfffffff</color>
<color name="white_aa">#afffffff</color>
<color name="white_a8">#8fffffff</color>
<color name="white_a6">#6fffffff</color>
<color name="white_a4">#4fffffff</color>
<color name="white_a2">#2fffffff</color>
<color name="white_a0">#0fffffff</color>
</resources>

@ -1 +1 @@
include ':uhabits-android', ':uhabits-core' include ':uhabits-android', ':uhabits-core', ':android-base'

@ -53,6 +53,8 @@ android {
dependencies { dependencies {
implementation project(":uhabits-core") implementation project(":uhabits-core")
implementation project(":android-base")
implementation 'com.android.support:appcompat-v7:25.3.1' implementation 'com.android.support:appcompat-v7:25.3.1'
implementation 'com.android.support:design:25.3.1' implementation 'com.android.support:design:25.3.1'
implementation 'com.android.support:preference-v14:25.3.1' implementation 'com.android.support:preference-v14:25.3.1'

@ -1,5 +0,0 @@
#!/bin/bash
P=/sdcard/Android/data/org.isoron.uhabits/cache/Failed/
adb pull $P Failed/
adb shell rm -r $P

@ -29,12 +29,12 @@ import dagger.*;
@AppScope @AppScope
@Component(modules = { @Component(modules = {
AppModule.class, AppContextModule.class,
HabitsModule.class, HabitsModule.class,
SingleThreadModule.class, SingleThreadModule.class,
SQLModelFactory.class SQLModelFactory.class
}) })
public interface AndroidTestComponent extends HabitsComponent public interface AndroidTestComponent extends HabitsApplicationComponent
{ {
} }

@ -31,11 +31,11 @@ import android.util.*;
import junit.framework.*; import junit.framework.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.tasks.*; import org.isoron.uhabits.core.tasks.*;
import org.isoron.uhabits.core.utils.*; import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*;
import org.junit.*; import org.junit.*;
import java.io.*; import java.io.*;
@ -71,8 +71,6 @@ public class BaseAndroidTest extends TestCase
protected ModelFactory modelFactory; protected ModelFactory modelFactory;
protected BaseSystem baseSystem;
@Override @Override
@Before @Before
public void setUp() public void setUp()
@ -89,11 +87,9 @@ public class BaseAndroidTest extends TestCase
component = DaggerAndroidTestComponent component = DaggerAndroidTestComponent
.builder() .builder()
.appModule(new AppModule(targetContext.getApplicationContext())) .appContextModule(new AppContextModule(targetContext.getApplicationContext()))
.build(); .build();
baseSystem = new BaseSystem(targetContext);
HabitsApplication.setComponent(component); HabitsApplication.setComponent(component);
prefs = component.getPreferences(); prefs = component.getPreferences();
habitList = component.getHabitList(); habitList = component.getHabitList();
@ -168,7 +164,7 @@ public class BaseAndroidTest extends TestCase
protected void startTracing() protected void startTracing()
{ {
File dir = baseSystem.getFilesDir("Profile"); File dir = new AndroidDirFinder(targetContext).getFilesDir("Profile");
assertNotNull(dir); assertNotNull(dir);
String tracePath = dir.getAbsolutePath() + "/performance.trace"; String tracePath = dir.getAbsolutePath() + "/performance.trace";
Log.d("PerformanceTest", String.format("Saving trace file to %s", tracePath)); Log.d("PerformanceTest", String.format("Saving trace file to %s", tracePath));

@ -40,7 +40,7 @@ public class BaseUserInterfaceTest
public static UiDevice device; public static UiDevice device;
private HabitsComponent component; private HabitsApplicationComponent component;
private HabitList habitList; private HabitList habitList;

@ -24,8 +24,8 @@ import android.support.annotation.*;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import org.isoron.androidbase.*;
import org.isoron.androidbase.utils.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.widgets.*; import org.isoron.uhabits.widgets.*;
import java.io.*; import java.io.*;
@ -170,7 +170,7 @@ public class BaseViewTest extends BaseAndroidTest
{ {
File dir = FileUtils.getSDCardDir("test-screenshots"); File dir = FileUtils.getSDCardDir("test-screenshots");
if (dir == null) if (dir == null)
dir = baseSystem.getFilesDir("test-screenshots"); dir = new AndroidDirFinder(targetContext).getFilesDir("test-screenshots");
if (dir == null) throw new RuntimeException( if (dir == null) throw new RuntimeException(
"Could not find suitable dir for screenshots"); "Could not find suitable dir for screenshots");

@ -54,8 +54,7 @@ public class HabitLoggerTest extends BaseAndroidTest
protected void assertLogcatContains(String expectedMsg) throws IOException protected void assertLogcatContains(String expectedMsg) throws IOException
{ {
BaseSystem system = new BaseSystem(targetContext); String logcat = new AndroidBugReporter(targetContext).getLogcat();
String logcat = system.getLogcat();
assertThat(logcat, containsString(expectedMsg)); assertThat(logcat, containsString(expectedMsg));
} }

@ -41,8 +41,7 @@ public class HabitsApplicationTest extends BaseAndroidTest
String msg = "LOGCAT TEST"; String msg = "LOGCAT TEST";
new RuntimeException(msg).printStackTrace(); new RuntimeException(msg).printStackTrace();
BaseSystem system = new BaseSystem(targetContext); String log = new AndroidBugReporter(targetContext).getLogcat();
String log = system.getLogcat();
assertThat(log, containsString(msg)); assertThat(log, containsString(msg));
} }
} }

@ -48,7 +48,7 @@ public class BarChartTest extends BaseViewTest
long day = DateUtils.millisecondsInOneDay; long day = DateUtils.millisecondsInOneDay;
CheckmarkList checkmarks = habit.getCheckmarks(); CheckmarkList checkmarks = habit.getCheckmarks();
view.setCheckmarks(checkmarks.getByInterval(today - 20 * day, today)); view.setCheckmarks(checkmarks.getByInterval(today - 20 * day, today));
view.setColor(ColorUtils.getColor(targetContext, habit.getColor())); view.setColor(PaletteUtils.getColor(targetContext, habit.getColor()));
view.setTarget(200.0); view.setTarget(200.0);
measureView(view, dpToPixels(300), dpToPixels(200)); measureView(view, dpToPixels(300), dpToPixels(200));
} }

@ -47,7 +47,7 @@ public class FrequencyChartTest extends BaseViewTest
view = new FrequencyChart(targetContext); view = new FrequencyChart(targetContext);
view.setFrequency(habit.getRepetitions().getWeekdayFrequency()); view.setFrequency(habit.getRepetitions().getWeekdayFrequency());
view.setColor(ColorUtils.getAndroidTestColor(habit.getColor())); view.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
measureView(view, dpToPixels(300), dpToPixels(100)); measureView(view, dpToPixels(300), dpToPixels(100));
} }

@ -47,7 +47,7 @@ public class HistoryChartTest extends BaseViewTest
chart = new HistoryChart(targetContext); chart = new HistoryChart(targetContext);
chart.setCheckmarks(habit.getCheckmarks().getAllValues()); chart.setCheckmarks(habit.getCheckmarks().getAllValues());
chart.setColor(ColorUtils.getAndroidTestColor(habit.getColor())); chart.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
measureView(chart, dpToPixels(400), dpToPixels(200)); measureView(chart, dpToPixels(400), dpToPixels(200));
} }

@ -47,7 +47,7 @@ public class RingViewTest extends BaseViewTest
view = new RingView(targetContext); view = new RingView(targetContext);
view.setPercentage(0.6f); view.setPercentage(0.6f);
view.setText("60%"); view.setText("60%");
view.setColor(ColorUtils.getAndroidTestColor(0)); view.setColor(PaletteUtils.getAndroidTestColor(0));
view.setBackgroundColor(Color.WHITE); view.setBackgroundColor(Color.WHITE);
view.setThickness(dpToPixels(3)); view.setThickness(dpToPixels(3));
} }
@ -63,7 +63,7 @@ public class RingViewTest extends BaseViewTest
public void testRender_withDifferentParams() throws IOException public void testRender_withDifferentParams() throws IOException
{ {
view.setPercentage(0.25f); view.setPercentage(0.25f);
view.setColor(ColorUtils.getAndroidTestColor(5)); view.setColor(PaletteUtils.getAndroidTestColor(5));
measureView(view, dpToPixels(200), dpToPixels(200)); measureView(view, dpToPixels(200), dpToPixels(200));
assertRenders(view, BASE_PATH + "renderDifferentParams.png"); assertRenders(view, BASE_PATH + "renderDifferentParams.png");

@ -50,7 +50,7 @@ public class ScoreChartTest extends BaseViewTest
view = new ScoreChart(targetContext); view = new ScoreChart(targetContext);
view.setScores(habit.getScores().toList()); view.setScores(habit.getScores().toList());
view.setColor(ColorUtils.getColor(targetContext, habit.getColor())); view.setColor(PaletteUtils.getColor(targetContext, habit.getColor()));
view.setBucketSize(7); view.setBucketSize(7);
measureView(view, dpToPixels(300), dpToPixels(200)); measureView(view, dpToPixels(300), dpToPixels(200));
} }

@ -46,7 +46,7 @@ public class StreakChartTest extends BaseViewTest
Habit habit = fixtures.createLongHabit(); Habit habit = fixtures.createLongHabit();
view = new StreakChart(targetContext); view = new StreakChart(targetContext);
view.setColor(ColorUtils.getAndroidTestColor(habit.getColor())); view.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
view.setStreaks(habit.getStreaks().getBest(5)); view.setStreaks(habit.getStreaks().getBest(5));
measureView(view, dpToPixels(300), dpToPixels(100)); measureView(view, dpToPixels(300), dpToPixels(100));
} }

@ -45,7 +45,7 @@ public class CheckmarkButtonViewTest extends BaseViewTest
super.setUp(); super.setUp();
view = new CheckmarkButtonView(targetContext); view = new CheckmarkButtonView(targetContext);
view.setValue(Checkmark.UNCHECKED); view.setValue(Checkmark.UNCHECKED);
view.setColor(ColorUtils.getAndroidTestColor(5)); view.setColor(PaletteUtils.getAndroidTestColor(5));
measureView(view, dpToPixels(48), dpToPixels(48)); measureView(view, dpToPixels(48), dpToPixels(48));
} }

@ -25,7 +25,7 @@ import android.test.suitebuilder.annotation.*;
import org.isoron.uhabits.core.models.Checkmark; import org.isoron.uhabits.core.models.Checkmark;
import org.isoron.uhabits.core.models.Habit; import org.isoron.uhabits.core.models.Habit;
import org.isoron.uhabits.BaseViewTest; import org.isoron.uhabits.BaseViewTest;
import org.isoron.uhabits.utils.ColorUtils; import org.isoron.uhabits.utils.*;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -60,7 +60,7 @@ public class CheckmarkPanelViewTest extends BaseViewTest
view.setHabit(habit); view.setHabit(habit);
view.setValues(checkmarks); view.setValues(checkmarks);
view.setButtonCount(4); view.setButtonCount(4);
view.setColor(ColorUtils.getAndroidTestColor(7)); view.setColor(PaletteUtils.getAndroidTestColor(7));
measureView(view, dpToPixels(200), dpToPixels(200)); measureView(view, dpToPixels(200), dpToPixels(200));
} }

@ -51,7 +51,7 @@ public class NumberButtonViewTest extends BaseViewTest
view = new NumberButtonView(targetContext); view = new NumberButtonView(targetContext);
view.setUnit("steps"); view.setUnit("steps");
view.setThreshold(100.0); view.setThreshold(100.0);
view.setColor(ColorUtils.getAndroidTestColor(8)); view.setColor(PaletteUtils.getAndroidTestColor(8));
measureView(view, dpToPixels(48), dpToPixels(48)); measureView(view, dpToPixels(48), dpToPixels(48));

@ -22,6 +22,7 @@ package org.isoron.uhabits.tasks;
import android.support.test.runner.*; import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*; import android.test.suitebuilder.annotation.*;
import org.isoron.androidbase.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.tasks.*; import org.isoron.uhabits.core.tasks.*;
@ -31,8 +32,8 @@ import org.junit.runner.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.IsNot.not; import static org.hamcrest.core.IsNot.not;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@ -54,7 +55,7 @@ public class ExportCSVTaskTest extends BaseAndroidTest
List<Habit> selected = new LinkedList<>(); List<Habit> selected = new LinkedList<>();
for (Habit h : habitList) selected.add(h); for (Habit h : habitList) selected.add(h);
File outputDir = baseSystem.getFilesDir("CSV"); File outputDir = new AndroidDirFinder(targetContext).getFilesDir("CSV");
assertNotNull(outputDir); assertNotNull(outputDir);
taskRunner.execute( taskRunner.execute(

@ -22,6 +22,7 @@ package org.isoron.uhabits.tasks;
import android.support.test.runner.*; import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*; import android.test.suitebuilder.annotation.*;
import org.isoron.androidbase.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.junit.*; import org.junit.*;
import org.junit.runner.*; import org.junit.runner.*;
@ -43,7 +44,9 @@ public class ExportDBTaskTest extends BaseAndroidTest
public void testExportCSV() throws Throwable public void testExportCSV() throws Throwable
{ {
ExportDBTask task = ExportDBTask task =
new ExportDBTask(targetContext, baseSystem, filename -> { new ExportDBTask(targetContext, new AndroidDirFinder(targetContext),
filename ->
{
assertNotNull(filename); assertNotNull(filename);
File f = new File(filename); File f = new File(filename);
assertTrue(f.exists()); assertTrue(f.exists());

@ -50,7 +50,7 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
double score = habit.getScores().getTodayValue(); double score = habit.getScores().getTodayValue();
float percentage = (float) score; float percentage = (float) score;
view.setActiveColor(ColorUtils.getAndroidTestColor(0)); view.setActiveColor(PaletteUtils.getAndroidTestColor(0));
view.setCheckmarkValue(habit.getCheckmarks().getTodayValue()); view.setCheckmarkValue(habit.getCheckmarks().getTodayValue());
view.setPercentage(percentage); view.setPercentage(percentage);
view.setName(habit.getName()); view.setName(habit.getName());

@ -42,7 +42,7 @@ public class HabitsApplication extends Application
{ {
private Context context; private Context context;
private static HabitsComponent component; private static HabitsApplicationComponent component;
private WidgetUpdater widgetUpdater; private WidgetUpdater widgetUpdater;
@ -50,12 +50,12 @@ public class HabitsApplication extends Application
private NotificationTray notificationTray; private NotificationTray notificationTray;
public HabitsComponent getComponent() public HabitsApplicationComponent getComponent()
{ {
return component; return component;
} }
public static void setComponent(HabitsComponent component) public static void setComponent(HabitsApplicationComponent component)
{ {
HabitsApplication.component = component; HabitsApplication.component = component;
} }
@ -79,9 +79,9 @@ public class HabitsApplication extends Application
super.onCreate(); super.onCreate();
context = this; context = this;
component = DaggerHabitsComponent component = DaggerHabitsApplicationComponent
.builder() .builder()
.appModule(new AppModule(context)) .appContextModule(new AppContextModule(context))
.build(); .build();
if (isTestMode()) if (isTestMode())

@ -43,15 +43,10 @@ import dagger.*;
@AppScope @AppScope
@Component(modules = { @Component(modules = {
AppModule.class, AppContextModule.class, HabitsModule.class, AndroidTaskRunner.class, SQLModelFactory.class
HabitsModule.class,
AndroidTaskRunner.class,
SQLModelFactory.class
}) })
public interface HabitsComponent public interface HabitsApplicationComponent
{ {
BaseSystem getBaseSystem();
CommandRunner getCommandRunner(); CommandRunner getCommandRunner();
@AppContext @AppContext

@ -22,7 +22,7 @@ package org.isoron.uhabits.activities;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.ui.*; import org.isoron.uhabits.core.ui.*;

@ -17,29 +17,25 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.activities.habits.show; package org.isoron.uhabits.activities;
import android.support.annotation.*; import org.isoron.uhabits.core.models.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import dagger.*; import dagger.*;
@ActivityScope @Module
@Component(modules = { ShowHabitModule.class }, public class HabitModule
dependencies = { HabitsComponent.class })
public interface ShowHabitComponent
{ {
@NonNull private final Habit habit;
ShowHabitController getController();
public HabitModule(Habit habit)
@NonNull {
ShowHabitsMenu getMenu(); this.habit = habit;
}
@NonNull
ShowHabitRootView getRootView(); @Provides
public Habit getHabit()
@NonNull {
ShowHabitScreen getScreen(); return habit;
}
} }

@ -0,0 +1,78 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities;
import android.content.*;
import android.net.*;
import android.os.*;
import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
public abstract class HabitsActivity extends BaseActivity
{
private HabitsActivityComponent component;
private HabitsApplicationComponent appComponent;
public HabitsActivityComponent getActivityComponent()
{
return component;
}
public HabitsApplicationComponent getAppComponent()
{
return appComponent;
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
appComponent =
((HabitsApplication) getApplicationContext()).getComponent();
Habit habit = getHabitFromIntent(appComponent.getHabitList());
component = DaggerHabitsActivityComponent
.builder()
.activityModule(new ActivityModule(this))
.habitModule(new HabitModule(habit))
.habitsApplicationComponent(appComponent)
.build();
component.getThemeSwitcher().apply();
}
@Nullable
private Habit getHabitFromIntent(@NonNull HabitList habitList)
{
Uri data = getIntent().getData();
if(data == null) return null;
Habit habit = habitList.getById(ContentUris.parseId(data));
if (habit == null) throw new RuntimeException("habit not found");
return habit;
}
}

@ -0,0 +1,74 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.list.*;
import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.activities.habits.show.*;
import org.isoron.uhabits.core.ui.*;
import dagger.*;
@ActivityScope
@Component(modules = {
ActivityModule.class,
HabitsActivityModule.class,
ListHabitsModule.class,
ShowHabitModule.class,
HabitModule.class
}, dependencies = { HabitsApplicationComponent.class })
public interface HabitsActivityComponent
{
BaseActivity getActivity();
CheckmarkButtonControllerFactory getCheckmarkButtonControllerFactory();
ColorPickerDialogFactory getColorPickerDialogFactory();
HabitCardListAdapter getHabitCardListAdapter();
HabitCardListController getHabitCardListController();
ListHabitsController getListHabitsController();
ListHabitsMenu getListHabitsMenu();
ListHabitsRootView getListHabitsRootView();
ListHabitsScreen getListHabitsScreen();
ListHabitsSelectionMenu getListHabitsSelectionMenu();
NumberButtonControllerFactory getNumberButtonControllerFactory();
ShowHabitController getShowHabitController();
ShowHabitsMenu getShowHabitMenu();
ShowHabitRootView getShowHabitRootView();
ShowHabitScreen getShowHabitScreen();
ThemeSwitcher getThemeSwitcher();
}

@ -17,22 +17,17 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.androidbase.activities; package org.isoron.uhabits.activities;
import org.isoron.uhabits.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.core.ui.*; import org.isoron.uhabits.core.ui.*;
import dagger.*; import dagger.*;
@ActivityScope @Module
@Component(modules = { ActivityModule.class }, public abstract class HabitsActivityModule
dependencies = { HabitsComponent.class })
public interface ActivityComponent
{ {
BaseActivity getActivity(); @Binds
@ActivityScope
ColorPickerDialogFactory getColorPickerDialogFactory(); abstract ThemeSwitcher getThemeSwitcher(AndroidThemeSwitcher t);
ThemeSwitcher getThemeSwitcher();
} }

@ -0,0 +1,47 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities;
import android.support.annotation.*;
import org.isoron.androidbase.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*;
import org.isoron.uhabits.core.ui.screens.habits.show.*;
import java.io.*;
import javax.inject.*;
public class HabitsDirFinder
implements ShowHabitMenuBehavior.System, ListHabitsBehavior.DirFinder
{
private AndroidDirFinder androidDirFinder;
@Inject
public HabitsDirFinder(@NonNull AndroidDirFinder androidDirFinder)
{
this.androidDirFinder = androidDirFinder;
}
@Override
public File getCSVOutputDir()
{
return androidDirFinder.getFilesDir("CSV");
}
}

@ -21,22 +21,21 @@ package org.isoron.uhabits.activities.about;
import android.os.*; import android.os.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.core.ui.screens.about.*; import org.isoron.uhabits.core.ui.screens.about.*;
/** /**
* Activity that allows the user to see information about the app itself. * Activity that allows the user to see information about the app itself.
* Display current version, link to Google Play and list of contributors. * Display current version, link to Google Play and list of contributors.
*/ */
public class AboutActivity extends BaseActivity public class AboutActivity extends HabitsActivity
{ {
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
HabitsApplication app = (HabitsApplication) getApplication(); HabitsApplicationComponent cmp = getAppComponent();
HabitsComponent cmp = app.getComponent();
AboutScreen screen = new AboutScreen(this, cmp.getIntentFactory()); AboutScreen screen = new AboutScreen(this, cmp.getIntentFactory());
AboutBehavior behavior = new AboutBehavior(cmp.getPreferences(), screen); AboutBehavior behavior = new AboutBehavior(cmp.getPreferences(), screen);
AboutRootView rootView = new AboutRootView(this, behavior); AboutRootView rootView = new AboutRootView(this, behavior);

@ -24,10 +24,10 @@ import android.support.annotation.*;
import android.widget.*; import android.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.BuildConfig; import org.isoron.uhabits.BuildConfig;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.core.ui.screens.about.*; import org.isoron.uhabits.core.ui.screens.about.*;
import org.isoron.uhabits.utils.*;
import butterknife.*; import butterknife.*;

@ -31,7 +31,7 @@ public class ColorPickerDialog extends com.android.colorpicker.ColorPickerDialog
{ {
super.setOnColorSelectedListener(c -> super.setOnColorSelectedListener(c ->
{ {
c = ColorUtils.colorToPaletteIndex(getContext(), c); c = PaletteUtils.colorToPaletteIndex(getContext(), c);
callback.onColorPicked(c); callback.onColorPicked(c);
}); });
} }

@ -22,7 +22,8 @@ package org.isoron.uhabits.activities.common.dialogs;
import android.content.*; import android.content.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.R;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import javax.inject.*; import javax.inject.*;
@ -42,7 +43,7 @@ public class ColorPickerDialogFactory
{ {
ColorPickerDialog dialog = new ColorPickerDialog(); ColorPickerDialog dialog = new ColorPickerDialog();
StyledResources res = new StyledResources(context); StyledResources res = new StyledResources(context);
int color = ColorUtils.getColor(context, paletteColor); int color = PaletteUtils.getColor(context, paletteColor);
dialog.initialize(R.string.color_picker_default_title, res.getPalette(), dialog.initialize(R.string.color_picker_default_title, res.getPalette(),
color, 4, com.android.colorpicker.ColorPickerDialog.SIZE_SMALL); color, 4, com.android.colorpicker.ColorPickerDialog.SIZE_SMALL);

@ -33,7 +33,7 @@ import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.tasks.*; import org.isoron.uhabits.core.tasks.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
public class HistoryEditorDialog extends AppCompatDialogFragment public class HistoryEditorDialog extends AppCompatDialogFragment
implements DialogInterface.OnClickListener, ModelObservable.Listener implements DialogInterface.OnClickListener, ModelObservable.Listener
@ -171,7 +171,7 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
if (getContext() == null || habit == null || historyChart == null) if (getContext() == null || habit == null || historyChart == null)
return; return;
int color = ColorUtils.getColor(getContext(), habit.getColor()); int color = PaletteUtils.getColor(getContext(), habit.getColor());
historyChart.setColor(color); historyChart.setColor(color);
historyChart.setCheckmarks(checkmarks); historyChart.setCheckmarks(checkmarks);
} }

@ -24,6 +24,7 @@ import android.graphics.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.util.*; import android.util.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.views.*; import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
@ -33,7 +34,7 @@ import org.isoron.uhabits.utils.*;
import java.text.*; import java.text.*;
import java.util.*; import java.util.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
public class BarChart extends ScrollableChart public class BarChart extends ScrollableChart
{ {

@ -24,6 +24,7 @@ import android.graphics.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.util.*; import android.util.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.core.utils.*; import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;

@ -26,6 +26,7 @@ import android.support.annotation.*;
import android.util.*; import android.util.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.core.utils.*; import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
@ -34,7 +35,7 @@ import java.text.*;
import java.util.*; import java.util.*;
import static org.isoron.uhabits.core.models.Checkmark.*; import static org.isoron.uhabits.core.models.Checkmark.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
public class HistoryChart extends ScrollableChart public class HistoryChart extends ScrollableChart
{ {

@ -26,11 +26,12 @@ import android.text.*;
import android.util.*; import android.util.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*; import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
public class RingView extends View public class RingView extends View
{ {
@ -76,7 +77,7 @@ public class RingView extends View
percentage = 0.0f; percentage = 0.0f;
precision = 0.01f; precision = 0.01f;
color = ColorUtils.getAndroidTestColor(0); color = PaletteUtils.getAndroidTestColor(0);
thickness = dpToPixels(getContext(), 2); thickness = dpToPixels(getContext(), 2);
text = ""; text = "";
textSize = getDimension(context, R.dimen.smallTextSize); textSize = getDimension(context, R.dimen.smallTextSize);

@ -24,6 +24,7 @@ import android.graphics.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.util.*; import android.util.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.utils.*; import org.isoron.uhabits.core.utils.*;
@ -32,7 +33,7 @@ import org.isoron.uhabits.utils.*;
import java.text.*; import java.text.*;
import java.util.*; import java.util.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
public class ScoreChart extends ScrollableChart public class ScoreChart extends ScrollableChart
{ {

@ -25,16 +25,16 @@ import android.util.*;
import android.view.*; import android.view.*;
import android.view.ViewGroup.*; import android.view.ViewGroup.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.utils.*; import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*;
import java.text.*; import java.text.*;
import java.util.*; import java.util.*;
import static android.view.View.MeasureSpec.*; import static android.view.View.MeasureSpec.*;
import static org.isoron.uhabits.utils.InterfaceUtils.getDimension; import static org.isoron.androidbase.utils.InterfaceUtils.getDimension;
public class StreakChart extends View public class StreakChart extends View
{ {

@ -28,9 +28,9 @@ import android.view.*;
import com.android.datetimepicker.time.*; import com.android.datetimepicker.time.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.edit.views.*; import org.isoron.uhabits.activities.habits.edit.views.*;
import org.isoron.uhabits.core.commands.*; import org.isoron.uhabits.core.commands.*;
@ -39,8 +39,8 @@ import org.isoron.uhabits.core.preferences.*;
import butterknife.*; import butterknife.*;
import static android.view.View.*; import static android.view.View.GONE;
import static org.isoron.uhabits.core.ui.ThemeSwitcher.*; import static org.isoron.uhabits.core.ui.ThemeSwitcher.THEME_LIGHT;
public class EditHabitDialog extends AppCompatDialogFragment public class EditHabitDialog extends AppCompatDialogFragment
{ {
@ -56,7 +56,7 @@ public class EditHabitDialog extends AppCompatDialogFragment
protected HabitList habitList; protected HabitList habitList;
protected HabitsComponent component; protected HabitsApplicationComponent component;
protected ModelFactory modelFactory; protected ModelFactory modelFactory;
@ -77,7 +77,7 @@ public class EditHabitDialog extends AppCompatDialogFragment
@Override @Override
public int getTheme() public int getTheme()
{ {
HabitsComponent component = HabitsApplicationComponent component =
((HabitsApplication) getContext().getApplicationContext()).getComponent(); ((HabitsApplication) getContext().getApplicationContext()).getComponent();
if(component.getPreferences().getTheme() == THEME_LIGHT) if(component.getPreferences().getTheme() == THEME_LIGHT)
@ -91,9 +91,9 @@ public class EditHabitDialog extends AppCompatDialogFragment
{ {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
BaseActivity activity = (BaseActivity) getActivity(); HabitsActivity activity = (HabitsActivity) getActivity();
colorPickerDialogFactory = colorPickerDialogFactory =
activity.getComponent().getColorPickerDialogFactory(); activity.getActivityComponent().getColorPickerDialogFactory();
} }
@Override @Override

@ -26,8 +26,8 @@ import android.util.*;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*; import static org.isoron.uhabits.utils.AttributeSetUtils.*;

@ -68,7 +68,7 @@ public class NameDescriptionPanel extends FrameLayout
public void setColor(int color) public void setColor(int color)
{ {
this.color = color; this.color = color;
tvName.setTextColor(ColorUtils.getColor(getContext(), color)); tvName.setTextColor(PaletteUtils.getColor(getContext(), color));
} }
@NonNull @NonNull

@ -21,8 +21,7 @@ package org.isoron.uhabits.activities.habits.list;
import android.os.*; import android.os.*;
import org.isoron.androidbase.activities.*; import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.ui.*; import org.isoron.uhabits.core.ui.*;
@ -31,7 +30,7 @@ import org.isoron.uhabits.core.utils.*;
/** /**
* Activity that allows the user to see and modify the list of habits. * Activity that allows the user to see and modify the list of habits.
*/ */
public class ListHabitsActivity extends BaseActivity public class ListHabitsActivity extends HabitsActivity
{ {
private HabitCardListAdapter adapter; private HabitCardListAdapter adapter;
@ -39,47 +38,33 @@ public class ListHabitsActivity extends BaseActivity
private ListHabitsScreen screen; private ListHabitsScreen screen;
private ListHabitsComponent component;
private boolean pureBlack; private boolean pureBlack;
private Preferences prefs; private Preferences prefs;
private MidnightTimer midnightTimer; private MidnightTimer midnightTimer;
public ListHabitsComponent getListHabitsComponent()
{
return component;
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
midnightTimer = getAppComponent().getMidnightTimer();
HabitsActivityComponent component = getActivityComponent();
HabitsApplication app = (HabitsApplication) getApplicationContext(); ListHabitsMenu menu = component.getListHabitsMenu();
midnightTimer = app.getComponent().getMidnightTimer(); ListHabitsSelectionMenu selectionMenu = component.getListHabitsSelectionMenu();
ListHabitsController controller = component.getListHabitsController();
component = DaggerListHabitsComponent
.builder()
.habitsComponent(app.getComponent())
.listHabitsModule(new ListHabitsModule(this))
.build();
ListHabitsMenu menu = component.getMenu();
ListHabitsSelectionMenu selectionMenu = component.getSelectionMenu();
ListHabitsController controller = component.getController();
adapter = component.getAdapter(); adapter = component.getHabitCardListAdapter();
rootView = component.getRootView(); rootView = component.getListHabitsRootView();
screen = component.getScreen(); screen = component.getListHabitsScreen();
prefs = app.getComponent().getPreferences(); prefs = getAppComponent().getPreferences();
pureBlack = prefs.isPureBlackEnabled(); pureBlack = prefs.isPureBlackEnabled();
screen.setMenu(menu); screen.setMenu(menu);
screen.setController(controller); screen.setController(controller);
screen.setListController(component.getListController()); screen.setListController(component.getHabitCardListController());
screen.setSelectionMenu(selectionMenu); screen.setSelectionMenu(selectionMenu);
rootView.setController(controller, selectionMenu); rootView.setController(controller, selectionMenu);

@ -1,51 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.list;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import dagger.*;
@ActivityScope
@Component(modules = { ListHabitsModule.class },
dependencies = { HabitsComponent.class })
public interface ListHabitsComponent
{
HabitCardListAdapter getAdapter();
CheckmarkButtonControllerFactory getCheckmarkButtonControllerFactory();
ListHabitsController getController();
HabitCardListController getListController();
ListHabitsMenu getMenu();
NumberButtonControllerFactory getNumberButtonControllerFactory();
ListHabitsRootView getRootView();
ListHabitsScreen getScreen();
ListHabitsSelectionMenu getSelectionMenu();
}

@ -22,7 +22,7 @@ package org.isoron.uhabits.activities.habits.list;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;

@ -23,7 +23,7 @@ import android.support.annotation.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.ui.*; import org.isoron.uhabits.core.ui.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*; import org.isoron.uhabits.core.ui.screens.habits.list.*;

@ -19,56 +19,51 @@
package org.isoron.uhabits.activities.habits.list; package org.isoron.uhabits.activities.habits.list;
import android.content.*;
import android.support.annotation.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*; import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*; import org.isoron.uhabits.core.ui.screens.habits.list.*;
import javax.inject.*;
import dagger.*; import dagger.*;
@Module class BugReporterProxy extends AndroidBugReporter
public class ListHabitsModule extends ActivityModule implements ListHabitsBehavior.BugReporter
{ {
public ListHabitsModule(BaseActivity activity) @Inject
public BugReporterProxy(@AppContext @NonNull Context context)
{ {
super(activity); super(context);
} }
}
@Provides @Module
ListHabitsMenuBehavior.Adapter getAdapter(HabitCardListAdapter adapter) public abstract class ListHabitsModule
{ {
return adapter; @Binds
} abstract ListHabitsMenuBehavior.Adapter getAdapter(HabitCardListAdapter adapter);
@Provides @Binds
ListHabitsMenuBehavior.Screen getMenuScreen(ListHabitsScreen screen) abstract ListHabitsBehavior.BugReporter getBugReporter(BugReporterProxy proxy);
{
return screen;
}
@Provides @Binds
ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen) abstract ListHabitsMenuBehavior.Screen getMenuScreen(ListHabitsScreen screen);
{
return screen;
}
@Provides @Binds
ListHabitsSelectionMenuBehavior.Adapter getSelMenuAdapter( abstract ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen);
HabitCardListAdapter adapter)
{
return adapter;
}
@Provides @Binds
ListHabitsSelectionMenuBehavior.Screen getSelMenuScreen(ListHabitsScreen screen) abstract ListHabitsSelectionMenuBehavior.Adapter getSelMenuAdapter(
{ HabitCardListAdapter adapter);
return screen;
}
@Provides @Binds
ListHabitsBehavior.System getSystem(BaseSystem system) abstract ListHabitsSelectionMenuBehavior.Screen getSelMenuScreen(
{ ListHabitsScreen screen);
return system;
} @Binds
abstract ListHabitsBehavior.DirFinder getSystem(HabitsDirFinder system);
} }

@ -26,6 +26,7 @@ import android.view.*;
import android.widget.*; import android.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.common.views.*; import org.isoron.uhabits.activities.common.views.*;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
@ -34,13 +35,12 @@ import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.tasks.*; import org.isoron.uhabits.core.tasks.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*; import org.isoron.uhabits.core.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*;
import javax.inject.*; import javax.inject.*;
import butterknife.*; import butterknife.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
@ActivityScope @ActivityScope
public class ListHabitsRootView extends BaseRootView public class ListHabitsRootView extends BaseRootView

@ -30,7 +30,7 @@ import android.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.edit.*; import org.isoron.uhabits.activities.habits.edit.*;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
@ -41,7 +41,6 @@ import org.isoron.uhabits.core.ui.*;
import org.isoron.uhabits.core.ui.callbacks.*; import org.isoron.uhabits.core.ui.callbacks.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*; import org.isoron.uhabits.core.ui.screens.habits.list.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.utils.*;
import java.io.*; import java.io.*;
import java.lang.reflect.*; import java.lang.reflect.*;

@ -23,7 +23,7 @@ import android.support.annotation.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.core.commands.*; import org.isoron.uhabits.core.commands.*;

@ -27,6 +27,7 @@ import android.text.*;
import android.util.*; import android.util.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
@ -34,8 +35,8 @@ import org.isoron.uhabits.utils.*;
import static android.view.View.MeasureSpec.*; import static android.view.View.MeasureSpec.*;
import static org.isoron.uhabits.core.models.Checkmark.*; import static org.isoron.uhabits.core.models.Checkmark.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*; import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.InterfaceUtils.getDimension; import static org.isoron.androidbase.utils.InterfaceUtils.getDimension;
import static org.isoron.uhabits.utils.InterfaceUtils.getFontAwesome; import static org.isoron.androidbase.utils.InterfaceUtils.getFontAwesome;
public class CheckmarkButtonView extends View public class CheckmarkButtonView extends View
{ {
@ -66,7 +67,7 @@ public class CheckmarkButtonView extends View
if(attrs == null) throw new IllegalStateException(); if(attrs == null) throw new IllegalStateException();
int paletteColor = getIntAttribute(ctx, attrs, "color", 0); int paletteColor = getIntAttribute(ctx, attrs, "color", 0);
setColor(ColorUtils.getAndroidTestColor(paletteColor)); setColor(PaletteUtils.getAndroidTestColor(paletteColor));
int value = getIntAttribute(ctx, attrs, "value", 0); int value = getIntAttribute(ctx, attrs, "value", 0);
setValue(value); setValue(value);

@ -25,7 +25,7 @@ import android.util.*;
import android.widget.*; import android.widget.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.*; import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
@ -33,10 +33,11 @@ import org.isoron.uhabits.core.utils.*;
import java.util.*; import java.util.*;
import static android.view.View.MeasureSpec.*; import static android.view.View.MeasureSpec.EXACTLY;
import static org.isoron.uhabits.utils.AttributeSetUtils.*; import static android.view.View.MeasureSpec.makeMeasureSpec;
import static org.isoron.uhabits.utils.ColorUtils.*; import static org.isoron.uhabits.utils.AttributeSetUtils.getIntAttribute;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor;
import static org.isoron.androidbase.utils.InterfaceUtils.getDimension;
public class CheckmarkPanelView extends LinearLayout public class CheckmarkPanelView extends LinearLayout
implements Preferences.Listener implements Preferences.Listener
@ -207,11 +208,11 @@ public class CheckmarkPanelView extends LinearLayout
CheckmarkButtonView buttonView) CheckmarkButtonView buttonView)
{ {
if (controller == null) return; if (controller == null) return;
if (!(getContext() instanceof ListHabitsActivity)) return; if (!(getContext() instanceof HabitsActivity)) return;
ListHabitsActivity activity = (ListHabitsActivity) getContext(); HabitsActivity activity = (HabitsActivity) getContext();
CheckmarkButtonControllerFactory buttonControllerFactory = activity CheckmarkButtonControllerFactory buttonControllerFactory = activity
.getListHabitsComponent() .getActivityComponent()
.getCheckmarkButtonControllerFactory(); .getCheckmarkButtonControllerFactory();
CheckmarkButtonController buttonController = CheckmarkButtonController buttonController =

@ -29,6 +29,7 @@ import android.util.*;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.common.views.*; import org.isoron.uhabits.activities.common.views.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
@ -40,7 +41,7 @@ import java.util.*;
import static android.os.Build.VERSION.*; import static android.os.Build.VERSION.*;
import static android.os.Build.VERSION_CODES.*; import static android.os.Build.VERSION_CODES.*;
import static android.view.ViewGroup.LayoutParams.*; import static android.view.ViewGroup.LayoutParams.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
public class HabitCardView extends FrameLayout public class HabitCardView extends FrameLayout
implements ModelObservable.Listener implements ModelObservable.Listener
@ -194,7 +195,7 @@ public class HabitCardView extends FrameLayout
private int getActiveColor(Habit habit) private int getActiveColor(Habit habit)
{ {
int mediumContrastColor = res.getColor(R.attr.mediumContrastTextColor); int mediumContrastColor = res.getColor(R.attr.mediumContrastTextColor);
int activeColor = ColorUtils.getColor(context, habit.getColor()); int activeColor = PaletteUtils.getColor(context, habit.getColor());
if (habit.isArchived()) activeColor = mediumContrastColor; if (habit.isArchived()) activeColor = mediumContrastColor;
return activeColor; return activeColor;
@ -237,7 +238,7 @@ public class HabitCardView extends FrameLayout
private void initEditMode() private void initEditMode()
{ {
Random rand = new Random(); Random rand = new Random();
int color = ColorUtils.getAndroidTestColor(rand.nextInt(10)); int color = PaletteUtils.getAndroidTestColor(rand.nextInt(10));
label.setText(EDIT_MODE_HABITS[rand.nextInt(EDIT_MODE_HABITS.length)]); label.setText(EDIT_MODE_HABITS[rand.nextInt(EDIT_MODE_HABITS.length)]);
label.setTextColor(color); label.setTextColor(color);
scoreRing.setColor(color); scoreRing.setColor(color);

@ -25,15 +25,15 @@ import android.support.annotation.*;
import android.text.*; import android.text.*;
import android.util.*; import android.util.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.common.views.*; import org.isoron.uhabits.activities.common.views.*;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.utils.*; import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*;
import java.util.*; import java.util.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
public class HeaderView extends ScrollableChart public class HeaderView extends ScrollableChart
implements Preferences.Listener, MidnightTimer.MidnightListener implements Preferences.Listener, MidnightTimer.MidnightListener

@ -26,6 +26,7 @@ import android.text.*;
import android.util.*; import android.util.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
@ -33,8 +34,7 @@ import org.isoron.uhabits.utils.*;
import java.text.*; import java.text.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*; import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.ColorUtils.*; import static org.isoron.androidbase.utils.InterfaceUtils.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*;
public class NumberButtonView extends View public class NumberButtonView extends View
{ {
@ -81,7 +81,7 @@ public class NumberButtonView extends View
int value = getIntAttribute(ctx, attrs, "value", 0); int value = getIntAttribute(ctx, attrs, "value", 0);
int threshold = getIntAttribute(ctx, attrs, "threshold", 1); int threshold = getIntAttribute(ctx, attrs, "threshold", 1);
String unit = getAttribute(ctx, attrs, "unit", "min"); String unit = getAttribute(ctx, attrs, "unit", "min");
setColor(getAndroidTestColor(color)); setColor(PaletteUtils.getAndroidTestColor(color));
setThreshold(threshold); setThreshold(threshold);
setValue(value); setValue(value);
setUnit(unit); setUnit(unit);

@ -25,7 +25,7 @@ import android.util.*;
import android.widget.*; import android.widget.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.*; import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
@ -33,10 +33,12 @@ import org.isoron.uhabits.core.utils.*;
import java.util.*; import java.util.*;
import static android.view.View.MeasureSpec.*; import static android.view.View.MeasureSpec.EXACTLY;
import static org.isoron.uhabits.utils.AttributeSetUtils.*; import static android.view.View.MeasureSpec.makeMeasureSpec;
import static org.isoron.uhabits.utils.ColorUtils.*; import static org.isoron.uhabits.utils.AttributeSetUtils.getAttribute;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.uhabits.utils.AttributeSetUtils.getIntAttribute;
import static org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor;
import static org.isoron.androidbase.utils.InterfaceUtils.getDimension;
public class NumberPanelView extends LinearLayout public class NumberPanelView extends LinearLayout
implements Preferences.Listener implements Preferences.Listener
@ -222,11 +224,11 @@ public class NumberPanelView extends LinearLayout
NumberButtonView buttonView) NumberButtonView buttonView)
{ {
if (controller == null) return; if (controller == null) return;
if (!(getContext() instanceof ListHabitsActivity)) return; if (!(getContext() instanceof HabitsActivity)) return;
ListHabitsActivity activity = (ListHabitsActivity) getContext(); HabitsActivity activity = (HabitsActivity) getContext();
NumberButtonControllerFactory buttonControllerFactory = activity NumberButtonControllerFactory buttonControllerFactory = activity
.getListHabitsComponent() .getActivityComponent()
.getNumberButtonControllerFactory(); .getNumberButtonControllerFactory();
NumberButtonController buttonController = NumberButtonController buttonController =

@ -19,27 +19,18 @@
package org.isoron.uhabits.activities.habits.show; package org.isoron.uhabits.activities.habits.show;
import android.content.*;
import android.net.*;
import android.os.*; import android.os.*;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*; import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
/** /**
* Activity that allows the user to see more information about a single habit. * Activity that allows the user to see more information about a single habit.
* <p> * <p>
* Shows all the metadata for the habit, in addition to several charts. * Shows all the metadata for the habit, in addition to several charts.
*/ */
public class ShowHabitActivity extends BaseActivity public class ShowHabitActivity extends HabitsActivity
{ {
@Nullable
private HabitList habitList;
@Nullable
private HabitsComponent appComponent;
@Nullable @Nullable
private ShowHabitScreen screen; private ShowHabitScreen screen;
@ -49,42 +40,21 @@ public class ShowHabitActivity extends BaseActivity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
HabitsApplication app = (HabitsApplication) getApplicationContext(); HabitsActivityComponent component = getActivityComponent();
appComponent = app.getComponent(); screen = component.getShowHabitScreen();
habitList = appComponent.getHabitList(); screen.setMenu(component.getShowHabitMenu());
Habit habit = getHabitFromIntent(); screen.setController(component.getShowHabitController());
component
ShowHabitComponent component = DaggerShowHabitComponent .getShowHabitRootView()
.builder() .setController(component.getShowHabitController());
.habitsComponent(app.getComponent())
.showHabitModule(new ShowHabitModule(this, habit))
.build();
screen = component.getScreen();
screen.setMenu(component.getMenu());
screen.setController(component.getController());
component.getRootView().setController(component.getController());
setScreen(screen); setScreen(screen);
} }
@Override @Override
protected void onResume() protected void onResume()
{ {
if(screen == null) throw new IllegalStateException(); if (screen == null) throw new IllegalStateException();
super.onResume(); super.onResume();
screen.reattachDialogs(); screen.reattachDialogs();
} }
@NonNull
private Habit getHabitFromIntent()
{
if(habitList == null) throw new IllegalStateException();
Uri data = getIntent().getData();
Habit habit = habitList.getById(ContentUris.parseId(data));
if (habit == null) throw new RuntimeException("habit not found");
return habit;
}
} }

@ -19,47 +19,20 @@
package org.isoron.uhabits.activities.habits.show; package org.isoron.uhabits.activities.habits.show;
import android.support.annotation.*; import org.isoron.uhabits.activities.*;
import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.ui.screens.habits.show.*; import org.isoron.uhabits.core.ui.screens.habits.show.*;
import dagger.*; import dagger.*;
@Module @Module
public class ShowHabitModule extends ActivityModule public abstract class ShowHabitModule
{ {
private Habit habit; @Binds
abstract ShowHabitBehavior.Screen getScreen(ShowHabitScreen screen);
public ShowHabitModule(@NonNull BaseActivity activity, @NonNull Habit habit)
{
super(activity);
this.habit = habit;
}
@Provides
public Habit getHabit()
{
return habit;
}
@Provides
public ShowHabitBehavior.Screen getScreen(ShowHabitScreen screen)
{
return screen;
}
@Provides @Binds
public ShowHabitMenuBehavior.Screen getMenuScreen(ShowHabitScreen screen) abstract ShowHabitMenuBehavior.Screen getMenuScreen(ShowHabitScreen screen);
{
return screen;
}
@Provides @Binds
public ShowHabitMenuBehavior.System getSystem(BaseSystem system) abstract ShowHabitMenuBehavior.System getSystem(HabitsDirFinder system);
{
return system;
}
} }

@ -25,6 +25,7 @@ import android.support.annotation.*;
import android.support.v7.widget.*; import android.support.v7.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.show.views.*; import org.isoron.uhabits.activities.habits.show.views.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
@ -90,7 +91,7 @@ public class ShowHabitRootView extends BaseRootView
if (!res.getBoolean(R.attr.useHabitColorAsPrimary)) if (!res.getBoolean(R.attr.useHabitColorAsPrimary))
return super.getToolbarColor(); return super.getToolbarColor();
return ColorUtils.getColor(getContext(), habit.getColor()); return PaletteUtils.getColor(getContext(), habit.getColor());
} }
@Override @Override

@ -22,7 +22,7 @@ package org.isoron.uhabits.activities.habits.show;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.edit.*; import org.isoron.uhabits.activities.habits.edit.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;

@ -23,7 +23,7 @@ import android.support.annotation.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.core.ui.screens.habits.show.*; import org.isoron.uhabits.core.ui.screens.habits.show.*;
import javax.inject.*; import javax.inject.*;

@ -83,7 +83,7 @@ public class BarCard extends HabitCard
private void initEditMode() private void initEditMode()
{ {
int color = ColorUtils.getAndroidTestColor(1); int color = PaletteUtils.getAndroidTestColor(1);
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
chart.populateWithRandomData(); chart.populateWithRandomData();
@ -107,7 +107,7 @@ public class BarCard extends HabitCard
@Override @Override
public void onPreExecute() public void onPreExecute()
{ {
int color = ColorUtils.getColor(getContext(), habit.getColor()); int color = PaletteUtils.getColor(getContext(), habit.getColor());
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
chart.setTarget(habit.getTargetValue()); chart.setTarget(habit.getTargetValue());

@ -82,7 +82,7 @@ public class FrequencyCard extends HabitCard
private void initEditMode() private void initEditMode()
{ {
int color = ColorUtils.getAndroidTestColor(1); int color = PaletteUtils.getAndroidTestColor(1);
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
chart.populateWithRandomData(); chart.populateWithRandomData();
@ -102,7 +102,7 @@ public class FrequencyCard extends HabitCard
public void onPreExecute() public void onPreExecute()
{ {
int paletteColor = getHabit().getColor(); int paletteColor = getHabit().getColor();
int color = ColorUtils.getColor(getContext(), paletteColor); int color = PaletteUtils.getColor(getContext(), paletteColor);
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
} }

@ -96,7 +96,7 @@ public class HistoryCard extends HabitCard
private void initEditMode() private void initEditMode()
{ {
int color = ColorUtils.getAndroidTestColor(1); int color = PaletteUtils.getAndroidTestColor(1);
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
chart.populateWithRandomData(); chart.populateWithRandomData();
@ -123,7 +123,7 @@ public class HistoryCard extends HabitCard
@Override @Override
public void onPreExecute() public void onPreExecute()
{ {
int color = ColorUtils.getColor(getContext(), habit.getColor()); int color = PaletteUtils.getColor(getContext(), habit.getColor());
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
if(habit.isNumerical()) if(habit.isNumerical())

@ -24,6 +24,7 @@ import android.support.annotation.*;
import android.util.*; import android.util.*;
import android.widget.*; import android.widget.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.common.views.*; import org.isoron.uhabits.activities.common.views.*;
@ -105,7 +106,7 @@ public class OverviewCard extends HabitCard
private void initEditMode() private void initEditMode()
{ {
color = ColorUtils.getAndroidTestColor(1); color = PaletteUtils.getAndroidTestColor(1);
cache.todayScore = 0.6f; cache.todayScore = 0.6f;
cache.lastMonthScore = 0.42f; cache.lastMonthScore = 0.42f;
cache.lastYearScore = 0.75f; cache.lastYearScore = 0.75f;
@ -182,7 +183,7 @@ public class OverviewCard extends HabitCard
@Override @Override
public void onPreExecute() public void onPreExecute()
{ {
color = ColorUtils.getColor(getContext(), getHabit().getColor()); color = PaletteUtils.getColor(getContext(), getHabit().getColor());
refreshColors(); refreshColors();
} }
} }

@ -127,8 +127,8 @@ public class ScoreCard extends HabitCard
if (isInEditMode()) if (isInEditMode())
{ {
spinner.setVisibility(GONE); spinner.setVisibility(GONE);
title.setTextColor(ColorUtils.getAndroidTestColor(1)); title.setTextColor(PaletteUtils.getAndroidTestColor(1));
chart.setColor(ColorUtils.getAndroidTestColor(1)); chart.setColor(PaletteUtils.getAndroidTestColor(1));
chart.populateWithRandomData(); chart.populateWithRandomData();
} }
} }
@ -159,7 +159,7 @@ public class ScoreCard extends HabitCard
public void onPreExecute() public void onPreExecute()
{ {
int color = int color =
ColorUtils.getColor(getContext(), getHabit().getColor()); PaletteUtils.getColor(getContext(), getHabit().getColor());
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
} }

@ -84,7 +84,7 @@ public class StreakCard extends HabitCard
private void initEditMode() private void initEditMode()
{ {
int color = ColorUtils.getAndroidTestColor(1); int color = PaletteUtils.getAndroidTestColor(1);
title.setTextColor(color); title.setTextColor(color);
streakChart.setColor(color); streakChart.setColor(color);
streakChart.populateWithRandomData(); streakChart.populateWithRandomData();
@ -111,7 +111,7 @@ public class StreakCard extends HabitCard
public void onPreExecute() public void onPreExecute()
{ {
int color = int color =
ColorUtils.getColor(getContext(), getHabit().getColor()); PaletteUtils.getColor(getContext(), getHabit().getColor());
title.setTextColor(color); title.setTextColor(color);
streakChart.setColor(color); streakChart.setColor(color);
} }

@ -52,7 +52,7 @@ public class SubtitleCard extends HabitCard
protected void refreshData() protected void refreshData()
{ {
Habit habit = getHabit(); Habit habit = getHabit();
int color = ColorUtils.getColor(getContext(), habit.getColor()); int color = PaletteUtils.getColor(getContext(), habit.getColor());
reminderLabel.setText(getResources().getString(R.string.reminder_off)); reminderLabel.setText(getResources().getString(R.string.reminder_off));
questionLabel.setVisibility(VISIBLE); questionLabel.setVisibility(VISIBLE);
@ -79,7 +79,7 @@ public class SubtitleCard extends HabitCard
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private void initEditMode() private void initEditMode()
{ {
questionLabel.setTextColor(ColorUtils.getAndroidTestColor(1)); questionLabel.setTextColor(PaletteUtils.getAndroidTestColor(1));
questionLabel.setText("Have you meditated today?"); questionLabel.setText("Have you meditated today?");
reminderLabel.setText("08:00"); reminderLabel.setText("08:00");
} }

@ -22,8 +22,8 @@ package org.isoron.uhabits.activities.settings;
import android.os.*; import android.os.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.R;
/** /**
* Activity that allows the user to view and modify the app settings. * Activity that allows the user to view and modify the app settings.

@ -21,17 +21,29 @@ package org.isoron.uhabits.activities.settings;
import android.app.backup.*; import android.app.backup.*;
import android.content.*; import android.content.*;
import android.net.*;
import android.os.*; import android.os.*;
import android.provider.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.v7.preference.*; import android.support.v7.preference.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.notifications.*; import org.isoron.uhabits.notifications.*;
import static org.isoron.uhabits.activities.habits.list.ListHabitsScreen.*; import static android.media.RingtoneManager.ACTION_RINGTONE_PICKER;
import static android.media.RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI;
import static android.media.RingtoneManager.EXTRA_RINGTONE_EXISTING_URI;
import static android.media.RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT;
import static android.media.RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT;
import static android.media.RingtoneManager.EXTRA_RINGTONE_TYPE;
import static android.media.RingtoneManager.TYPE_NOTIFICATION;
import static org.isoron.uhabits.activities.habits.list.ListHabitsScreen.RESULT_BUG_REPORT;
import static org.isoron.uhabits.activities.habits.list.ListHabitsScreen.RESULT_EXPORT_CSV;
import static org.isoron.uhabits.activities.habits.list.ListHabitsScreen.RESULT_EXPORT_DB;
import static org.isoron.uhabits.activities.habits.list.ListHabitsScreen.RESULT_IMPORT_DATA;
import static org.isoron.uhabits.activities.habits.list.ListHabitsScreen.RESULT_REPAIR_DB;
public class SettingsFragment extends PreferenceFragmentCompat public class SettingsFragment extends PreferenceFragmentCompat
implements SharedPreferences.OnSharedPreferenceChangeListener implements SharedPreferences.OnSharedPreferenceChangeListener
@ -100,7 +112,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
if (key.equals("reminderSound")) if (key.equals("reminderSound"))
{ {
BaseScreen.showRingtonePicker(this, RINGTONE_REQUEST_CODE); showRingtonePicker();
return true; return true;
} }
@ -142,6 +154,20 @@ public class SettingsFragment extends PreferenceFragmentCompat
}); });
} }
private void showRingtonePicker()
{
Uri existingRingtoneUri = RingtoneManager.getRingtoneUri(getContext());
Uri defaultRingtoneUri = Settings.System.DEFAULT_NOTIFICATION_URI;
Intent intent = new Intent(ACTION_RINGTONE_PICKER);
intent.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
intent.putExtra(EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true);
intent.putExtra(EXTRA_RINGTONE_DEFAULT_URI, defaultRingtoneUri);
intent.putExtra(EXTRA_RINGTONE_EXISTING_URI, existingRingtoneUri);
startActivityForResult(intent, RINGTONE_REQUEST_CODE);
}
private void updateRingtoneDescription() private void updateRingtoneDescription()
{ {
String ringtoneName = RingtoneManager.getRingtoneName(getContext()); String ringtoneName = RingtoneManager.getRingtoneName(getContext());

@ -26,9 +26,9 @@ import android.support.v7.widget.Toolbar;
import android.widget.*; import android.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.utils.*;
import java.util.*; import java.util.*;

@ -55,7 +55,7 @@ public class FireSettingReceiver extends BroadcastReceiver
ReceiverComponent component = ReceiverComponent component =
DaggerFireSettingReceiver_ReceiverComponent DaggerFireSettingReceiver_ReceiverComponent
.builder() .builder()
.habitsComponent(app.getComponent()) .habitsApplicationComponent(app.getComponent())
.build(); .build();
allHabits = app.getComponent().getHabitList(); allHabits = app.getComponent().getHabitList();
@ -100,7 +100,7 @@ public class FireSettingReceiver extends BroadcastReceiver
} }
@ReceiverScope @ReceiverScope
@Component(dependencies = HabitsComponent.class) @Component(dependencies = HabitsApplicationComponent.class)
interface ReceiverComponent interface ReceiverComponent
{ {
WidgetBehavior getWidgetController(); WidgetBehavior getWidgetController();

@ -29,7 +29,7 @@ import com.activeandroid.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.androidbase.utils.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.BuildConfig;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.utils.DatabaseUtils; import org.isoron.uhabits.utils.DatabaseUtils;

@ -27,7 +27,7 @@ import android.support.v4.app.*;
import android.support.v4.app.NotificationCompat.*; import android.support.v4.app.NotificationCompat.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.R;
import org.isoron.uhabits.core.*; import org.isoron.uhabits.core.*;
import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.preferences.*;
@ -36,8 +36,8 @@ import org.isoron.uhabits.intents.*;
import javax.inject.*; import javax.inject.*;
import static android.graphics.BitmapFactory.*; import static android.graphics.BitmapFactory.decodeResource;
import static org.isoron.uhabits.notifications.RingtoneManager.*; import static org.isoron.uhabits.notifications.RingtoneManager.getRingtoneUri;
@AppScope @AppScope
public class AndroidNotificationTray implements NotificationTray.SystemTray public class AndroidNotificationTray implements NotificationTray.SystemTray

@ -26,23 +26,20 @@ import android.preference.*;
import android.provider.*; import android.provider.*;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.core.*; import org.isoron.uhabits.core.*;
import javax.inject.*; import javax.inject.*;
import static android.media.RingtoneManager.*; import static android.media.RingtoneManager.EXTRA_RINGTONE_PICKED_URI;
import static android.media.RingtoneManager.getRingtone;
@AppScope @AppScope
public class RingtoneManager public class RingtoneManager
{ {
private Context context;
@Inject @Inject
public RingtoneManager(@AppContext @NonNull Context context) public RingtoneManager()
{ {
this.context = context;
} }
@Nullable @Nullable
@ -106,7 +103,6 @@ public class RingtoneManager
} }
else else
{ {
String off = context.getResources().getString(R.string.none);
SharedPreferences prefs = SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(context); PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putString("pref_ringtone_uri", "").apply(); prefs.edit().putString("pref_ringtone_uri", "").apply();

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save