mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Create android-base module
This commit is contained in:
@@ -53,6 +53,8 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation project(":uhabits-core")
|
||||
implementation project(":android-base")
|
||||
|
||||
implementation 'com.android.support:appcompat-v7:25.3.1'
|
||||
implementation 'com.android.support:design: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
|
||||
@Component(modules = {
|
||||
AppModule.class,
|
||||
AppContextModule.class,
|
||||
HabitsModule.class,
|
||||
SingleThreadModule.class,
|
||||
SQLModelFactory.class
|
||||
})
|
||||
public interface AndroidTestComponent extends HabitsComponent
|
||||
public interface AndroidTestComponent extends HabitsApplicationComponent
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ import android.util.*;
|
||||
import junit.framework.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
import org.isoron.uhabits.core.tasks.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
|
||||
import java.io.*;
|
||||
@@ -71,8 +71,6 @@ public class BaseAndroidTest extends TestCase
|
||||
|
||||
protected ModelFactory modelFactory;
|
||||
|
||||
protected BaseSystem baseSystem;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp()
|
||||
@@ -89,11 +87,9 @@ public class BaseAndroidTest extends TestCase
|
||||
|
||||
component = DaggerAndroidTestComponent
|
||||
.builder()
|
||||
.appModule(new AppModule(targetContext.getApplicationContext()))
|
||||
.appContextModule(new AppContextModule(targetContext.getApplicationContext()))
|
||||
.build();
|
||||
|
||||
baseSystem = new BaseSystem(targetContext);
|
||||
|
||||
HabitsApplication.setComponent(component);
|
||||
prefs = component.getPreferences();
|
||||
habitList = component.getHabitList();
|
||||
@@ -168,7 +164,7 @@ public class BaseAndroidTest extends TestCase
|
||||
|
||||
protected void startTracing()
|
||||
{
|
||||
File dir = baseSystem.getFilesDir("Profile");
|
||||
File dir = new AndroidDirFinder(targetContext).getFilesDir("Profile");
|
||||
assertNotNull(dir);
|
||||
String tracePath = dir.getAbsolutePath() + "/performance.trace";
|
||||
Log.d("PerformanceTest", String.format("Saving trace file to %s", tracePath));
|
||||
|
||||
@@ -40,7 +40,7 @@ public class BaseUserInterfaceTest
|
||||
|
||||
public static UiDevice device;
|
||||
|
||||
private HabitsComponent component;
|
||||
private HabitsApplicationComponent component;
|
||||
|
||||
private HabitList habitList;
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ import android.support.annotation.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.isoron.uhabits.widgets.*;
|
||||
|
||||
import java.io.*;
|
||||
@@ -170,7 +170,7 @@ public class BaseViewTest extends BaseAndroidTest
|
||||
{
|
||||
File dir = FileUtils.getSDCardDir("test-screenshots");
|
||||
if (dir == null)
|
||||
dir = baseSystem.getFilesDir("test-screenshots");
|
||||
dir = new AndroidDirFinder(targetContext).getFilesDir("test-screenshots");
|
||||
if (dir == null) throw new RuntimeException(
|
||||
"Could not find suitable dir for screenshots");
|
||||
|
||||
|
||||
@@ -54,8 +54,7 @@ public class HabitLoggerTest extends BaseAndroidTest
|
||||
|
||||
protected void assertLogcatContains(String expectedMsg) throws IOException
|
||||
{
|
||||
BaseSystem system = new BaseSystem(targetContext);
|
||||
String logcat = system.getLogcat();
|
||||
String logcat = new AndroidBugReporter(targetContext).getLogcat();
|
||||
assertThat(logcat, containsString(expectedMsg));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,7 @@ public class HabitsApplicationTest extends BaseAndroidTest
|
||||
String msg = "LOGCAT TEST";
|
||||
new RuntimeException(msg).printStackTrace();
|
||||
|
||||
BaseSystem system = new BaseSystem(targetContext);
|
||||
String log = system.getLogcat();
|
||||
String log = new AndroidBugReporter(targetContext).getLogcat();
|
||||
assertThat(log, containsString(msg));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class BarChartTest extends BaseViewTest
|
||||
long day = DateUtils.millisecondsInOneDay;
|
||||
CheckmarkList checkmarks = habit.getCheckmarks();
|
||||
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);
|
||||
measureView(view, dpToPixels(300), dpToPixels(200));
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class FrequencyChartTest extends BaseViewTest
|
||||
|
||||
view = new FrequencyChart(targetContext);
|
||||
view.setFrequency(habit.getRepetitions().getWeekdayFrequency());
|
||||
view.setColor(ColorUtils.getAndroidTestColor(habit.getColor()));
|
||||
view.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
|
||||
measureView(view, dpToPixels(300), dpToPixels(100));
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class HistoryChartTest extends BaseViewTest
|
||||
|
||||
chart = new HistoryChart(targetContext);
|
||||
chart.setCheckmarks(habit.getCheckmarks().getAllValues());
|
||||
chart.setColor(ColorUtils.getAndroidTestColor(habit.getColor()));
|
||||
chart.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
|
||||
measureView(chart, dpToPixels(400), dpToPixels(200));
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class RingViewTest extends BaseViewTest
|
||||
view = new RingView(targetContext);
|
||||
view.setPercentage(0.6f);
|
||||
view.setText("60%");
|
||||
view.setColor(ColorUtils.getAndroidTestColor(0));
|
||||
view.setColor(PaletteUtils.getAndroidTestColor(0));
|
||||
view.setBackgroundColor(Color.WHITE);
|
||||
view.setThickness(dpToPixels(3));
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class RingViewTest extends BaseViewTest
|
||||
public void testRender_withDifferentParams() throws IOException
|
||||
{
|
||||
view.setPercentage(0.25f);
|
||||
view.setColor(ColorUtils.getAndroidTestColor(5));
|
||||
view.setColor(PaletteUtils.getAndroidTestColor(5));
|
||||
|
||||
measureView(view, dpToPixels(200), dpToPixels(200));
|
||||
assertRenders(view, BASE_PATH + "renderDifferentParams.png");
|
||||
|
||||
@@ -50,7 +50,7 @@ public class ScoreChartTest extends BaseViewTest
|
||||
|
||||
view = new ScoreChart(targetContext);
|
||||
view.setScores(habit.getScores().toList());
|
||||
view.setColor(ColorUtils.getColor(targetContext, habit.getColor()));
|
||||
view.setColor(PaletteUtils.getColor(targetContext, habit.getColor()));
|
||||
view.setBucketSize(7);
|
||||
measureView(view, dpToPixels(300), dpToPixels(200));
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class StreakChartTest extends BaseViewTest
|
||||
Habit habit = fixtures.createLongHabit();
|
||||
|
||||
view = new StreakChart(targetContext);
|
||||
view.setColor(ColorUtils.getAndroidTestColor(habit.getColor()));
|
||||
view.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
|
||||
view.setStreaks(habit.getStreaks().getBest(5));
|
||||
measureView(view, dpToPixels(300), dpToPixels(100));
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class CheckmarkButtonViewTest extends BaseViewTest
|
||||
super.setUp();
|
||||
view = new CheckmarkButtonView(targetContext);
|
||||
view.setValue(Checkmark.UNCHECKED);
|
||||
view.setColor(ColorUtils.getAndroidTestColor(5));
|
||||
view.setColor(PaletteUtils.getAndroidTestColor(5));
|
||||
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.Habit;
|
||||
import org.isoron.uhabits.BaseViewTest;
|
||||
import org.isoron.uhabits.utils.ColorUtils;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -60,7 +60,7 @@ public class CheckmarkPanelViewTest extends BaseViewTest
|
||||
view.setHabit(habit);
|
||||
view.setValues(checkmarks);
|
||||
view.setButtonCount(4);
|
||||
view.setColor(ColorUtils.getAndroidTestColor(7));
|
||||
view.setColor(PaletteUtils.getAndroidTestColor(7));
|
||||
|
||||
measureView(view, dpToPixels(200), dpToPixels(200));
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class NumberButtonViewTest extends BaseViewTest
|
||||
view = new NumberButtonView(targetContext);
|
||||
view.setUnit("steps");
|
||||
view.setThreshold(100.0);
|
||||
view.setColor(ColorUtils.getAndroidTestColor(8));
|
||||
view.setColor(PaletteUtils.getAndroidTestColor(8));
|
||||
|
||||
measureView(view, dpToPixels(48), dpToPixels(48));
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ package org.isoron.uhabits.tasks;
|
||||
import android.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.tasks.*;
|
||||
@@ -31,8 +32,8 @@ import org.junit.runner.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -54,7 +55,7 @@ public class ExportCSVTaskTest extends BaseAndroidTest
|
||||
|
||||
List<Habit> selected = new LinkedList<>();
|
||||
for (Habit h : habitList) selected.add(h);
|
||||
File outputDir = baseSystem.getFilesDir("CSV");
|
||||
File outputDir = new AndroidDirFinder(targetContext).getFilesDir("CSV");
|
||||
assertNotNull(outputDir);
|
||||
|
||||
taskRunner.execute(
|
||||
|
||||
@@ -22,6 +22,7 @@ package org.isoron.uhabits.tasks;
|
||||
import android.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
@@ -43,12 +44,14 @@ public class ExportDBTaskTest extends BaseAndroidTest
|
||||
public void testExportCSV() throws Throwable
|
||||
{
|
||||
ExportDBTask task =
|
||||
new ExportDBTask(targetContext, baseSystem, filename -> {
|
||||
assertNotNull(filename);
|
||||
File f = new File(filename);
|
||||
assertTrue(f.exists());
|
||||
assertTrue(f.canRead());
|
||||
});
|
||||
new ExportDBTask(targetContext, new AndroidDirFinder(targetContext),
|
||||
filename ->
|
||||
{
|
||||
assertNotNull(filename);
|
||||
File f = new File(filename);
|
||||
assertTrue(f.exists());
|
||||
assertTrue(f.canRead());
|
||||
});
|
||||
|
||||
taskRunner.execute(task);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
|
||||
double score = habit.getScores().getTodayValue();
|
||||
float percentage = (float) score;
|
||||
|
||||
view.setActiveColor(ColorUtils.getAndroidTestColor(0));
|
||||
view.setActiveColor(PaletteUtils.getAndroidTestColor(0));
|
||||
view.setCheckmarkValue(habit.getCheckmarks().getTodayValue());
|
||||
view.setPercentage(percentage);
|
||||
view.setName(habit.getName());
|
||||
|
||||
@@ -1,31 +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.androidbase;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@Qualifier
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AppContext
|
||||
{
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* 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.os.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.v4.content.*;
|
||||
import android.util.*;
|
||||
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.lang.Process;
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
@Override
|
||||
public Context getContext()
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public BaseSystem(@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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@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.
|
||||
* @throws IOException when any I/O error occur.
|
||||
*/
|
||||
@Override
|
||||
@NonNull
|
||||
public String getBugReport() throws IOException
|
||||
{
|
||||
String logcat = getLogcat();
|
||||
String deviceInfo = getDeviceInfo();
|
||||
|
||||
String log = "---------- BUG REPORT BEGINS ----------\n";
|
||||
log += deviceInfo + "\n" + logcat;
|
||||
log += "---------- BUG REPORT ENDS ------------\n";
|
||||
|
||||
return log;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getCSVOutputDir()
|
||||
{
|
||||
return getFilesDir("CSV");
|
||||
}
|
||||
|
||||
public String getLogcat() throws IOException
|
||||
{
|
||||
int maxLineCount = 250;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
String[] command = new String[]{ "logcat", "-d" };
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
|
||||
InputStreamReader in = new InputStreamReader(process.getInputStream());
|
||||
BufferedReader bufferedReader = new BufferedReader(in);
|
||||
|
||||
LinkedList<String> log = new LinkedList<>();
|
||||
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null)
|
||||
{
|
||||
log.addLast(line);
|
||||
if (log.size() > maxLineCount) log.removeFirst();
|
||||
}
|
||||
|
||||
for (String l : log)
|
||||
{
|
||||
builder.append(l);
|
||||
builder.append('\n');
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String getDeviceInfo()
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* 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 java.io.*;
|
||||
import java.security.*;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.*;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
|
||||
public interface CACertSSLContextProvider
|
||||
{
|
||||
default SSLContext getCACertSSLContext()
|
||||
{
|
||||
try
|
||||
{
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
InputStream caInput = getContext().getAssets().open("cacert.pem");
|
||||
Certificate ca = cf.generateCertificate(caInput);
|
||||
|
||||
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
ks.load(null, null);
|
||||
ks.setCertificateEntry("ca", ca);
|
||||
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
|
||||
TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(ks);
|
||||
|
||||
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||
ctx.init(null, tmf.getTrustManagers(), null);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
Context getContext();
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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.activities;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.common.dialogs.*;
|
||||
import org.isoron.uhabits.core.ui.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@ActivityScope
|
||||
@Component(modules = { ActivityModule.class },
|
||||
dependencies = { HabitsComponent.class })
|
||||
public interface ActivityComponent
|
||||
{
|
||||
BaseActivity getActivity();
|
||||
|
||||
ColorPickerDialogFactory getColorPickerDialogFactory();
|
||||
|
||||
ThemeSwitcher getThemeSwitcher();
|
||||
}
|
||||
@@ -1,58 +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.androidbase.activities;
|
||||
|
||||
import android.content.*;
|
||||
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.core.ui.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@Module
|
||||
public class ActivityModule
|
||||
{
|
||||
private BaseActivity activity;
|
||||
|
||||
public ActivityModule(BaseActivity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Provides
|
||||
public BaseActivity getActivity()
|
||||
{
|
||||
return activity;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ActivityContext
|
||||
public Context getContext()
|
||||
{
|
||||
return activity;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public static ThemeSwitcher getThemeSwitcher(AndroidThemeSwitcher t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +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.androidbase.activities;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
/**
|
||||
* Scope used by objects that live as long as the activity is alive.
|
||||
*/
|
||||
@Scope
|
||||
public @interface ActivityScope { }
|
||||
@@ -1,139 +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.androidbase.activities;
|
||||
|
||||
import android.content.*;
|
||||
import android.os.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.v7.app.*;
|
||||
import android.view.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
|
||||
import static android.R.anim.fade_in;
|
||||
import static android.R.anim.fade_out;
|
||||
|
||||
/**
|
||||
* Base class for all activities in the application.
|
||||
* <p>
|
||||
* This class delegates the responsibilities of an Android activity to other
|
||||
* classes. For example, callbacks related to menus are forwarded to a {@link
|
||||
* BaseMenu}, while callbacks related to activity results are forwarded to a
|
||||
* {@link BaseScreen}.
|
||||
* <p>
|
||||
* A BaseActivity also installs an {@link java.lang.Thread.UncaughtExceptionHandler}
|
||||
* to the main thread. By default, this handler is an instance of
|
||||
* BaseExceptionHandler, which logs the exception to the disk before the application
|
||||
* crashes. To the default handler, you should override the method
|
||||
* getExceptionHandler.
|
||||
*/
|
||||
abstract public class BaseActivity extends AppCompatActivity
|
||||
{
|
||||
@Nullable
|
||||
private BaseMenu baseMenu;
|
||||
|
||||
@Nullable
|
||||
private BaseScreen screen;
|
||||
|
||||
private ActivityComponent component;
|
||||
|
||||
public ActivityComponent getComponent()
|
||||
{
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(@Nullable Menu menu)
|
||||
{
|
||||
if (menu == null) return true;
|
||||
if (baseMenu == null) return true;
|
||||
baseMenu.onCreate(getMenuInflater(), menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@Nullable MenuItem item)
|
||||
{
|
||||
if (item == null) return false;
|
||||
if (baseMenu == null) return false;
|
||||
return baseMenu.onItemSelected(item);
|
||||
}
|
||||
|
||||
public void restartWithFade(Class<?> cls)
|
||||
{
|
||||
new Handler().postDelayed(() ->
|
||||
{
|
||||
finish();
|
||||
overridePendingTransition(fade_in, fade_out);
|
||||
startActivity(new Intent(this, cls));
|
||||
|
||||
}, 500); // HACK: Let the menu disappear first
|
||||
}
|
||||
|
||||
public void setBaseMenu(@Nullable BaseMenu baseMenu)
|
||||
{
|
||||
this.baseMenu = baseMenu;
|
||||
}
|
||||
|
||||
public void setScreen(@Nullable BaseScreen screen)
|
||||
{
|
||||
this.screen = screen;
|
||||
}
|
||||
|
||||
public void showDialog(AppCompatDialogFragment dialog, String tag)
|
||||
{
|
||||
dialog.show(getSupportFragmentManager(), tag);
|
||||
}
|
||||
|
||||
public void showDialog(AppCompatDialog dialog)
|
||||
{
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int request, int result, Intent data)
|
||||
{
|
||||
if (screen == null) super.onActivityResult(request, result, data);
|
||||
else screen.onResult(request, result, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
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()
|
||||
{
|
||||
return new BaseExceptionHandler(this);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* 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.activities;
|
||||
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.models.sqlite.*;
|
||||
|
||||
public class BaseExceptionHandler implements Thread.UncaughtExceptionHandler
|
||||
{
|
||||
@Nullable
|
||||
private Thread.UncaughtExceptionHandler originalHandler;
|
||||
|
||||
@NonNull
|
||||
private BaseActivity activity;
|
||||
|
||||
public BaseExceptionHandler(@NonNull BaseActivity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
originalHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(@Nullable Thread thread,
|
||||
@Nullable Throwable ex)
|
||||
{
|
||||
if (ex == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
ex.printStackTrace();
|
||||
new BaseSystem(activity).dumpBugReportToFile();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (ex.getCause() instanceof InconsistentDatabaseException)
|
||||
{
|
||||
HabitsApplication app = (HabitsApplication) activity.getApplication();
|
||||
HabitList habits = app.getComponent().getHabitList();
|
||||
habits.repair();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if (originalHandler != null)
|
||||
originalHandler.uncaughtException(thread, ex);
|
||||
}
|
||||
}
|
||||
@@ -1,105 +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.androidbase.activities;
|
||||
|
||||
import android.support.annotation.*;
|
||||
import android.view.*;
|
||||
|
||||
import javax.annotation.*;
|
||||
|
||||
/**
|
||||
* Base class for all the menus in the application.
|
||||
* <p>
|
||||
* This class receives from BaseActivity all callbacks related to menus, such as
|
||||
* menu creation and click events. It also handles some implementation details
|
||||
* of creating menus in Android, such as inflating the resources.
|
||||
*/
|
||||
public abstract class BaseMenu
|
||||
{
|
||||
@NonNull
|
||||
private final BaseActivity activity;
|
||||
|
||||
public BaseMenu(@NonNull BaseActivity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public BaseActivity getActivity()
|
||||
{
|
||||
return activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare that the menu has changed, and should be recreated.
|
||||
*/
|
||||
public void invalidate()
|
||||
{
|
||||
activity.invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the menu is first displayed.
|
||||
* <p>
|
||||
* The given menu is already inflated and ready to receive items. The
|
||||
* application should override this method and add items to the menu here.
|
||||
*
|
||||
* @param menu the menu that is being created.
|
||||
*/
|
||||
public void onCreate(@NonNull Menu menu)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the menu is first displayed.
|
||||
* <p>
|
||||
* This method should not be overridden. The application should override
|
||||
* the methods onCreate(Menu) and getMenuResourceId instead.
|
||||
*
|
||||
* @param inflater a menu inflater, for creating the menu
|
||||
* @param menu the menu that is being created.
|
||||
*/
|
||||
public void onCreate(@NonNull MenuInflater inflater,
|
||||
@NonNull Menu menu)
|
||||
{
|
||||
menu.clear();
|
||||
inflater.inflate(getMenuResourceId(), menu);
|
||||
onCreate(menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever an item on the menu is selected.
|
||||
*
|
||||
* @param item the item that was selected.
|
||||
* @return true if the event was consumed, or false otherwise
|
||||
*/
|
||||
public boolean onItemSelected(@NonNull MenuItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the resource that should be used to inflate this menu.
|
||||
*
|
||||
* @return id of the menu resource.
|
||||
*/
|
||||
@Resource
|
||||
protected abstract int getMenuResourceId();
|
||||
}
|
||||
@@ -1,106 +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.androidbase.activities;
|
||||
|
||||
import android.content.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.v4.content.res.*;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.ui.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import static android.os.Build.VERSION.*;
|
||||
import static android.os.Build.VERSION_CODES.*;
|
||||
|
||||
/**
|
||||
* Base class for all root views in the application.
|
||||
* <p>
|
||||
* A root view is an Android view that is directly attached to an activity. This
|
||||
* view usually includes a toolbar and a progress bar. This abstract class hides
|
||||
* some of the complexity of setting these things up, for every version of
|
||||
* Android.
|
||||
*/
|
||||
public abstract class BaseRootView extends FrameLayout
|
||||
{
|
||||
@NonNull
|
||||
private final Context context;
|
||||
|
||||
private final ThemeSwitcher themeSwitcher;
|
||||
|
||||
boolean shouldDisplayHomeAsUp = false;
|
||||
|
||||
public BaseRootView(@NonNull Context context)
|
||||
{
|
||||
super(context);
|
||||
this.context = context;
|
||||
BaseActivity activity = (BaseActivity) context;
|
||||
themeSwitcher = activity.getComponent().getThemeSwitcher();
|
||||
}
|
||||
|
||||
public boolean getDisplayHomeAsUp()
|
||||
{
|
||||
return shouldDisplayHomeAsUp;
|
||||
}
|
||||
|
||||
public void setDisplayHomeAsUp(boolean b)
|
||||
{
|
||||
shouldDisplayHomeAsUp = b;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Toolbar getToolbar()
|
||||
{
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
if (toolbar == null) throw new RuntimeException(
|
||||
"Your BaseRootView should have a " +
|
||||
"toolbar with id R.id.toolbar");
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
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);
|
||||
return res.getColor(R.attr.colorPrimary);
|
||||
}
|
||||
|
||||
protected void initToolbar()
|
||||
{
|
||||
if (SDK_INT >= LOLLIPOP)
|
||||
{
|
||||
getToolbar().setElevation(InterfaceUtils.dpToPixels(context, 2));
|
||||
|
||||
View view = findViewById(R.id.toolbarShadow);
|
||||
if (view != null) view.setVisibility(GONE);
|
||||
|
||||
view = findViewById(R.id.headerShadow);
|
||||
if (view != null) view.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,332 +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.androidbase.activities;
|
||||
|
||||
import android.content.*;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.net.*;
|
||||
import android.os.*;
|
||||
import android.provider.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.design.widget.*;
|
||||
import android.support.v4.app.*;
|
||||
import android.support.v4.content.res.*;
|
||||
import android.support.v7.app.*;
|
||||
import android.support.v7.view.ActionMode;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.notifications.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
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 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.
|
||||
* <p>
|
||||
* Screens are responsible for deciding what root views and what menus should be
|
||||
* attached to the main window. They are also responsible for showing other
|
||||
* screens and for receiving their results.
|
||||
*/
|
||||
public class BaseScreen
|
||||
{
|
||||
public static final int REQUEST_CREATE_DOCUMENT = 1;
|
||||
|
||||
protected BaseActivity activity;
|
||||
|
||||
@Nullable
|
||||
private BaseRootView rootView;
|
||||
|
||||
@Nullable
|
||||
private BaseSelectionMenu selectionMenu;
|
||||
|
||||
protected Snackbar snackbar;
|
||||
|
||||
public BaseScreen(@NonNull BaseActivity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void setupActionBarColor(@NonNull AppCompatActivity activity,
|
||||
int color)
|
||||
{
|
||||
|
||||
Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar);
|
||||
if (toolbar == null) return;
|
||||
|
||||
activity.setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar actionBar = activity.getSupportActionBar();
|
||||
if (actionBar == null) return;
|
||||
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
|
||||
ColorDrawable drawable = new ColorDrawable(color);
|
||||
actionBar.setBackgroundDrawable(drawable);
|
||||
|
||||
if (SDK_INT >= LOLLIPOP)
|
||||
{
|
||||
int darkerColor = ColorUtils.mixColors(color, Color.BLACK, 0.75f);
|
||||
activity.getWindow().setStatusBarColor(darkerColor);
|
||||
|
||||
toolbar.setElevation(InterfaceUtils.dpToPixels(activity, 2));
|
||||
|
||||
View view = activity.findViewById(R.id.toolbarShadow);
|
||||
if (view != null) view.setVisibility(View.GONE);
|
||||
|
||||
view = activity.findViewById(R.id.headerShadow);
|
||||
if (view != null) view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@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.
|
||||
*/
|
||||
public void invalidate()
|
||||
{
|
||||
if (rootView == null) return;
|
||||
rootView.invalidate();
|
||||
}
|
||||
|
||||
public void invalidateToolbar()
|
||||
{
|
||||
if (rootView == null) return;
|
||||
|
||||
activity.runOnUiThread(() -> {
|
||||
Toolbar toolbar = rootView.getToolbar();
|
||||
activity.setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = activity.getSupportActionBar();
|
||||
if (actionBar == null) return;
|
||||
|
||||
actionBar.setDisplayHomeAsUpEnabled(rootView.getDisplayHomeAsUp());
|
||||
|
||||
int color = rootView.getToolbarColor();
|
||||
setActionBarColor(actionBar, color);
|
||||
setStatusBarColor(color);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when another Activity has finished, and has returned some result.
|
||||
*
|
||||
* @param requestCode the request code originally supplied to {@link
|
||||
* android.app.Activity#startActivityForResult(Intent,
|
||||
* int, Bundle)}.
|
||||
* @param resultCode the result code sent by the other activity.
|
||||
* @param data an Intent containing extra data sent by the other
|
||||
* activity.
|
||||
* @see {@link android.app.Activity#onActivityResult(int, int, Intent)}
|
||||
*/
|
||||
public void onResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the menu to be shown by this screen.
|
||||
* <p>
|
||||
* This menu will be visible if when there is no active selection operation.
|
||||
* If the provided menu is null, then no menu will be shown.
|
||||
*
|
||||
* @param menu the menu to be shown.
|
||||
*/
|
||||
public void setMenu(@Nullable BaseMenu menu)
|
||||
{
|
||||
activity.setBaseMenu(menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the root view for this screen.
|
||||
*
|
||||
* @param rootView the root view for this screen.
|
||||
*/
|
||||
public void setRootView(@Nullable BaseRootView rootView)
|
||||
{
|
||||
this.rootView = rootView;
|
||||
activity.setContentView(rootView);
|
||||
if (rootView == null) return;
|
||||
|
||||
invalidateToolbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the menu to be shown when a selection is active on the screen.
|
||||
*
|
||||
* @param menu the menu to be shown during a selection
|
||||
*/
|
||||
public void setSelectionMenu(@Nullable BaseSelectionMenu menu)
|
||||
{
|
||||
this.selectionMenu = menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a message on the screen.
|
||||
*
|
||||
* @param stringId the string resource id for this message.
|
||||
*/
|
||||
public void showMessage(@StringRes Integer stringId)
|
||||
{
|
||||
if (stringId == null || rootView == null) return;
|
||||
if (snackbar == null)
|
||||
{
|
||||
snackbar = Snackbar.make(rootView, stringId, Snackbar.LENGTH_SHORT);
|
||||
int tvId = android.support.design.R.id.snackbar_text;
|
||||
TextView tv = (TextView) snackbar.getView().findViewById(tvId);
|
||||
tv.setTextColor(Color.WHITE);
|
||||
}
|
||||
else snackbar.setText(stringId);
|
||||
snackbar.show();
|
||||
}
|
||||
|
||||
public void showSendEmailScreen(@StringRes int toId,
|
||||
@StringRes int subjectId,
|
||||
String content)
|
||||
{
|
||||
String to = activity.getString(toId);
|
||||
String subject = activity.getString(subjectId);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("message/rfc822");
|
||||
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{ to });
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
|
||||
intent.putExtra(Intent.EXTRA_TEXT, content);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
public void showSendFileScreen(@NonNull String archiveFilename)
|
||||
{
|
||||
File file = new File(archiveFilename);
|
||||
Uri fileUri = getUriForFile(activity, "org.isoron.uhabits", file);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("application/zip");
|
||||
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the screen to start a selection.
|
||||
* <p>
|
||||
* If a selection menu was provided, this menu will be shown instead of the
|
||||
* regular one.
|
||||
*/
|
||||
public void startSelection()
|
||||
{
|
||||
activity.startSupportActionMode(new ActionModeWrapper());
|
||||
}
|
||||
|
||||
private void setActionBarColor(@NonNull ActionBar actionBar, int color)
|
||||
{
|
||||
ColorDrawable drawable = new ColorDrawable(color);
|
||||
actionBar.setBackgroundDrawable(drawable);
|
||||
}
|
||||
|
||||
private void setStatusBarColor(int baseColor)
|
||||
{
|
||||
if (SDK_INT < LOLLIPOP) return;
|
||||
|
||||
int darkerColor = ColorUtils.mixColors(baseColor, Color.BLACK, 0.75f);
|
||||
activity.getWindow().setStatusBarColor(darkerColor);
|
||||
}
|
||||
|
||||
private class ActionModeWrapper implements ActionMode.Callback
|
||||
{
|
||||
@Override
|
||||
public boolean onActionItemClicked(@Nullable ActionMode mode,
|
||||
@Nullable MenuItem item)
|
||||
{
|
||||
if (item == null || selectionMenu == null) return false;
|
||||
return selectionMenu.onItemClicked(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateActionMode(@Nullable ActionMode mode,
|
||||
@Nullable Menu menu)
|
||||
{
|
||||
if (selectionMenu == null) return false;
|
||||
if (mode == null || menu == null) return false;
|
||||
selectionMenu.onCreate(activity.getMenuInflater(), mode, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(@Nullable ActionMode mode)
|
||||
{
|
||||
if (selectionMenu == null) return;
|
||||
selectionMenu.onFinish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(@Nullable ActionMode mode,
|
||||
@Nullable Menu menu)
|
||||
{
|
||||
if (selectionMenu == null || menu == null) return false;
|
||||
return selectionMenu.onPrepare(menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +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.androidbase.activities;
|
||||
|
||||
import android.support.annotation.*;
|
||||
import android.support.v7.view.ActionMode;
|
||||
import android.view.*;
|
||||
|
||||
/**
|
||||
* Base class for all the selection menus in the application.
|
||||
* <p>
|
||||
* A selection menu is a menu that appears when the screen starts a selection
|
||||
* operation. It contains actions that modify the selected items, such as delete
|
||||
* or archive. Since it replaces the toolbar, it also has a title.
|
||||
* <p>
|
||||
* This class hides many implementation details of creating such menus in
|
||||
* Android. The interface is supposed to look very similar to {@link BaseMenu},
|
||||
* with a few additional methods, such as finishing the selection operation.
|
||||
* Internally, it uses an {@link ActionMode}.
|
||||
*/
|
||||
public abstract class BaseSelectionMenu
|
||||
{
|
||||
@Nullable
|
||||
private ActionMode actionMode;
|
||||
|
||||
/**
|
||||
* Finishes the selection operation.
|
||||
*/
|
||||
public void finish()
|
||||
{
|
||||
if (actionMode != null) actionMode.finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare that the menu has changed, and should be recreated.
|
||||
*/
|
||||
public void invalidate()
|
||||
{
|
||||
if (actionMode != null) actionMode.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the menu is first displayed.
|
||||
* <p>
|
||||
* This method should not be overridden. The application should override
|
||||
* the methods onCreate(Menu) and getMenuResourceId instead.
|
||||
*
|
||||
* @param inflater a menu inflater, for creating the menu
|
||||
* @param mode the action mode associated with this menu.
|
||||
* @param menu the menu that is being created.
|
||||
*/
|
||||
public void onCreate(@NonNull MenuInflater inflater,
|
||||
@NonNull ActionMode mode,
|
||||
@NonNull Menu menu)
|
||||
{
|
||||
this.actionMode = mode;
|
||||
inflater.inflate(getResourceId(), menu);
|
||||
onCreate(menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the selection operation is about to finish.
|
||||
*/
|
||||
public void onFinish()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever an item on the menu is selected.
|
||||
*
|
||||
* @param item the item that was selected.
|
||||
* @return true if the event was consumed, or false otherwise
|
||||
*/
|
||||
public boolean onItemClicked(@NonNull MenuItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called whenever the menu is invalidated.
|
||||
*
|
||||
* @param menu the menu to be refreshed
|
||||
* @return true if the menu has changes, false otherwise
|
||||
*/
|
||||
public boolean onPrepare(@NonNull Menu menu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title of the selection menu.
|
||||
*
|
||||
* @param title the new title.
|
||||
*/
|
||||
public void setTitle(String title)
|
||||
{
|
||||
if (actionMode != null) actionMode.setTitle(title);
|
||||
}
|
||||
|
||||
protected abstract int getResourceId();
|
||||
|
||||
/**
|
||||
* Called when the menu is first created.
|
||||
*
|
||||
* @param menu the menu being created
|
||||
*/
|
||||
protected void onCreate(@NonNull Menu menu)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import android.os.*;
|
||||
import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public abstract class FileUtils
|
||||
{
|
||||
public static void copy(File src, File dst) throws IOException
|
||||
{
|
||||
FileInputStream inStream = new FileInputStream(src);
|
||||
FileOutputStream outStream = new FileOutputStream(dst);
|
||||
copy(inStream, outStream);
|
||||
}
|
||||
|
||||
public static void copy(InputStream inStream, File dst) throws IOException
|
||||
{
|
||||
FileOutputStream outStream = new FileOutputStream(dst);
|
||||
copy(inStream, outStream);
|
||||
}
|
||||
|
||||
public static void copy(InputStream in, OutputStream out) throws IOException
|
||||
{
|
||||
int numBytes;
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
while ((numBytes = in.read(buffer)) != -1)
|
||||
out.write(buffer, 0, numBytes);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getDir(@NonNull File potentialParentDirs[],
|
||||
@Nullable String relativePath)
|
||||
{
|
||||
if (relativePath == null) relativePath = "";
|
||||
|
||||
File chosenDir = null;
|
||||
for (File dir : potentialParentDirs)
|
||||
{
|
||||
if (dir == null || !dir.canWrite()) continue;
|
||||
chosenDir = dir;
|
||||
break;
|
||||
}
|
||||
|
||||
if (chosenDir == null)
|
||||
{
|
||||
Log.e("FileUtils",
|
||||
"getDir: all potential parents are null or non-writable");
|
||||
return null;
|
||||
}
|
||||
|
||||
File dir = new File(
|
||||
String.format("%s/%s/", chosenDir.getAbsolutePath(), relativePath));
|
||||
if (!dir.exists() && !dir.mkdirs())
|
||||
{
|
||||
Log.e("FileUtils",
|
||||
"getDir: chosen dir does not exist and cannot be created");
|
||||
return null;
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getSDCardDir(@Nullable String relativePath)
|
||||
{
|
||||
File parents[] =
|
||||
new File[]{ Environment.getExternalStorageDirectory() };
|
||||
return getDir(parents, relativePath);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public class HabitsApplication extends Application
|
||||
{
|
||||
private Context context;
|
||||
|
||||
private static HabitsComponent component;
|
||||
private static HabitsApplicationComponent component;
|
||||
|
||||
private WidgetUpdater widgetUpdater;
|
||||
|
||||
@@ -50,12 +50,12 @@ public class HabitsApplication extends Application
|
||||
|
||||
private NotificationTray notificationTray;
|
||||
|
||||
public HabitsComponent getComponent()
|
||||
public HabitsApplicationComponent getComponent()
|
||||
{
|
||||
return component;
|
||||
}
|
||||
|
||||
public static void setComponent(HabitsComponent component)
|
||||
public static void setComponent(HabitsApplicationComponent component)
|
||||
{
|
||||
HabitsApplication.component = component;
|
||||
}
|
||||
@@ -79,9 +79,9 @@ public class HabitsApplication extends Application
|
||||
super.onCreate();
|
||||
context = this;
|
||||
|
||||
component = DaggerHabitsComponent
|
||||
component = DaggerHabitsApplicationComponent
|
||||
.builder()
|
||||
.appModule(new AppModule(context))
|
||||
.appContextModule(new AppContextModule(context))
|
||||
.build();
|
||||
|
||||
if (isTestMode())
|
||||
|
||||
@@ -43,15 +43,10 @@ import dagger.*;
|
||||
|
||||
@AppScope
|
||||
@Component(modules = {
|
||||
AppModule.class,
|
||||
HabitsModule.class,
|
||||
AndroidTaskRunner.class,
|
||||
SQLModelFactory.class
|
||||
AppContextModule.class, HabitsModule.class, AndroidTaskRunner.class, SQLModelFactory.class
|
||||
})
|
||||
public interface HabitsComponent
|
||||
public interface HabitsApplicationComponent
|
||||
{
|
||||
BaseSystem getBaseSystem();
|
||||
|
||||
CommandRunner getCommandRunner();
|
||||
|
||||
@AppContext
|
||||
@@ -22,7 +22,7 @@ package org.isoron.uhabits.activities;
|
||||
import android.support.annotation.*;
|
||||
|
||||
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.ui.*;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
@@ -17,26 +17,25 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.androidbase;
|
||||
package org.isoron.uhabits.activities;
|
||||
|
||||
import android.content.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@Module
|
||||
public class AppModule
|
||||
public class HabitModule
|
||||
{
|
||||
private final Context context;
|
||||
private final Habit habit;
|
||||
|
||||
public AppModule(@AppContext Context context)
|
||||
public HabitModule(Habit habit)
|
||||
{
|
||||
this.context = context;
|
||||
this.habit = habit;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@AppContext
|
||||
Context getContext()
|
||||
public Habit getHabit()
|
||||
{
|
||||
return context;
|
||||
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();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
@@ -17,15 +17,17 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.androidbase.activities;
|
||||
package org.isoron.uhabits.activities;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.core.ui.*;
|
||||
|
||||
import javax.inject.*;
|
||||
import dagger.*;
|
||||
|
||||
@Qualifier
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ActivityContext
|
||||
@Module
|
||||
public abstract class HabitsActivityModule
|
||||
{
|
||||
@Binds
|
||||
@ActivityScope
|
||||
abstract ThemeSwitcher getThemeSwitcher(AndroidThemeSwitcher t);
|
||||
}
|
||||
@@ -16,30 +16,32 @@
|
||||
* 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.show;
|
||||
package org.isoron.uhabits.activities;
|
||||
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.core.ui.screens.habits.list.*;
|
||||
import org.isoron.uhabits.core.ui.screens.habits.show.*;
|
||||
|
||||
import dagger.*;
|
||||
import java.io.*;
|
||||
|
||||
@ActivityScope
|
||||
@Component(modules = { ShowHabitModule.class },
|
||||
dependencies = { HabitsComponent.class })
|
||||
public interface ShowHabitComponent
|
||||
import javax.inject.*;
|
||||
|
||||
public class HabitsDirFinder
|
||||
implements ShowHabitMenuBehavior.System, ListHabitsBehavior.DirFinder
|
||||
{
|
||||
@NonNull
|
||||
ShowHabitController getController();
|
||||
private AndroidDirFinder androidDirFinder;
|
||||
|
||||
@NonNull
|
||||
ShowHabitsMenu getMenu();
|
||||
@Inject
|
||||
public HabitsDirFinder(@NonNull AndroidDirFinder androidDirFinder)
|
||||
{
|
||||
this.androidDirFinder = androidDirFinder;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
ShowHabitRootView getRootView();
|
||||
|
||||
@NonNull
|
||||
ShowHabitScreen getScreen();
|
||||
@Override
|
||||
public File getCSVOutputDir()
|
||||
{
|
||||
return androidDirFinder.getFilesDir("CSV");
|
||||
}
|
||||
}
|
||||
@@ -21,22 +21,21 @@ package org.isoron.uhabits.activities.about;
|
||||
|
||||
import android.os.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.core.ui.screens.about.*;
|
||||
|
||||
/**
|
||||
* Activity that allows the user to see information about the app itself.
|
||||
* Display current version, link to Google Play and list of contributors.
|
||||
*/
|
||||
public class AboutActivity extends BaseActivity
|
||||
public class AboutActivity extends HabitsActivity
|
||||
{
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
HabitsApplication app = (HabitsApplication) getApplication();
|
||||
HabitsComponent cmp = app.getComponent();
|
||||
HabitsApplicationComponent cmp = getAppComponent();
|
||||
AboutScreen screen = new AboutScreen(this, cmp.getIntentFactory());
|
||||
AboutBehavior behavior = new AboutBehavior(cmp.getPreferences(), screen);
|
||||
AboutRootView rootView = new AboutRootView(this, behavior);
|
||||
|
||||
@@ -24,10 +24,10 @@ import android.support.annotation.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.BuildConfig;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.core.ui.screens.about.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import butterknife.*;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ColorPickerDialog extends com.android.colorpicker.ColorPickerDialog
|
||||
{
|
||||
super.setOnColorSelectedListener(c ->
|
||||
{
|
||||
c = ColorUtils.colorToPaletteIndex(getContext(), c);
|
||||
c = PaletteUtils.colorToPaletteIndex(getContext(), c);
|
||||
callback.onColorPicked(c);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ package org.isoron.uhabits.activities.common.dialogs;
|
||||
import android.content.*;
|
||||
|
||||
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 javax.inject.*;
|
||||
@@ -42,7 +43,7 @@ public class ColorPickerDialogFactory
|
||||
{
|
||||
ColorPickerDialog dialog = new ColorPickerDialog();
|
||||
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(),
|
||||
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.utils.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.*;
|
||||
|
||||
public class HistoryEditorDialog extends AppCompatDialogFragment
|
||||
implements DialogInterface.OnClickListener, ModelObservable.Listener
|
||||
@@ -171,7 +171,7 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
|
||||
if (getContext() == null || habit == null || historyChart == null)
|
||||
return;
|
||||
|
||||
int color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
int color = PaletteUtils.getColor(getContext(), habit.getColor());
|
||||
historyChart.setColor(color);
|
||||
historyChart.setCheckmarks(checkmarks);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.graphics.*;
|
||||
import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.habits.list.views.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
@@ -33,7 +34,7 @@ import org.isoron.uhabits.utils.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.*;
|
||||
|
||||
public class BarChart extends ScrollableChart
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.graphics.*;
|
||||
import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
@@ -34,7 +35,7 @@ import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@@ -26,11 +26,12 @@ import android.text.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
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
|
||||
{
|
||||
@@ -76,7 +77,7 @@ public class RingView extends View
|
||||
|
||||
percentage = 0.0f;
|
||||
precision = 0.01f;
|
||||
color = ColorUtils.getAndroidTestColor(0);
|
||||
color = PaletteUtils.getAndroidTestColor(0);
|
||||
thickness = dpToPixels(getContext(), 2);
|
||||
text = "";
|
||||
textSize = getDimension(context, R.dimen.smallTextSize);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.graphics.*;
|
||||
import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
@@ -32,7 +33,7 @@ import org.isoron.uhabits.utils.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.*;
|
||||
|
||||
public class ScoreChart extends ScrollableChart
|
||||
{
|
||||
|
||||
@@ -25,16 +25,16 @@ import android.util.*;
|
||||
import android.view.*;
|
||||
import android.view.ViewGroup.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@@ -28,9 +28,9 @@ import android.view.*;
|
||||
|
||||
import com.android.datetimepicker.time.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.activities.common.dialogs.*;
|
||||
import org.isoron.uhabits.activities.habits.edit.views.*;
|
||||
import org.isoron.uhabits.core.commands.*;
|
||||
@@ -39,8 +39,8 @@ import org.isoron.uhabits.core.preferences.*;
|
||||
|
||||
import butterknife.*;
|
||||
|
||||
import static android.view.View.*;
|
||||
import static org.isoron.uhabits.core.ui.ThemeSwitcher.*;
|
||||
import static android.view.View.GONE;
|
||||
import static org.isoron.uhabits.core.ui.ThemeSwitcher.THEME_LIGHT;
|
||||
|
||||
public class EditHabitDialog extends AppCompatDialogFragment
|
||||
{
|
||||
@@ -56,7 +56,7 @@ public class EditHabitDialog extends AppCompatDialogFragment
|
||||
|
||||
protected HabitList habitList;
|
||||
|
||||
protected HabitsComponent component;
|
||||
protected HabitsApplicationComponent component;
|
||||
|
||||
protected ModelFactory modelFactory;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class EditHabitDialog extends AppCompatDialogFragment
|
||||
@Override
|
||||
public int getTheme()
|
||||
{
|
||||
HabitsComponent component =
|
||||
HabitsApplicationComponent component =
|
||||
((HabitsApplication) getContext().getApplicationContext()).getComponent();
|
||||
|
||||
if(component.getPreferences().getTheme() == THEME_LIGHT)
|
||||
@@ -91,9 +91,9 @@ public class EditHabitDialog extends AppCompatDialogFragment
|
||||
{
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
BaseActivity activity = (BaseActivity) getActivity();
|
||||
HabitsActivity activity = (HabitsActivity) getActivity();
|
||||
colorPickerDialogFactory =
|
||||
activity.getComponent().getColorPickerDialogFactory();
|
||||
activity.getActivityComponent().getColorPickerDialogFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,8 +26,8 @@ import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class NameDescriptionPanel extends FrameLayout
|
||||
public void setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
tvName.setTextColor(ColorUtils.getColor(getContext(), color));
|
||||
tvName.setTextColor(PaletteUtils.getColor(getContext(), color));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
||||
@@ -21,8 +21,7 @@ package org.isoron.uhabits.activities.habits.list;
|
||||
|
||||
import android.os.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
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.
|
||||
*/
|
||||
public class ListHabitsActivity extends BaseActivity
|
||||
public class ListHabitsActivity extends HabitsActivity
|
||||
{
|
||||
private HabitCardListAdapter adapter;
|
||||
|
||||
@@ -39,47 +38,33 @@ public class ListHabitsActivity extends BaseActivity
|
||||
|
||||
private ListHabitsScreen screen;
|
||||
|
||||
private ListHabitsComponent component;
|
||||
|
||||
private boolean pureBlack;
|
||||
|
||||
private Preferences prefs;
|
||||
|
||||
private MidnightTimer midnightTimer;
|
||||
|
||||
public ListHabitsComponent getListHabitsComponent()
|
||||
{
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
midnightTimer = getAppComponent().getMidnightTimer();
|
||||
HabitsActivityComponent component = getActivityComponent();
|
||||
|
||||
HabitsApplication app = (HabitsApplication) getApplicationContext();
|
||||
midnightTimer = app.getComponent().getMidnightTimer();
|
||||
ListHabitsMenu menu = component.getListHabitsMenu();
|
||||
ListHabitsSelectionMenu selectionMenu = component.getListHabitsSelectionMenu();
|
||||
ListHabitsController controller = component.getListHabitsController();
|
||||
|
||||
component = DaggerListHabitsComponent
|
||||
.builder()
|
||||
.habitsComponent(app.getComponent())
|
||||
.listHabitsModule(new ListHabitsModule(this))
|
||||
.build();
|
||||
adapter = component.getHabitCardListAdapter();
|
||||
rootView = component.getListHabitsRootView();
|
||||
screen = component.getListHabitsScreen();
|
||||
|
||||
ListHabitsMenu menu = component.getMenu();
|
||||
ListHabitsSelectionMenu selectionMenu = component.getSelectionMenu();
|
||||
ListHabitsController controller = component.getController();
|
||||
|
||||
adapter = component.getAdapter();
|
||||
rootView = component.getRootView();
|
||||
screen = component.getScreen();
|
||||
|
||||
prefs = app.getComponent().getPreferences();
|
||||
prefs = getAppComponent().getPreferences();
|
||||
pureBlack = prefs.isPureBlackEnabled();
|
||||
|
||||
screen.setMenu(menu);
|
||||
screen.setController(controller);
|
||||
screen.setListController(component.getListController());
|
||||
screen.setListController(component.getHabitCardListController());
|
||||
screen.setSelectionMenu(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 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.model.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.support.annotation.*;
|
||||
import android.view.*;
|
||||
|
||||
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.ui.*;
|
||||
import org.isoron.uhabits.core.ui.screens.habits.list.*;
|
||||
|
||||
@@ -19,56 +19,51 @@
|
||||
|
||||
package org.isoron.uhabits.activities.habits.list;
|
||||
|
||||
import android.content.*;
|
||||
import android.support.annotation.*;
|
||||
|
||||
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.core.ui.screens.habits.list.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@Module
|
||||
public class ListHabitsModule extends ActivityModule
|
||||
class BugReporterProxy extends AndroidBugReporter
|
||||
implements ListHabitsBehavior.BugReporter
|
||||
{
|
||||
public ListHabitsModule(BaseActivity activity)
|
||||
@Inject
|
||||
public BugReporterProxy(@AppContext @NonNull Context context)
|
||||
{
|
||||
super(activity);
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsMenuBehavior.Adapter getAdapter(HabitCardListAdapter adapter)
|
||||
{
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsMenuBehavior.Screen getMenuScreen(ListHabitsScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsSelectionMenuBehavior.Adapter getSelMenuAdapter(
|
||||
HabitCardListAdapter adapter)
|
||||
{
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsSelectionMenuBehavior.Screen getSelMenuScreen(ListHabitsScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsBehavior.System getSystem(BaseSystem system)
|
||||
{
|
||||
return system;
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Module
|
||||
public abstract class ListHabitsModule
|
||||
{
|
||||
@Binds
|
||||
abstract ListHabitsMenuBehavior.Adapter getAdapter(HabitCardListAdapter adapter);
|
||||
|
||||
@Binds
|
||||
abstract ListHabitsBehavior.BugReporter getBugReporter(BugReporterProxy proxy);
|
||||
|
||||
@Binds
|
||||
abstract ListHabitsMenuBehavior.Screen getMenuScreen(ListHabitsScreen screen);
|
||||
|
||||
@Binds
|
||||
abstract ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen);
|
||||
|
||||
@Binds
|
||||
abstract ListHabitsSelectionMenuBehavior.Adapter getSelMenuAdapter(
|
||||
HabitCardListAdapter adapter);
|
||||
|
||||
@Binds
|
||||
abstract ListHabitsSelectionMenuBehavior.Screen getSelMenuScreen(
|
||||
ListHabitsScreen screen);
|
||||
|
||||
@Binds
|
||||
abstract ListHabitsBehavior.DirFinder getSystem(HabitsDirFinder system);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.activities.common.views.*;
|
||||
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.tasks.*;
|
||||
import org.isoron.uhabits.core.ui.screens.habits.list.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
import butterknife.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.*;
|
||||
|
||||
@ActivityScope
|
||||
public class ListHabitsRootView extends BaseRootView
|
||||
|
||||
@@ -30,7 +30,7 @@ import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
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.habits.edit.*;
|
||||
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.screens.habits.list.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.support.annotation.*;
|
||||
import android.view.*;
|
||||
|
||||
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.model.*;
|
||||
import org.isoron.uhabits.core.commands.*;
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.text.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.habits.list.controllers.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
@@ -34,8 +35,8 @@ import org.isoron.uhabits.utils.*;
|
||||
import static android.view.View.MeasureSpec.*;
|
||||
import static org.isoron.uhabits.core.models.Checkmark.*;
|
||||
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.getDimension;
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.getFontAwesome;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.getDimension;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.getFontAwesome;
|
||||
|
||||
public class CheckmarkButtonView extends View
|
||||
{
|
||||
@@ -66,7 +67,7 @@ public class CheckmarkButtonView extends View
|
||||
if(attrs == null) throw new IllegalStateException();
|
||||
|
||||
int paletteColor = getIntAttribute(ctx, attrs, "color", 0);
|
||||
setColor(ColorUtils.getAndroidTestColor(paletteColor));
|
||||
setColor(PaletteUtils.getAndroidTestColor(paletteColor));
|
||||
|
||||
int value = getIntAttribute(ctx, attrs, "value", 0);
|
||||
setValue(value);
|
||||
|
||||
@@ -25,7 +25,7 @@ import android.util.*;
|
||||
import android.widget.*;
|
||||
|
||||
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.core.models.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
@@ -33,10 +33,11 @@ import org.isoron.uhabits.core.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static android.view.View.MeasureSpec.*;
|
||||
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
|
||||
import static org.isoron.uhabits.utils.ColorUtils.*;
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static android.view.View.MeasureSpec.EXACTLY;
|
||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
||||
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 CheckmarkPanelView extends LinearLayout
|
||||
implements Preferences.Listener
|
||||
@@ -207,11 +208,11 @@ public class CheckmarkPanelView extends LinearLayout
|
||||
CheckmarkButtonView buttonView)
|
||||
{
|
||||
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
|
||||
.getListHabitsComponent()
|
||||
.getActivityComponent()
|
||||
.getCheckmarkButtonControllerFactory();
|
||||
|
||||
CheckmarkButtonController buttonController =
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.common.views.*;
|
||||
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_CODES.*;
|
||||
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
|
||||
implements ModelObservable.Listener
|
||||
@@ -194,7 +195,7 @@ public class HabitCardView extends FrameLayout
|
||||
private int getActiveColor(Habit habit)
|
||||
{
|
||||
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;
|
||||
|
||||
return activeColor;
|
||||
@@ -237,7 +238,7 @@ public class HabitCardView extends FrameLayout
|
||||
private void initEditMode()
|
||||
{
|
||||
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.setTextColor(color);
|
||||
scoreRing.setColor(color);
|
||||
|
||||
@@ -25,15 +25,15 @@ import android.support.annotation.*;
|
||||
import android.text.*;
|
||||
import android.util.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.common.views.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.*;
|
||||
|
||||
public class HeaderView extends ScrollableChart
|
||||
implements Preferences.Listener, MidnightTimer.MidnightListener
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.text.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.habits.list.controllers.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
@@ -33,8 +34,7 @@ import org.isoron.uhabits.utils.*;
|
||||
import java.text.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
|
||||
import static org.isoron.uhabits.utils.ColorUtils.*;
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static org.isoron.androidbase.utils.InterfaceUtils.*;
|
||||
|
||||
public class NumberButtonView extends View
|
||||
{
|
||||
@@ -81,7 +81,7 @@ public class NumberButtonView extends View
|
||||
int value = getIntAttribute(ctx, attrs, "value", 0);
|
||||
int threshold = getIntAttribute(ctx, attrs, "threshold", 1);
|
||||
String unit = getAttribute(ctx, attrs, "unit", "min");
|
||||
setColor(getAndroidTestColor(color));
|
||||
setColor(PaletteUtils.getAndroidTestColor(color));
|
||||
setThreshold(threshold);
|
||||
setValue(value);
|
||||
setUnit(unit);
|
||||
|
||||
@@ -25,7 +25,7 @@ import android.util.*;
|
||||
import android.widget.*;
|
||||
|
||||
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.core.models.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
@@ -33,10 +33,12 @@ import org.isoron.uhabits.core.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static android.view.View.MeasureSpec.*;
|
||||
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
|
||||
import static org.isoron.uhabits.utils.ColorUtils.*;
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
import static android.view.View.MeasureSpec.EXACTLY;
|
||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
||||
import static org.isoron.uhabits.utils.AttributeSetUtils.getAttribute;
|
||||
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
|
||||
implements Preferences.Listener
|
||||
@@ -222,11 +224,11 @@ public class NumberPanelView extends LinearLayout
|
||||
NumberButtonView buttonView)
|
||||
{
|
||||
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
|
||||
.getListHabitsComponent()
|
||||
.getActivityComponent()
|
||||
.getNumberButtonControllerFactory();
|
||||
|
||||
NumberButtonController buttonController =
|
||||
|
||||
@@ -19,27 +19,18 @@
|
||||
|
||||
package org.isoron.uhabits.activities.habits.show;
|
||||
|
||||
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.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
|
||||
/**
|
||||
* Activity that allows the user to see more information about a single habit.
|
||||
* <p>
|
||||
* 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
|
||||
private ShowHabitScreen screen;
|
||||
@@ -49,42 +40,21 @@ public class ShowHabitActivity extends BaseActivity
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
HabitsApplication app = (HabitsApplication) getApplicationContext();
|
||||
appComponent = app.getComponent();
|
||||
habitList = appComponent.getHabitList();
|
||||
Habit habit = getHabitFromIntent();
|
||||
|
||||
ShowHabitComponent component = DaggerShowHabitComponent
|
||||
.builder()
|
||||
.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());
|
||||
HabitsActivityComponent component = getActivityComponent();
|
||||
screen = component.getShowHabitScreen();
|
||||
screen.setMenu(component.getShowHabitMenu());
|
||||
screen.setController(component.getShowHabitController());
|
||||
component
|
||||
.getShowHabitRootView()
|
||||
.setController(component.getShowHabitController());
|
||||
setScreen(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
if(screen == null) throw new IllegalStateException();
|
||||
|
||||
if (screen == null) throw new IllegalStateException();
|
||||
super.onResume();
|
||||
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;
|
||||
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.core.ui.screens.habits.show.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@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;
|
||||
}
|
||||
@Binds
|
||||
abstract ShowHabitMenuBehavior.Screen getMenuScreen(ShowHabitScreen screen);
|
||||
|
||||
@Provides
|
||||
public Habit getHabit()
|
||||
{
|
||||
return habit;
|
||||
}
|
||||
|
||||
@Provides
|
||||
public ShowHabitBehavior.Screen getScreen(ShowHabitScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
public ShowHabitMenuBehavior.Screen getMenuScreen(ShowHabitScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
public ShowHabitMenuBehavior.System getSystem(BaseSystem system)
|
||||
{
|
||||
return system;
|
||||
}
|
||||
@Binds
|
||||
abstract ShowHabitMenuBehavior.System getSystem(HabitsDirFinder system);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.support.annotation.*;
|
||||
import android.support.v7.widget.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.activities.habits.show.views.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
@@ -90,7 +91,7 @@ public class ShowHabitRootView extends BaseRootView
|
||||
if (!res.getBoolean(R.attr.useHabitColorAsPrimary))
|
||||
return super.getToolbarColor();
|
||||
|
||||
return ColorUtils.getColor(getContext(), habit.getColor());
|
||||
return PaletteUtils.getColor(getContext(), habit.getColor());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,7 +22,7 @@ package org.isoron.uhabits.activities.habits.show;
|
||||
import android.support.annotation.*;
|
||||
|
||||
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.habits.edit.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.support.annotation.*;
|
||||
import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.core.ui.screens.habits.show.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@@ -83,7 +83,7 @@ public class BarCard extends HabitCard
|
||||
|
||||
private void initEditMode()
|
||||
{
|
||||
int color = ColorUtils.getAndroidTestColor(1);
|
||||
int color = PaletteUtils.getAndroidTestColor(1);
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
chart.populateWithRandomData();
|
||||
@@ -107,7 +107,7 @@ public class BarCard extends HabitCard
|
||||
@Override
|
||||
public void onPreExecute()
|
||||
{
|
||||
int color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
int color = PaletteUtils.getColor(getContext(), habit.getColor());
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
chart.setTarget(habit.getTargetValue());
|
||||
|
||||
@@ -82,7 +82,7 @@ public class FrequencyCard extends HabitCard
|
||||
|
||||
private void initEditMode()
|
||||
{
|
||||
int color = ColorUtils.getAndroidTestColor(1);
|
||||
int color = PaletteUtils.getAndroidTestColor(1);
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
chart.populateWithRandomData();
|
||||
@@ -102,7 +102,7 @@ public class FrequencyCard extends HabitCard
|
||||
public void onPreExecute()
|
||||
{
|
||||
int paletteColor = getHabit().getColor();
|
||||
int color = ColorUtils.getColor(getContext(), paletteColor);
|
||||
int color = PaletteUtils.getColor(getContext(), paletteColor);
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class HistoryCard extends HabitCard
|
||||
|
||||
private void initEditMode()
|
||||
{
|
||||
int color = ColorUtils.getAndroidTestColor(1);
|
||||
int color = PaletteUtils.getAndroidTestColor(1);
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
chart.populateWithRandomData();
|
||||
@@ -123,7 +123,7 @@ public class HistoryCard extends HabitCard
|
||||
@Override
|
||||
public void onPreExecute()
|
||||
{
|
||||
int color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
int color = PaletteUtils.getColor(getContext(), habit.getColor());
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
if(habit.isNumerical())
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.activities.common.views.*;
|
||||
@@ -105,7 +106,7 @@ public class OverviewCard extends HabitCard
|
||||
|
||||
private void initEditMode()
|
||||
{
|
||||
color = ColorUtils.getAndroidTestColor(1);
|
||||
color = PaletteUtils.getAndroidTestColor(1);
|
||||
cache.todayScore = 0.6f;
|
||||
cache.lastMonthScore = 0.42f;
|
||||
cache.lastYearScore = 0.75f;
|
||||
@@ -182,7 +183,7 @@ public class OverviewCard extends HabitCard
|
||||
@Override
|
||||
public void onPreExecute()
|
||||
{
|
||||
color = ColorUtils.getColor(getContext(), getHabit().getColor());
|
||||
color = PaletteUtils.getColor(getContext(), getHabit().getColor());
|
||||
refreshColors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,8 +127,8 @@ public class ScoreCard extends HabitCard
|
||||
if (isInEditMode())
|
||||
{
|
||||
spinner.setVisibility(GONE);
|
||||
title.setTextColor(ColorUtils.getAndroidTestColor(1));
|
||||
chart.setColor(ColorUtils.getAndroidTestColor(1));
|
||||
title.setTextColor(PaletteUtils.getAndroidTestColor(1));
|
||||
chart.setColor(PaletteUtils.getAndroidTestColor(1));
|
||||
chart.populateWithRandomData();
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ public class ScoreCard extends HabitCard
|
||||
public void onPreExecute()
|
||||
{
|
||||
int color =
|
||||
ColorUtils.getColor(getContext(), getHabit().getColor());
|
||||
PaletteUtils.getColor(getContext(), getHabit().getColor());
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class StreakCard extends HabitCard
|
||||
|
||||
private void initEditMode()
|
||||
{
|
||||
int color = ColorUtils.getAndroidTestColor(1);
|
||||
int color = PaletteUtils.getAndroidTestColor(1);
|
||||
title.setTextColor(color);
|
||||
streakChart.setColor(color);
|
||||
streakChart.populateWithRandomData();
|
||||
@@ -111,7 +111,7 @@ public class StreakCard extends HabitCard
|
||||
public void onPreExecute()
|
||||
{
|
||||
int color =
|
||||
ColorUtils.getColor(getContext(), getHabit().getColor());
|
||||
PaletteUtils.getColor(getContext(), getHabit().getColor());
|
||||
title.setTextColor(color);
|
||||
streakChart.setColor(color);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class SubtitleCard extends HabitCard
|
||||
protected void refreshData()
|
||||
{
|
||||
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));
|
||||
questionLabel.setVisibility(VISIBLE);
|
||||
@@ -79,7 +79,7 @@ public class SubtitleCard extends HabitCard
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void initEditMode()
|
||||
{
|
||||
questionLabel.setTextColor(ColorUtils.getAndroidTestColor(1));
|
||||
questionLabel.setTextColor(PaletteUtils.getAndroidTestColor(1));
|
||||
questionLabel.setText("Have you meditated today?");
|
||||
reminderLabel.setText("08:00");
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ package org.isoron.uhabits.activities.settings;
|
||||
import android.os.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.R;
|
||||
|
||||
/**
|
||||
* 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.content.*;
|
||||
import android.net.*;
|
||||
import android.os.*;
|
||||
import android.provider.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.v7.preference.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
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
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
@@ -100,7 +112,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
|
||||
if (key.equals("reminderSound"))
|
||||
{
|
||||
BaseScreen.showRingtonePicker(this, RINGTONE_REQUEST_CODE);
|
||||
showRingtonePicker();
|
||||
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()
|
||||
{
|
||||
String ringtoneName = RingtoneManager.getRingtoneName(getContext());
|
||||
|
||||
@@ -26,9 +26,9 @@ import android.support.v7.widget.Toolbar;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public class FireSettingReceiver extends BroadcastReceiver
|
||||
ReceiverComponent component =
|
||||
DaggerFireSettingReceiver_ReceiverComponent
|
||||
.builder()
|
||||
.habitsComponent(app.getComponent())
|
||||
.habitsApplicationComponent(app.getComponent())
|
||||
.build();
|
||||
|
||||
allHabits = app.getComponent().getHabitList();
|
||||
@@ -100,7 +100,7 @@ public class FireSettingReceiver extends BroadcastReceiver
|
||||
}
|
||||
|
||||
@ReceiverScope
|
||||
@Component(dependencies = HabitsComponent.class)
|
||||
@Component(dependencies = HabitsApplicationComponent.class)
|
||||
interface ReceiverComponent
|
||||
{
|
||||
WidgetBehavior getWidgetController();
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.activeandroid.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.BuildConfig;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.utils.DatabaseUtils;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import android.support.v4.app.*;
|
||||
import android.support.v4.app.NotificationCompat.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
@@ -36,8 +36,8 @@ import org.isoron.uhabits.intents.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
import static android.graphics.BitmapFactory.*;
|
||||
import static org.isoron.uhabits.notifications.RingtoneManager.*;
|
||||
import static android.graphics.BitmapFactory.decodeResource;
|
||||
import static org.isoron.uhabits.notifications.RingtoneManager.getRingtoneUri;
|
||||
|
||||
@AppScope
|
||||
public class AndroidNotificationTray implements NotificationTray.SystemTray
|
||||
|
||||
@@ -26,23 +26,20 @@ import android.preference.*;
|
||||
import android.provider.*;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
import static android.media.RingtoneManager.*;
|
||||
import static android.media.RingtoneManager.EXTRA_RINGTONE_PICKED_URI;
|
||||
import static android.media.RingtoneManager.getRingtone;
|
||||
|
||||
@AppScope
|
||||
public class RingtoneManager
|
||||
{
|
||||
private Context context;
|
||||
|
||||
@Inject
|
||||
public RingtoneManager(@AppContext @NonNull Context context)
|
||||
public RingtoneManager()
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -106,7 +103,6 @@ public class RingtoneManager
|
||||
}
|
||||
else
|
||||
{
|
||||
String off = context.getResources().getString(R.string.none);
|
||||
SharedPreferences prefs =
|
||||
PreferenceManager.getDefaultSharedPreferences(context);
|
||||
prefs.edit().putString("pref_ringtone_uri", "").apply();
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.preference.*;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ConnectivityReceiver extends BroadcastReceiver
|
||||
if (context == null) return;
|
||||
if (intent == null) return;
|
||||
|
||||
HabitsComponent component =
|
||||
HabitsApplicationComponent component =
|
||||
((HabitsApplication) context.getApplicationContext()).getComponent();
|
||||
|
||||
NetworkInfo networkInfo =
|
||||
|
||||
@@ -73,7 +73,7 @@ public class PebbleReceiver extends PebbleDataReceiver
|
||||
HabitsApplication app =
|
||||
(HabitsApplication) context.getApplicationContext();
|
||||
|
||||
HabitsComponent component = app.getComponent();
|
||||
HabitsApplicationComponent component = app.getComponent();
|
||||
commandRunner = component.getCommandRunner();
|
||||
taskRunner = component.getTaskRunner();
|
||||
allHabits = component.getHabitList();
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
|
||||
ReminderComponent component = DaggerReminderReceiver_ReminderComponent
|
||||
.builder()
|
||||
.habitsComponent(app.getComponent())
|
||||
.habitsApplicationComponent(app.getComponent())
|
||||
.build();
|
||||
|
||||
HabitList habits = app.getComponent().getHabitList();
|
||||
@@ -105,7 +105,7 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
}
|
||||
|
||||
@ReceiverScope
|
||||
@Component(dependencies = HabitsComponent.class)
|
||||
@Component(dependencies = HabitsApplicationComponent.class)
|
||||
interface ReminderComponent
|
||||
{
|
||||
ReminderController getReminderController();
|
||||
|
||||
@@ -57,7 +57,7 @@ public class WidgetReceiver extends BroadcastReceiver
|
||||
|
||||
WidgetComponent component = DaggerWidgetReceiver_WidgetComponent
|
||||
.builder()
|
||||
.habitsComponent(app.getComponent())
|
||||
.habitsApplicationComponent(app.getComponent())
|
||||
.build();
|
||||
|
||||
IntentParser parser = app.getComponent().getIntentParser();
|
||||
@@ -94,7 +94,7 @@ public class WidgetReceiver extends BroadcastReceiver
|
||||
}
|
||||
|
||||
@ReceiverScope
|
||||
@Component(dependencies = HabitsComponent.class)
|
||||
@Component(dependencies = HabitsApplicationComponent.class)
|
||||
interface WidgetComponent
|
||||
{
|
||||
WidgetBehavior getWidgetController();
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.BuildConfig;
|
||||
import org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.commands.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
@@ -38,7 +38,17 @@ import io.socket.client.*;
|
||||
import io.socket.client.Socket;
|
||||
import io.socket.emitter.*;
|
||||
|
||||
import static io.socket.client.Socket.*;
|
||||
import static io.socket.client.Socket.EVENT_CONNECT;
|
||||
import static io.socket.client.Socket.EVENT_CONNECTING;
|
||||
import static io.socket.client.Socket.EVENT_CONNECT_ERROR;
|
||||
import static io.socket.client.Socket.EVENT_CONNECT_TIMEOUT;
|
||||
import static io.socket.client.Socket.EVENT_DISCONNECT;
|
||||
import static io.socket.client.Socket.EVENT_PING;
|
||||
import static io.socket.client.Socket.EVENT_PONG;
|
||||
import static io.socket.client.Socket.EVENT_RECONNECT;
|
||||
import static io.socket.client.Socket.EVENT_RECONNECT_ATTEMPT;
|
||||
import static io.socket.client.Socket.EVENT_RECONNECT_ERROR;
|
||||
import static io.socket.client.Socket.EVENT_RECONNECT_FAILED;
|
||||
|
||||
@AppScope
|
||||
public class SyncManager implements CommandRunner.Listener
|
||||
@@ -83,17 +93,17 @@ public class SyncManager implements CommandRunner.Listener
|
||||
|
||||
private boolean isListening;
|
||||
|
||||
private BaseSystem system;
|
||||
private SSLContextProvider sslProvider;
|
||||
|
||||
@Inject
|
||||
public SyncManager(@NonNull BaseSystem system,
|
||||
public SyncManager(@NonNull SSLContextProvider sslProvider,
|
||||
@NonNull Preferences prefs,
|
||||
@NonNull CommandRunner commandRunner,
|
||||
@NonNull CommandParser commandParser)
|
||||
{
|
||||
this.system = system;
|
||||
Log.i("SyncManager", this.toString());
|
||||
|
||||
this.sslProvider = sslProvider;
|
||||
this.prefs = prefs;
|
||||
this.commandRunner = commandRunner;
|
||||
this.commandParser = commandParser;
|
||||
@@ -110,18 +120,6 @@ public class SyncManager implements CommandRunner.Listener
|
||||
connect(serverURL);
|
||||
}
|
||||
|
||||
private JSONObject toJSONObject(String json)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new JSONObject(json);
|
||||
}
|
||||
catch (JSONException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandExecuted(@NonNull Command command,
|
||||
@Nullable Long refreshKey)
|
||||
@@ -141,8 +139,8 @@ public class SyncManager implements CommandRunner.Listener
|
||||
|
||||
public void onNetworkStatusChanged(boolean isConnected)
|
||||
{
|
||||
if(!isListening) return;
|
||||
if(isConnected) socket.connect();
|
||||
if (!isListening) return;
|
||||
if (isConnected) socket.connect();
|
||||
else socket.disconnect();
|
||||
}
|
||||
|
||||
@@ -159,7 +157,7 @@ public class SyncManager implements CommandRunner.Listener
|
||||
|
||||
public void stopListening()
|
||||
{
|
||||
if(!isListening) return;
|
||||
if (!isListening) return;
|
||||
|
||||
commandRunner.removeListener(this);
|
||||
socket.close();
|
||||
@@ -170,7 +168,7 @@ public class SyncManager implements CommandRunner.Listener
|
||||
{
|
||||
try
|
||||
{
|
||||
IO.setDefaultSSLContext(system.getCACertSSLContext());
|
||||
IO.setDefaultSSLContext(sslProvider.getCACertSSLContext());
|
||||
socket = IO.socket(serverURL);
|
||||
|
||||
logSocketEvent(socket, EVENT_CONNECT, "Connected");
|
||||
@@ -228,6 +226,18 @@ public class SyncManager implements CommandRunner.Listener
|
||||
});
|
||||
}
|
||||
|
||||
private JSONObject toJSONObject(String json)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new JSONObject(json);
|
||||
}
|
||||
catch (JSONException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLastSync(Long timestamp)
|
||||
{
|
||||
prefs.setLastSync(timestamp + 1);
|
||||
@@ -292,7 +302,7 @@ public class SyncManager implements CommandRunner.Listener
|
||||
public void call(Object... args)
|
||||
{
|
||||
readyToEmit = false;
|
||||
for(Event e : pendingConfirmation) pendingEmit.add(e);
|
||||
for (Event e : pendingConfirmation) pendingEmit.add(e);
|
||||
pendingConfirmation.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@ public class ExportDBTask implements Task
|
||||
@NonNull
|
||||
private Context context;
|
||||
|
||||
private BaseSystem system;
|
||||
private AndroidDirFinder system;
|
||||
|
||||
@NonNull
|
||||
private final Listener listener;
|
||||
|
||||
public ExportDBTask(@Provided @AppContext @NonNull Context context,
|
||||
@Provided @NonNull BaseSystem system,
|
||||
@Provided @NonNull AndroidDirFinder system,
|
||||
@NonNull Listener listener)
|
||||
{
|
||||
this.system = system;
|
||||
|
||||
@@ -21,10 +21,8 @@ package org.isoron.uhabits.utils;
|
||||
|
||||
import android.content.*;
|
||||
import android.text.format.*;
|
||||
import android.text.format.DateUtils;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,125 +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.utils;
|
||||
|
||||
import android.content.*;
|
||||
import android.graphics.*;
|
||||
import android.util.*;
|
||||
|
||||
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)
|
||||
{
|
||||
final byte ALPHA_CHANNEL = 24;
|
||||
final byte RED_CHANNEL = 16;
|
||||
final byte GREEN_CHANNEL = 8;
|
||||
final byte BLUE_CHANNEL = 0;
|
||||
|
||||
final float inverseAmount = 1.0f - amount;
|
||||
|
||||
int a = ((int) (((float) (color1 >> ALPHA_CHANNEL & 0xff) * amount) +
|
||||
((float) (color2 >> ALPHA_CHANNEL & 0xff) *
|
||||
inverseAmount))) & 0xff;
|
||||
int r = ((int) (((float) (color1 >> RED_CHANNEL & 0xff) * amount) +
|
||||
((float) (color2 >> RED_CHANNEL & 0xff) *
|
||||
inverseAmount))) & 0xff;
|
||||
int g = ((int) (((float) (color1 >> GREEN_CHANNEL & 0xff) * amount) +
|
||||
((float) (color2 >> GREEN_CHANNEL & 0xff) *
|
||||
inverseAmount))) & 0xff;
|
||||
int b = ((int) (((float) (color1 & 0xff) * amount) +
|
||||
((float) (color2 & 0xff) * inverseAmount))) & 0xff;
|
||||
|
||||
return a << ALPHA_CHANNEL | r << RED_CHANNEL | g << GREEN_CHANNEL |
|
||||
b << BLUE_CHANNEL;
|
||||
}
|
||||
|
||||
public static int setAlpha(int color, float newAlpha)
|
||||
{
|
||||
int intAlpha = (int) (newAlpha * 255);
|
||||
return Color.argb(intAlpha, Color.red(color), Color.green(color),
|
||||
Color.blue(color));
|
||||
}
|
||||
|
||||
public static int setMinValue(int color, float newValue)
|
||||
{
|
||||
float hsv[] = new float[3];
|
||||
Color.colorToHSV(color, hsv);
|
||||
hsv[2] = Math.max(hsv[2], newValue);
|
||||
return Color.HSVToColor(hsv);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,102 +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.utils;
|
||||
|
||||
import android.content.*;
|
||||
import android.content.res.*;
|
||||
import android.graphics.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.v4.view.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
public abstract class InterfaceUtils
|
||||
{
|
||||
private static Typeface fontAwesome;
|
||||
|
||||
@Nullable
|
||||
private static Float fixedResolution = null;
|
||||
|
||||
public static void setFixedResolution(@NonNull Float f)
|
||||
{
|
||||
fixedResolution = f;
|
||||
}
|
||||
|
||||
public static Typeface getFontAwesome(Context context)
|
||||
{
|
||||
if(fontAwesome == null) fontAwesome =
|
||||
Typeface.createFromAsset(context.getAssets(),
|
||||
"fontawesome-webfont.ttf");
|
||||
|
||||
return fontAwesome;
|
||||
}
|
||||
|
||||
public static float dpToPixels(Context context, float dp)
|
||||
{
|
||||
if(fixedResolution != null) return dp * fixedResolution;
|
||||
|
||||
Resources resources = context.getResources();
|
||||
DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
|
||||
}
|
||||
|
||||
public static float spToPixels(Context context, float sp)
|
||||
{
|
||||
if(fixedResolution != null) return sp * fixedResolution;
|
||||
|
||||
Resources resources = context.getResources();
|
||||
DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, metrics);
|
||||
}
|
||||
|
||||
public static float getDimension(Context context, int id)
|
||||
{
|
||||
float dim = context.getResources().getDimension(id);
|
||||
if (fixedResolution == null) return dim;
|
||||
else
|
||||
{
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
float actualDensity = dm.density;
|
||||
return dim / actualDensity * fixedResolution;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupEditorAction(@NonNull ViewGroup parent,
|
||||
@NonNull TextView.OnEditorActionListener listener)
|
||||
{
|
||||
for (int i = 0; i < parent.getChildCount(); i++)
|
||||
{
|
||||
View child = parent.getChildAt(i);
|
||||
|
||||
if (child instanceof ViewGroup)
|
||||
setupEditorAction((ViewGroup) child, listener);
|
||||
|
||||
if (child instanceof TextView)
|
||||
((TextView) child).setOnEditorActionListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isLayoutRtl(View view)
|
||||
{
|
||||
return ViewCompat.getLayoutDirection(view) ==
|
||||
ViewCompat.LAYOUT_DIRECTION_RTL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.isoron.uhabits.utils;
|
||||
|
||||
import android.content.*;
|
||||
import android.graphics.*;
|
||||
import android.util.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
|
||||
public class PaletteUtils
|
||||
{
|
||||
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];
|
||||
}
|
||||
}
|
||||
@@ -1,107 +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.utils;
|
||||
|
||||
import android.content.*;
|
||||
import android.content.res.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
|
||||
public class StyledResources
|
||||
{
|
||||
private static Integer fixedTheme;
|
||||
|
||||
private final Context context;
|
||||
|
||||
public StyledResources(@NonNull Context context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static void setFixedTheme(Integer theme)
|
||||
{
|
||||
fixedTheme = theme;
|
||||
}
|
||||
|
||||
public boolean getBoolean(@AttrRes int attrId)
|
||||
{
|
||||
TypedArray ta = getTypedArray(attrId);
|
||||
boolean bool = ta.getBoolean(0, false);
|
||||
ta.recycle();
|
||||
|
||||
return bool;
|
||||
}
|
||||
|
||||
public int getColor(@AttrRes int attrId)
|
||||
{
|
||||
TypedArray ta = getTypedArray(attrId);
|
||||
int color = ta.getColor(0, 0);
|
||||
ta.recycle();
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
public Drawable getDrawable(@AttrRes int attrId)
|
||||
{
|
||||
TypedArray ta = getTypedArray(attrId);
|
||||
Drawable drawable = ta.getDrawable(0);
|
||||
ta.recycle();
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public float getFloat(@AttrRes int attrId)
|
||||
{
|
||||
TypedArray ta = getTypedArray(attrId);
|
||||
float f = ta.getFloat(0, 0);
|
||||
ta.recycle();
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public int[] getPalette()
|
||||
{
|
||||
int resourceId = getStyleResource(R.attr.palette);
|
||||
if (resourceId < 0) throw new RuntimeException("resource not found");
|
||||
|
||||
return context.getResources().getIntArray(resourceId);
|
||||
}
|
||||
|
||||
int getStyleResource(@AttrRes int attrId)
|
||||
{
|
||||
TypedArray ta = getTypedArray(attrId);
|
||||
int resourceId = ta.getResourceId(0, -1);
|
||||
ta.recycle();
|
||||
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
private TypedArray getTypedArray(@AttrRes int attrId)
|
||||
{
|
||||
int[] attrs = new int[]{ attrId };
|
||||
|
||||
if (fixedTheme != null)
|
||||
return context.getTheme().obtainStyledAttributes(fixedTheme, attrs);
|
||||
|
||||
return context.obtainStyledAttributes(attrs);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user