diff --git a/Task3. TaskManager/TaskManager/.idea/dictionaries/JeMinay.xml b/Task3. TaskManager/TaskManager/.idea/dictionaries/JeMinay.xml
index f14db48..26f13c9 100644
--- a/Task3. TaskManager/TaskManager/.idea/dictionaries/JeMinay.xml
+++ b/Task3. TaskManager/TaskManager/.idea/dictionaries/JeMinay.xml
@@ -2,7 +2,9 @@
itemlist
+ resultable
showable
+ thenable
unsubscribe
diff --git a/Task3. TaskManager/TaskManager/.idea/inspectionProfiles/Project_Default.xml b/Task3. TaskManager/TaskManager/.idea/inspectionProfiles/Project_Default.xml
index 8f908f4..5878c7a 100644
--- a/Task3. TaskManager/TaskManager/.idea/inspectionProfiles/Project_Default.xml
+++ b/Task3. TaskManager/TaskManager/.idea/inspectionProfiles/Project_Default.xml
@@ -1,11 +1,13 @@
+
+
diff --git a/Task3. TaskManager/TaskManager/.idea/kotlinc.xml b/Task3. TaskManager/TaskManager/.idea/kotlinc.xml
new file mode 100644
index 0000000..1c24f9a
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/.idea/kotlinc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/.idea/misc.xml b/Task3. TaskManager/TaskManager/.idea/misc.xml
index fbb6828..d2e6725 100644
--- a/Task3. TaskManager/TaskManager/.idea/misc.xml
+++ b/Task3. TaskManager/TaskManager/.idea/misc.xml
@@ -27,16 +27,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/Task3. TaskManager/TaskManager/app/build.gradle b/Task3. TaskManager/TaskManager/app/build.gradle
index db2caf6..d610082 100644
--- a/Task3. TaskManager/TaskManager/app/build.gradle
+++ b/Task3. TaskManager/TaskManager/app/build.gradle
@@ -46,6 +46,7 @@ dependencies {
compile 'com.github.javiersantos:BottomDialogs:1.2.1'
compile 'com.daasuu:animateHorizontalProgressBar:0.2.4'
compile 'com.github.florent37:singledateandtimepicker:1.1.0'
+ compile 'com.loopj.android:android-async-http:1.4.9'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
diff --git a/Task3. TaskManager/TaskManager/app/src/main/AndroidManifest.xml b/Task3. TaskManager/TaskManager/app/src/main/AndroidManifest.xml
index 6ff8e26..4217f88 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/AndroidManifest.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/AndroidManifest.xml
@@ -3,6 +3,8 @@
package="ru.urfu.taskmanager">
+
+
@@ -15,10 +17,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
+
@@ -26,10 +27,15 @@
+
+
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/Application.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/Application.java
index 161b45a..1439173 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/Application.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/Application.java
@@ -1,12 +1,16 @@
package ru.urfu.taskmanager;
+import android.content.BroadcastReceiver;
+
import ru.urfu.taskmanager.color_picker.recent.RecentColorsStorage;
import ru.urfu.taskmanager.task_manager.main.filter.FiltersStorage;
-import ru.urfu.taskmanager.utils.db.DbTasks;
+import ru.urfu.taskmanager.data.db.DbTasks;
import ru.urfu.taskmanager.utils.tools.SizeManager;
public class Application extends android.app.Application
{
+ private BroadcastReceiver apiSyncReceiver;
+
@Override
public void onCreate() {
super.onCreate();
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/auth/LoginActivity.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/auth/LoginActivity.java
new file mode 100644
index 0000000..7716ff3
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/auth/LoginActivity.java
@@ -0,0 +1,44 @@
+package ru.urfu.taskmanager.auth;
+
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.widget.EditText;
+
+import org.androidannotations.annotations.AfterViews;
+import org.androidannotations.annotations.Click;
+import org.androidannotations.annotations.EActivity;
+import org.androidannotations.annotations.ViewById;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity_;
+
+@EActivity(R.layout.activity_login)
+public class LoginActivity extends AppCompatActivity
+{
+ @ViewById(R.id.loginEditText)
+ EditText mLoginEditText;
+
+ @AfterViews
+ public void init() {
+ if (User.getActiveUser() != null) {
+ afterLogin();
+ }
+ }
+
+ @Click(R.id.loginButton)
+ public void doLogin() {
+ String login = mLoginEditText.getText().toString();
+ if (!login.isEmpty()) {
+ User.doLogin(getApplicationContext(), login);
+ afterLogin();
+ }
+ }
+
+ private void afterLogin() {
+ Intent intent = new Intent(this, TaskManagerActivity_.class);
+ startActivity(intent);
+
+ finish();
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/auth/models/User.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/auth/models/User.java
new file mode 100644
index 0000000..e3f0eee
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/auth/models/User.java
@@ -0,0 +1,60 @@
+package ru.urfu.taskmanager.auth.models;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.provider.Settings;
+
+import ru.urfu.taskmanager.data.network.APIServiceExecutor;
+import ru.urfu.taskmanager.data.network.APIService;
+
+public class User
+{
+ private static User activeUser;
+
+ private int mId;
+ private String mLogin;
+ private APIService mApiService;
+ private APIServiceExecutor mAPIServiceExecutor;
+ private String deviceIdentifier;
+
+
+ private User(Context context, String mLogin) {
+ this.mId = Math.abs(mLogin.hashCode());
+ this.mLogin = mLogin;
+ this.deviceIdentifier = initDeviceId(context);
+ this.mAPIServiceExecutor = new APIServiceExecutor(context, mApiService = new APIService(this));
+ }
+
+ public int getUserId() {
+ return mId;
+ }
+
+ public String getDeviceIdentifier() {
+ return deviceIdentifier;
+ }
+
+ public String getLogin() {
+ return mLogin;
+ }
+
+ public APIServiceExecutor getExecutor() {
+ return mAPIServiceExecutor;
+ }
+
+ public APIService getService() {
+ return mApiService;
+ }
+
+ @SuppressLint("HardwareIds")
+ private static String initDeviceId(Context context) {
+ return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+ }
+
+ public static void doLogin(Context context, String login) {
+ activeUser = new User(context, login);
+ }
+
+ public static User getActiveUser() {
+ return activeUser;
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/BackupManager.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/BackupManager.java
similarity index 92%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/BackupManager.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/BackupManager.java
index c029b6f..5ffb6c7 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/BackupManager.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/BackupManager.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.task_manager.main.tools;
+package ru.urfu.taskmanager.data.backup;
import android.os.Build;
import android.os.Handler;
@@ -22,8 +22,7 @@
import java.util.ArrayList;
import java.util.List;
-import ru.urfu.taskmanager.utils.db.async.ExecuteController;
-import ru.urfu.taskmanager.utils.tools.JSONFactory;
+import ru.urfu.taskmanager.data.db.async.ExecuteController;
public class BackupManager extends HandlerThread
{
@@ -52,7 +51,7 @@ public void exportTo(DataProvider provider) {
try {
outputStream = new FileOutputStream(file);
BufferedWriter bufferedWriter;
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,
StandardCharsets.UTF_8));
} else {
@@ -84,7 +83,7 @@ public void importFrom(InputStream inputStream, Class _class, ExecuteCont
.create();
try {
InputStreamReader streamReader;
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
streamReader = new InputStreamReader(inputStream,
StandardCharsets.UTF_8);
} else {
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/DataExportController.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/DataExportController.java
similarity index 96%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/DataExportController.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/DataExportController.java
index 3af2a68..cd1fcc5 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/DataExportController.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/DataExportController.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.task_manager.main.tools;
+package ru.urfu.taskmanager.data.backup;
import android.app.NotificationManager;
import android.content.Context;
@@ -7,7 +7,7 @@
import java.util.List;
import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.utils.db.async.ExecuteControllerAdapter;
+import ru.urfu.taskmanager.data.db.async.ExecuteControllerAdapter;
import ru.urfu.taskmanager.utils.interfaces.Progressive;
public class DataExportController extends ExecuteControllerAdapter>
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/DataImportController.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/DataImportController.java
similarity index 94%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/DataImportController.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/DataImportController.java
index 60f2194..161bdad 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/DataImportController.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/DataImportController.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.task_manager.main.tools;
+package ru.urfu.taskmanager.data.backup;
import android.app.NotificationManager;
import android.content.Context;
@@ -7,9 +7,9 @@
import java.util.List;
import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.data.db.async.DbAsyncExecutor;
+import ru.urfu.taskmanager.data.db.async.ExecuteControllerAdapter;
import ru.urfu.taskmanager.task_manager.main.view.TaskManager;
-import ru.urfu.taskmanager.utils.db.async.DbAsyncExecutor;
-import ru.urfu.taskmanager.utils.db.async.ExecuteControllerAdapter;
import ru.urfu.taskmanager.utils.interfaces.Callback;
public class DataImportController extends ExecuteControllerAdapter>
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/TasksGenerator.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/TasksGenerator.java
similarity index 93%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/TasksGenerator.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/TasksGenerator.java
index 2342564..2434be9 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/tools/TasksGenerator.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/backup/TasksGenerator.java
@@ -1,19 +1,17 @@
-package ru.urfu.taskmanager.task_manager.main.tools;
+package ru.urfu.taskmanager.data.backup;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Color;
import android.support.v4.app.NotificationCompat;
-import org.androidannotations.annotations.res.StringRes;
-
import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.data.db.DbTasks;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.async.AsyncExecutor;
+import ru.urfu.taskmanager.data.db.async.ExecuteControllerAdapter;
import ru.urfu.taskmanager.task_manager.main.presenter.TaskManagerPresenter;
import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.utils.db.async.AsyncExecutor;
-import ru.urfu.taskmanager.utils.db.DbTasks;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
-import ru.urfu.taskmanager.utils.db.async.ExecuteControllerAdapter;
import ru.urfu.taskmanager.utils.interfaces.Progressive;
public class TasksGenerator
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbFilter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbFilter.java
similarity index 70%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbFilter.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbFilter.java
index 9f81a43..e042d17 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbFilter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbFilter.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.utils.db;
+package ru.urfu.taskmanager.data.db;
public interface DbFilter
{
@@ -13,4 +13,8 @@ public interface DbFilter
String getHaving();
String getOrderBy();
+
+ boolean isOrdered();
+
+ int getType();
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasks.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasks.java
similarity index 77%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasks.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasks.java
index 86649e3..1632e4e 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasks.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasks.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.utils.db;
+package ru.urfu.taskmanager.data.db;
import android.content.ContentValues;
import android.content.Context;
@@ -8,12 +8,11 @@
import java.util.ArrayList;
import java.util.List;
+import ru.urfu.taskmanager.auth.models.User;
import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.utils.db.async.DbAsyncExecutor;
+import ru.urfu.taskmanager.data.db.async.DbAsyncExecutor;
import ru.urfu.taskmanager.utils.interfaces.Callback;
-import static ru.urfu.taskmanager.utils.db.DbTasksFilter.COMPLETED_TASK;
-
public class DbTasks implements SimpleDatabase
{
private static DbTasks sInstance;
@@ -41,18 +40,20 @@ public List getAllEntries() {
}
@Override
- public void insertEntry(TaskEntry entry) {
- mDatabase.insert(DbTasksHelper.TABLE_NAME, null, contentValuesFrom(entry));
+ public long insertEntry(TaskEntry entry) {
+ long id = mDatabase.insert(DbTasksHelper.TABLE_NAME, null, contentValuesFrom(entry));
+ updateEntry(getEntryById((int) id).setOrder((int) id));
+ return id;
}
@Override
public void removeEntryById(int id) {
- mDatabase.delete(DbTasksHelper.TABLE_NAME, DbTasksHelper.ID + " = " + id, null);
+ mDatabase.delete(DbTasksHelper.TABLE_NAME, DbTasksHelper.ID + "=" + id, null);
}
@Override
public TaskEntry updateEntry(TaskEntry entry) {
- mDatabase.update(DbTasksHelper.TABLE_NAME, contentValuesFrom(entry), DbTasksHelper.ID + " = " + entry.getId(), null);
+ mDatabase.update(DbTasksHelper.TABLE_NAME, contentValuesFrom(entry), DbTasksHelper.ID + "=" + entry.getId(), null);
return getEntryById(entry.getId());
}
@@ -82,6 +83,18 @@ public TaskEntry getEntryById(int id) {
return getCurrentEntryFromCursor(cursor);
}
+ public TaskEntry getEntryByEntryId(int entryId) {
+ Cursor cursor = mDatabase.rawQuery("SELECT * FROM " +
+ DbTasksHelper.TABLE_NAME + " WHERE " +
+ DbTasksHelper.ENTRY_ID + "=" + entryId + " AND " +
+ DbTasksHelper.USER_ID + "=" + User.getActiveUser().getUserId(), null);
+
+ if (cursor.getCount() == 0) return null;
+
+ cursor.moveToFirst();
+ return getCurrentEntryFromCursor(cursor);
+ }
+
@Override
public void replaceAll(List entries) {
mDatabase.delete(DbTasksHelper.TABLE_NAME, null, null);
@@ -94,25 +107,27 @@ public void replaceAll(List entries) {
public TaskEntry getCurrentEntryFromCursor(Cursor cursor) {
int id = cursor.getColumnIndex(DbTasksHelper.ID);
+ int order = cursor.getColumnIndex(DbTasksHelper.ORDER);
int title = cursor.getColumnIndex(DbTasksHelper.TITLE);
+ int entry_id = cursor.getColumnIndex(DbTasksHelper.ENTRY_ID);
+ int image_url = cursor.getColumnIndex(DbTasksHelper.IMAGE_URL);
int timetolive = cursor.getColumnIndex(DbTasksHelper.TTL);
int time_edited = cursor.getColumnIndex(DbTasksHelper.TIME_EDITED);
int time_created = cursor.getColumnIndex(DbTasksHelper.TIME_CREATED);
int description = cursor.getColumnIndex(DbTasksHelper.DESCRIPTION);
- int isCompleted = cursor.getColumnIndex(DbTasksHelper.COMPLETED);
int decorate_color = cursor.getColumnIndex(DbTasksHelper.DECORATE_COLOR);
- int image_url = cursor.getColumnIndex(DbTasksHelper.IMAGE_URL);
return new TaskEntry(cursor.getInt(id))
+ .setId(cursor.getInt(id))
+ .setOrder(cursor.getInt(order))
+ .setEntryId(cursor.getInt(entry_id))
.setTitle(cursor.getString(title))
.setDescription(cursor.getString(description))
- .setTtl(Long.valueOf(cursor.getString(timetolive)))
.setCreated(Long.valueOf(cursor.getString(time_created)))
.setEdited(Long.valueOf(cursor.getString(time_edited)))
.setTtl(Long.valueOf(cursor.getString(timetolive)))
.setColor(cursor.getInt(decorate_color))
- .setImageUrl(cursor.getString(image_url))
- .setCompleted(cursor.getInt(isCompleted) == COMPLETED_TASK);
+ .setImageUrl(cursor.getString(image_url));
}
public Cursor getCursor(DbFilter filter) {
@@ -133,22 +148,35 @@ public DbAsyncExecutor getAsyncExecutor() {
private ContentValues contentValuesFrom(TaskEntry entry) {
ContentValues values = new ContentValues();
+
+ if (entry.getEntryId() != null)
+ values.put(DbTasksHelper.ENTRY_ID, entry.getEntryId());
+
if (entry.getTtl() != null)
values.put(DbTasksHelper.TTL, entry.getTtlTimestamp());
+
if (entry.getTitle() != null)
values.put(DbTasksHelper.TITLE, entry.getTitle());
+
if (entry.getDescription() != null)
values.put(DbTasksHelper.DESCRIPTION, entry.getDescription());
+
if (entry.getEdited() != null)
values.put(DbTasksHelper.TIME_EDITED, entry.getEditedTimestamp());
+
if (entry.getCreated() != null)
values.put(DbTasksHelper.TIME_CREATED, entry.getCreatedTimestamp());
+
if (entry.getColor() != null)
values.put(DbTasksHelper.DECORATE_COLOR, entry.getColorInt());
+
if (entry.getImageUrl() != null)
values.put(DbTasksHelper.IMAGE_URL, entry.getImageUrl());
- values.put(DbTasksHelper.COMPLETED, entry.isCompleted());
+ if (entry.getOrder() != null)
+ values.put(DbTasksHelper.ORDER, entry.getOrder());
+
+ values.put(DbTasksHelper.USER_ID, User.getActiveUser().getUserId());
return values;
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasksFilter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasksFilter.java
similarity index 86%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasksFilter.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasksFilter.java
index fa221fa..1f683b5 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasksFilter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasksFilter.java
@@ -1,8 +1,10 @@
-package ru.urfu.taskmanager.utils.db;
+package ru.urfu.taskmanager.data.db;
import java.util.ArrayList;
import java.util.List;
+import ru.urfu.taskmanager.auth.models.User;
+
import static android.text.format.DateUtils.DAY_IN_MILLIS;
public class DbTasksFilter implements DbFilter
@@ -45,6 +47,8 @@ public String[] getColumns() {
}
public String getWhereClause() {
+ mWhereClause.add(DbTasksHelper.USER_ID + "=" + User.getActiveUser().getUserId());
+
StringBuilder builder = new StringBuilder();
for (int i = 0; i < mWhereClause.size(); i++) {
builder.append(mWhereClause.get(i));
@@ -76,6 +80,10 @@ public String getOrderBy() {
return mOrderBy + " " + mOrientation;
}
+ public boolean isOrdered() {
+ return mOrderBy.equals(DbTasksHelper.ORDER);
+ }
+
public int getType() {
return mType;
}
@@ -102,9 +110,18 @@ public boolean isDefault() {
public Builder setType(int type) {
mFilter.mType = type;
- if (type != ALL_TASK) {
- mFilter.mWhereClause.add(DbTasksHelper.COMPLETED + "=" + String.valueOf(type));
+
+ switch (type) {
+ case ALL_TASK:
+ break;
+ case ACTIVE_TASK:
+ mFilter.mWhereClause.add(DbTasksHelper.TIME_EDITED + "!=" + DbTasksHelper.TTL);
+ break;
+ case COMPLETED_TASK:
+ mFilter.mWhereClause.add(DbTasksHelper.TIME_EDITED + "=" + DbTasksHelper.TTL);
+ break;
}
+
return this;
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasksHelper.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasksHelper.java
similarity index 77%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasksHelper.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasksHelper.java
index 5c0b16c..967f4e2 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/DbTasksHelper.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/DbTasksHelper.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.utils.db;
+package ru.urfu.taskmanager.data.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
@@ -11,13 +11,15 @@ public class DbTasksHelper extends SQLiteOpenHelper
public static final int DATABASE_VERSION = 1;
public static final String ID = "_id";
+ public static final String ORDER = "_order";
+ public static final String USER_ID = "_user_id";
+ public static final String ENTRY_ID = "_entry_id";
public static final String TITLE = "_title";
public static final String DESCRIPTION = "_description";
public static final String TTL = "_timetolive";
public static final String TIME_CREATED = "_time_created";
public static final String TIME_EDITED = "_time_edited";
public static final String DECORATE_COLOR = "_decorate_color";
- public static final String COMPLETED = "_completed";
public static final String IMAGE_URL = "_img_url";
public DbTasksHelper(Context context) {
@@ -27,15 +29,17 @@ public DbTasksHelper(Context context) {
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL("create table " + TABLE_NAME + "(" +
- ID + " integer primary key," +
+ ID + " integer primary key autoincrement," +
+ ORDER + " integer," +
+ USER_ID + " integer," +
+ ENTRY_ID + " integer," +
TITLE + " text," +
DESCRIPTION + " text," +
TTL + " text," +
TIME_CREATED + " text," +
TIME_EDITED + " text," +
IMAGE_URL + " text," +
- DECORATE_COLOR + " integer," +
- COMPLETED + " integer" + ")"
+ DECORATE_COLOR + " integer" + ")"
);
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/SimpleDatabase.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/SimpleDatabase.java
similarity index 78%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/SimpleDatabase.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/SimpleDatabase.java
index bf027e6..281d0c0 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/SimpleDatabase.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/SimpleDatabase.java
@@ -1,10 +1,9 @@
-package ru.urfu.taskmanager.utils.db;
+package ru.urfu.taskmanager.data.db;
import android.database.Cursor;
import java.util.List;
-import ru.urfu.taskmanager.task_manager.models.TaskEntry;
import ru.urfu.taskmanager.utils.interfaces.Callback;
public interface SimpleDatabase
@@ -13,7 +12,7 @@ public interface SimpleDatabase
T getEntryById(int id);
- void insertEntry(T entry);
+ long insertEntry(T entry);
void removeEntryById(int id);
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/AsyncExecutor.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/AsyncExecutor.java
similarity index 80%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/AsyncExecutor.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/AsyncExecutor.java
index fc33f2a..abe19a2 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/AsyncExecutor.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/AsyncExecutor.java
@@ -1,11 +1,11 @@
-package ru.urfu.taskmanager.utils.db.async;
+package ru.urfu.taskmanager.data.db.async;
import android.database.Cursor;
import android.support.annotation.NonNull;
import java.util.List;
-import ru.urfu.taskmanager.utils.db.DbFilter;
+import ru.urfu.taskmanager.data.db.DbFilter;
public interface AsyncExecutor
@@ -16,11 +16,11 @@ public interface AsyncExecutor
void insertEntry(@NonNull T entry);
- void insertEntry(@NonNull T entry, @NonNull ExecuteController controller);
+ void insertEntry(@NonNull T entry, @NonNull ExecuteController controller);
void removeEntryById(int id);
- void removeEntryById(int id, @NonNull ExecuteController controller);
+ void removeEntryById(int id, @NonNull ExecuteController controller);
void updateEntry(@NonNull T entry);
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/DbAsyncExecutor.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/DbAsyncExecutor.java
similarity index 90%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/DbAsyncExecutor.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/DbAsyncExecutor.java
index b7a0a15..db1be05 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/DbAsyncExecutor.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/DbAsyncExecutor.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.utils.db.async;
+package ru.urfu.taskmanager.data.db.async;
import android.database.Cursor;
import android.os.AsyncTask;
@@ -9,9 +9,9 @@
import java.util.ArrayList;
import java.util.List;
-import ru.urfu.taskmanager.utils.db.DbFilter;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
-import ru.urfu.taskmanager.utils.db.SimpleDatabase;
+import ru.urfu.taskmanager.data.db.DbFilter;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.SimpleDatabase;
public class DbAsyncExecutor extends HandlerThread implements AsyncExecutor
{
@@ -93,11 +93,11 @@ public void insertEntry(@NonNull T entry) {
}
@Override
- public void insertEntry(@NonNull T entry, @NonNull ExecuteController controller) {
+ public void insertEntry(@NonNull T entry, @NonNull ExecuteController controller) {
mWorkerHandler.post(() -> {
controller.onStart();
- mDatabase.insertEntry(entry);
- controller.onFinish(null);
+ T inserted = mDatabase.getEntryById((int) mDatabase.insertEntry(entry));
+ controller.onFinish(inserted);
});
}
@@ -107,11 +107,12 @@ public void removeEntryById(int id) {
}
@Override
- public void removeEntryById(int id, @NonNull ExecuteController controller) {
+ public void removeEntryById(int id, @NonNull ExecuteController controller) {
mWorkerHandler.post(() -> {
controller.onStart();
+ T entry = mDatabase.getEntryById(id);
mDatabase.removeEntryById(id);
- controller.onFinish(null);
+ controller.onFinish(entry);
});
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/ExecuteController.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/ExecuteController.java
similarity index 80%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/ExecuteController.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/ExecuteController.java
index 6ea3931..bb35980 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/ExecuteController.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/ExecuteController.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.utils.db.async;
+package ru.urfu.taskmanager.data.db.async;
import android.support.annotation.Nullable;
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/ExecuteControllerAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/ExecuteControllerAdapter.java
similarity index 95%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/ExecuteControllerAdapter.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/ExecuteControllerAdapter.java
index 8affa42..e500404 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/db/async/ExecuteControllerAdapter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/db/async/ExecuteControllerAdapter.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.utils.db.async;
+package ru.urfu.taskmanager.data.db.async;
import android.app.NotificationManager;
import android.support.annotation.Nullable;
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APICallback.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APICallback.java
new file mode 100644
index 0000000..563af96
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APICallback.java
@@ -0,0 +1,14 @@
+package ru.urfu.taskmanager.data.network;
+
+public abstract class APICallback implements APICallbackInterface
+{
+ @Override
+ public void onResponse(APIResponse response) {
+ // Stub!
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ t.printStackTrace();
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APICallbackInterface.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APICallbackInterface.java
new file mode 100644
index 0000000..2e3d1b2
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APICallbackInterface.java
@@ -0,0 +1,8 @@
+package ru.urfu.taskmanager.data.network;
+
+public interface APICallbackInterface
+{
+ void onResponse(APIResponse response);
+
+ void onFailure(Throwable t);
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIRequest.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIRequest.java
new file mode 100644
index 0000000..e451e91
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIRequest.java
@@ -0,0 +1,115 @@
+package ru.urfu.taskmanager.data.network;
+
+import android.accounts.NetworkErrorException;
+import android.net.ParseException;
+
+import com.google.gson.reflect.TypeToken;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+
+import cz.msebera.android.httpclient.client.methods.CloseableHttpResponse;
+import cz.msebera.android.httpclient.client.methods.HttpUriRequest;
+import cz.msebera.android.httpclient.impl.client.CloseableHttpClient;
+import cz.msebera.android.httpclient.impl.client.HttpClientBuilder;
+import ru.urfu.taskmanager.utils.tools.JSONFactory;
+
+public class APIRequest
+{
+ private HttpUriRequest request;
+ private Type parseType;
+
+ public APIRequest(HttpUriRequest request) {
+ this.request = request;
+ }
+
+ public APIRequest(HttpUriRequest request, Type type) {
+ this.request = request;
+ this.parseType = type;
+ }
+
+ public void send() {
+ send(new APICallbackInterface()
+ {
+ @Override
+ public void onResponse(APIResponse response) {
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ t.printStackTrace();
+ }
+ });
+ }
+
+ public void send(APICallbackInterface cb)
+ {
+ new Thread(() ->
+ {
+ CloseableHttpClient client = null;
+ CloseableHttpResponse response = null;
+
+ try
+ {
+ client = HttpClientBuilder.create().build();
+ response = client.execute(request);
+
+ APIResponse apiResponse = null;
+
+ if(response.getEntity() != null)
+ {
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(response.getEntity().getContent()));
+
+ StringBuilder stringBuilder = new StringBuilder();
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ stringBuilder.append(line);
+ }
+
+ if (parseType != null) {
+ apiResponse = JSONFactory.fromJson(stringBuilder.toString(),
+ TypeToken.getParameterized(APIResponse.class, parseType).getType());
+ } else {
+ apiResponse = JSONFactory.fromJson(stringBuilder.toString(),
+ new TypeToken>(){}.getType());
+ }
+
+ reader.close();
+ }
+
+ if (apiResponse != null) {
+ if (apiResponse.getStatus().equals(APIResponse.STATUS_OK)) {
+ cb.onResponse(apiResponse);
+ } else {
+ cb.onFailure(new NetworkErrorException("The server response is different than expected."));
+ }
+ } else {
+ cb.onFailure(new NetworkErrorException("The server did not receive a reply."));
+ }
+ }
+ catch (IOException | ParseException e)
+ {
+ cb.onFailure(e);
+ e.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ if (response != null) response.close();
+ if (client != null) client.close();
+ }
+ catch (IOException e)
+ {
+ cb.onFailure(e);
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+}
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIResponse.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIResponse.java
new file mode 100644
index 0000000..29c5b60
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIResponse.java
@@ -0,0 +1,32 @@
+package ru.urfu.taskmanager.data.network;
+
+import com.google.gson.annotations.SerializedName;
+
+public class APIResponse
+{
+ public static final String STATUS_OK = "ok";
+
+ public static final String PARSE_ERROR = "parse_error";
+ public static final String QUERY_FAILED = "query_failed";
+ public static final String NOT_FOUND = "not_found";
+
+ private transient int statusCode;
+
+ private String status;
+ private String error;
+
+ @SerializedName("data")
+ private T body;
+
+ public T getBody() {
+ return body;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public boolean isError() {
+ return error != null;
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIService.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIService.java
new file mode 100644
index 0000000..32ddb1f
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIService.java
@@ -0,0 +1,69 @@
+package ru.urfu.taskmanager.data.network;
+
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import cz.msebera.android.httpclient.client.methods.HttpDelete;
+import cz.msebera.android.httpclient.client.methods.HttpGet;
+import cz.msebera.android.httpclient.client.methods.HttpPost;
+import cz.msebera.android.httpclient.entity.StringEntity;
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+import ru.urfu.taskmanager.utils.tools.JSONFactory;
+
+public class APIService
+{
+ private static final String SERVER_BASE_URL = "https://notesbackend-yufimtsev.rhcloud.com/";
+ private static final String BODY_ENCODE = "utf-8";
+
+ private final String serviceUrl;
+
+ public APIService(User user) {
+ this.serviceUrl = SERVER_BASE_URL + "user/" + user.getUserId() + "/";
+ }
+
+ public > APIRequest getUserNotes() {
+ HttpGet request = new HttpGet(serviceUrl + "notes");
+ request.setHeader("Accept", "application/json");
+
+ return new APIRequest<>(request, TypeToken.getParameterized(Collection.class, TaskEntry.class).getType());
+ }
+
+ public APIRequest getNoteById(int noteId) {
+ HttpGet request = new HttpGet(serviceUrl + "note/" + noteId);
+ request.setHeader("Accept", "application/json");
+
+ return new APIRequest<>(request);
+ }
+
+ public APIRequest createNote(TaskEntry entry) {
+ HttpPost request = new HttpPost(serviceUrl + "notes");
+ request.setHeader("Accept", "application/json");
+
+ String json = JSONFactory.toJson(entry, TaskEntry.class);
+ request.setEntity(new StringEntity(json, BODY_ENCODE));
+
+ return new APIRequest<>(request, Integer.class);
+ }
+
+ public APIRequest editNote(TaskEntry entry) {
+ HttpPost request = new HttpPost(serviceUrl + "note/" + entry.getEntryId());
+ request.setHeader("Accept", "application/json");
+
+ String json = JSONFactory.toJson(entry, TaskEntry.class);
+ request.setEntity(new StringEntity(json, BODY_ENCODE));
+
+ return new APIRequest<>(request);
+ }
+
+ public APIRequest deleteNote(int id) {
+ HttpDelete request = new HttpDelete(serviceUrl + "note/" + id);
+ request.setHeader("Accept", "application/json");
+
+ return new APIRequest<>(request);
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIServiceExecutor.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIServiceExecutor.java
new file mode 100644
index 0000000..b848807
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/APIServiceExecutor.java
@@ -0,0 +1,204 @@
+package ru.urfu.taskmanager.data.network;
+
+import android.accounts.NetworkErrorException;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.support.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+import ru.urfu.taskmanager.data.db.DbFilter;
+import ru.urfu.taskmanager.data.db.DbTasks;
+import ru.urfu.taskmanager.data.db.async.AsyncExecutor;
+import ru.urfu.taskmanager.data.db.async.DbAsyncExecutor;
+import ru.urfu.taskmanager.data.db.async.ExecuteController;
+import ru.urfu.taskmanager.data.db.async.ExecuteControllerAdapter;
+import ru.urfu.taskmanager.data.network.sync_module.BroadcastSyncManager;
+import ru.urfu.taskmanager.utils.tools.NetworkUtil;
+
+public class APIServiceExecutor implements AsyncExecutor
+{
+ private Context mContext;
+ private DbAsyncExecutor mDbAsyncExecutor = DbTasks.getInstance().getAsyncExecutor();
+ private APIService mApiService;
+
+ private APICallback mFailedCallback = new APICallback() {
+ @Override
+ public void onFailure(Throwable t) {
+ mContext.sendBroadcast(new Intent(BroadcastSyncManager.SYNC_SCHEDULE_ACTION));
+ }
+ };
+
+ public APIServiceExecutor(Context context, APIService service) {
+ this.mContext = context;
+ this.mApiService = service;
+ }
+
+ private boolean isConnected() {
+ boolean isConnected = NetworkUtil.networkIsReachable(mContext);
+ if (!isConnected) {
+ mFailedCallback.onFailure(new NetworkErrorException());
+ }
+
+ return isConnected;
+ }
+
+ @Override
+ public void getAllEntries(@NonNull ExecuteController> controller) {
+ if (isConnected()) {
+ controller.onStart();
+ mApiService.getUserNotes().send(new APICallback>()
+ {
+ @Override
+ public void onResponse(APIResponse> response) {
+ controller.onFinish(new ArrayList<>(response.getBody()));
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ mFailedCallback.onFailure(t);
+ }
+ });
+ } else {
+ mDbAsyncExecutor.getAllEntries(controller);
+ }
+ }
+
+ @Override
+ public void getEntryById(int id, ExecuteController controller) {
+ if (isConnected()) {
+ controller.onStart();
+ mApiService.getNoteById(id).send(new APICallback()
+ {
+ @Override
+ public void onResponse(APIResponse response) {
+ controller.onFinish(response.getBody());
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ mFailedCallback.onFailure(t);
+ }
+ });
+ } else {
+ mDbAsyncExecutor.getEntryById(id, controller);
+ }
+ }
+
+ @Override
+ public void insertEntry(@NonNull TaskEntry entry) {
+ if (isConnected()) {
+ mApiService.createNote(entry).send(new APICallback()
+ {
+ @Override
+ public void onResponse(APIResponse response) {
+ mDbAsyncExecutor.insertEntry(entry.setEntryId(response.getBody()));
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ mFailedCallback.onFailure(t);
+ }
+ });
+ } else {
+ mDbAsyncExecutor.insertEntry(entry.setEntryId(-1));
+ }
+ }
+
+ @Override
+ public void insertEntry(@NonNull TaskEntry entry, @NonNull ExecuteController controller) {
+ mDbAsyncExecutor.insertEntry(entry, new ExecuteControllerAdapter()
+ {
+ @Override
+ public void onFinish(TaskEntry result) {
+ controller.onFinish(result);
+
+ if (isConnected()) {
+ mApiService.createNote(result).send(new APICallback()
+ {
+ @Override
+ public void onResponse(APIResponse response) {
+ TaskEntry toUpdate = result.setEntryId(response.getBody());
+ mDbAsyncExecutor.updateEntry(toUpdate);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ mFailedCallback.onFailure(t);
+ }
+ });
+ }
+ }
+ });
+ }
+
+ @Override
+ public void removeEntryById(int id) {
+ if (isConnected()) {
+ mApiService.deleteNote(id).send(mFailedCallback);
+ } else {
+ mDbAsyncExecutor.removeEntryById(id);
+ }
+ }
+
+ @Override
+ public void removeEntryById(int id, @NonNull ExecuteController controller) {
+ controller.onStart();
+ mDbAsyncExecutor.removeEntryById(id, new ExecuteControllerAdapter()
+ {
+ @Override
+ public void onFinish(TaskEntry deleted) {
+ if (isConnected()) {
+ mApiService.deleteNote(deleted.getEntryId()).send(mFailedCallback);
+ }
+
+ controller.onFinish(deleted);
+ }
+ });
+ }
+
+ @Override
+ public void updateEntry(@NonNull TaskEntry entry) {
+ mDbAsyncExecutor.updateEntry(entry, new ExecuteControllerAdapter()
+ {
+ @Override
+ public void onFinish(TaskEntry result) {
+ if (isConnected()) mApiService.editNote(result).send(mFailedCallback);
+ }
+ });
+ }
+
+ @Override
+ public void updateEntry(@NonNull TaskEntry entry, @NonNull ExecuteController controller) {
+ controller.onStart();
+ mDbAsyncExecutor.updateEntry(entry, new ExecuteControllerAdapter()
+ {
+ @Override
+ public void onFinish(TaskEntry result) {
+ controller.onFinish(result);
+ if (isConnected()) mApiService.editNote(result).send(mFailedCallback);
+ }
+ });
+ }
+
+ @Override
+ public void replaceAll(@NonNull List entries, @NonNull ExecuteController controller) {
+ mDbAsyncExecutor.replaceAll(entries, controller);
+ }
+
+ @Override
+ public void getCursor(@NonNull DbFilter filter, @NonNull ExecuteController controller) {
+ mDbAsyncExecutor.getCursor(filter, controller);
+ }
+
+ @Override
+ public void startTransaction(ExecuteController controller) {
+ mDbAsyncExecutor.startTransaction(controller);
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/BroadcastSyncManager.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/BroadcastSyncManager.java
new file mode 100644
index 0000000..3558823
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/BroadcastSyncManager.java
@@ -0,0 +1,170 @@
+package ru.urfu.taskmanager.data.network.sync_module;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.github.javiersantos.bottomdialogs.BottomDialog;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+import ru.urfu.taskmanager.task_manager.models.TaskEntryCouples;
+import ru.urfu.taskmanager.utils.tools.NetworkUtil;
+
+public abstract class BroadcastSyncManager extends BroadcastReceiver
+{
+ public static final String SYNC_AT_FIRST_TIME_KEY = "ru.urfu.taskmanager.SYNC_AT_FIRST_TIME_KEY";
+
+ public static final int SYNC_SCHEDULED = 1;
+ public static final int SYNC_NOT_SCHEDULED = 2;
+ public static final int SYNC_AT_FIRST_TIME = 3;
+
+ public static final String SYNC_SCHEDULE_ACTION = "ru.urfu.taskmanager.SYNC_SCHEDULE_ACTION";
+ public static final String SYNC_SUCCESS_ACTION = "ru.urfu.taskmanager.SYNC_SUCCESS_ACTION";
+ public static final String SYNC_FAILED_ACTION = "ru.urfu.taskmanager.SYNC_FAILED_ACTION";
+ public static final String SYNC_START_ACTION = "ru.urfu.taskmanager.SYNC_START_ACTION";
+ public static final String SYNC_ASK_ACTION = "ru.urfu.taskmanager.SYNC_ASK_ACTION";
+
+ public static final String REPOSITORY_NAME = "ru.urfu.taskmanager.API_SYNC";
+
+ private Context mContext;
+ private MergeConflictsSolver mMergeConflictsSolver;
+ private SharedPreferences mSyncRepository;
+
+ public BroadcastSyncManager(Activity activity) {
+ this.mContext = activity;
+ this.mSyncRepository = mContext.getSharedPreferences(REPOSITORY_NAME, Context.MODE_PRIVATE);
+ }
+
+ @Override
+ public final void onReceive(final Context context, final Intent data) {
+ switch (data.getAction()) {
+ case SYNC_SCHEDULE_ACTION:
+ onScheduleSync();
+ break;
+ case SYNC_SUCCESS_ACTION:
+ unScheduleSync();
+ onStopSync();
+ break;
+ case SYNC_FAILED_ACTION:
+ Toast.makeText(context, context.getString(R.string.sync_failed), Toast.LENGTH_SHORT).show();
+ onScheduleSync();
+ onStopSync();
+ break;
+ case SYNC_ASK_ACTION:
+ Bundle bundle = data.getExtras();
+ startConflictsSolver(bundle.getParcelable(SynchronizeService.EXTRA_KEY));
+ break;
+ case SYNC_START_ACTION:
+ synchronizeData(SYNC_SCHEDULED);
+ break;
+ case ConnectivityManager.CONNECTIVITY_ACTION:
+ synchronizeDataIfScheduled();
+ break;
+ }
+ }
+
+ public final void startConflictsSolver(TaskEntryCouples mergeCouples) {
+
+ mMergeConflictsSolver = new MergeConflictsSolver(mContext, mergeCouples);
+
+ for (TaskEntryCouples.Couple couple : mergeCouples)
+ {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ View view = inflater.inflate(R.layout.sync_conflict_layout, null);
+
+ ViewGroup leftLayout = (ViewGroup) view.findViewById(R.id.first_container);
+ ViewGroup rightLayout = (ViewGroup) view.findViewById(R.id.second_container);
+
+ fillLayout(leftLayout, couple.getKey());
+ fillLayout(rightLayout, couple.getValue());
+
+ BottomDialog solverDialog = new BottomDialog.Builder(mContext)
+ .setTitle(mContext.getString(R.string.merge_conflict_title))
+ .setContent(mContext.getString(R.string.merge_conflict_descr))
+ .setCustomView(view)
+ .setCancelable(false)
+ .build();
+
+
+ leftLayout.setOnClickListener(mMergeConflictsSolver.with(couple, MergeConflictsSolver.LOCAL,
+ aVoid -> solverDialog.dismiss())
+ );
+
+ rightLayout.setOnClickListener(mMergeConflictsSolver.with(couple, MergeConflictsSolver.REMOTE,
+ aVoid -> solverDialog.dismiss())
+ );
+
+ solverDialog.show();
+ }
+ }
+
+ public abstract void onStopSync();
+
+ private void fillLayout(ViewGroup viewGroup, TaskEntry entry) {
+ viewGroup.addView(createTextView("Title: " + entry.getTitle()));
+ viewGroup.addView(createTextView("Descr: " + entry.getDescription()));
+ viewGroup.addView(createTextView("Created: " + entry.getCreated()));
+ viewGroup.addView(createTextView("Edited: " + entry.getEdited()));
+ viewGroup.addView(createTextView("Viewed: " + entry.getTtl()));
+ viewGroup.addView(createTextView("ImgUrl: " + entry.getImageUrl()));
+ viewGroup.addView(createTextView("Color: " + entry.getColor()));
+ }
+
+ private TextView createTextView(String text) {
+ TextView textView = new TextView(mContext);
+ textView.setText(text);
+ return textView;
+ }
+
+ private void onScheduleSync() {
+ if (mMergeConflictsSolver != null)
+ mMergeConflictsSolver.conflictWasNotResolved();
+
+ mSyncRepository.edit()
+ .putInt(User.getActiveUser().getLogin(), SYNC_SCHEDULED)
+ .apply();
+ }
+
+ private void unScheduleSync() {
+ mSyncRepository.edit()
+ .putInt(User.getActiveUser().getLogin(), SYNC_NOT_SCHEDULED)
+ .apply();
+
+ Toast.makeText(mContext, mContext.getString(R.string.sync_success), Toast.LENGTH_SHORT).show();
+ }
+
+ private void synchronizeDataIfScheduled() {
+ int type = mSyncRepository.getInt(User.getActiveUser().getLogin(), SYNC_AT_FIRST_TIME);
+ synchronizeData(type);
+ }
+
+ private void synchronizeData(int type) {
+ if (NetworkUtil.networkIsReachable(mContext)) {
+ switch (type) {
+ case SYNC_SCHEDULED:
+ Toast.makeText(mContext, mContext.getString(R.string.sync_title), Toast.LENGTH_SHORT).show();
+ mContext.startService(new Intent(mContext, SynchronizeService.class));
+ break;
+ case SYNC_AT_FIRST_TIME:
+ Toast.makeText(mContext, mContext.getString(R.string.sync_title), Toast.LENGTH_SHORT).show();
+ Intent intent = new Intent(mContext, SynchronizeService.class);
+ intent.putExtra(SYNC_AT_FIRST_TIME_KEY, true);
+ mContext.startService(intent);
+ break;
+ }
+ } else if (type == SYNC_AT_FIRST_TIME) {
+ onScheduleSync();
+ }
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/MergeConflictsSolver.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/MergeConflictsSolver.java
new file mode 100644
index 0000000..9896b08
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/MergeConflictsSolver.java
@@ -0,0 +1,89 @@
+package ru.urfu.taskmanager.data.network.sync_module;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.data.network.APIServiceExecutor;
+import ru.urfu.taskmanager.task_manager.models.TaskEntryCouples;
+import ru.urfu.taskmanager.utils.interfaces.Callback;
+
+public final class MergeConflictsSolver
+{
+ public static final int LOCAL = 1;
+ public static final int REMOTE = 2;
+
+ private Context mContext;
+ private TaskEntryCouples mCouples;
+ private List mListeners;
+
+ private boolean isResolved = true;
+
+ public MergeConflictsSolver(Context context, TaskEntryCouples couples) {
+ this.mContext = context;
+ this.mCouples = couples;
+ this.mListeners = new ArrayList<>();
+ }
+
+ public OnSolveListener with(TaskEntryCouples.Couple couple, int type, Callback callback) {
+ OnSolveListener onSolveListener = new OnSolveListener(couple, type, callback);
+ mListeners.add(onSolveListener);
+ return onSolveListener;
+ }
+
+ public void conflictWasNotResolved() {
+ isResolved = false;
+
+ for (OnSolveListener mListener : mListeners) {
+ mListener.mCallback.call(null);
+ }
+
+ Toast.makeText(mContext, mContext.getString(R.string.conflict_not_resolved), Toast.LENGTH_SHORT).show();
+ }
+
+ private class OnSolveListener implements View.OnClickListener
+ {
+ int mType;
+ TaskEntryCouples.Couple mCouple;
+ Callback mCallback;
+
+ APIServiceExecutor mApiService;
+
+ OnSolveListener(TaskEntryCouples.Couple couple, int type, Callback callback) {
+ this.mType = type;
+ this.mCouple = couple;
+ this.mCallback = callback;
+ this.mApiService = User.getActiveUser()
+ .getExecutor();
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (mType) {
+ case LOCAL:
+ mApiService.updateEntry(mCouple.getKey());
+ break;
+ case REMOTE:
+ mApiService.updateEntry(mCouple.getValue()
+ .setId(mCouple.getKey().getId())
+ .setDeviceIdentifier(User.getActiveUser().getDeviceIdentifier())
+ );
+ break;
+ }
+
+ MergeConflictsSolver.this.mCouples.remove(mCouple);
+ if (MergeConflictsSolver.this.mCouples.size() == 0 && isResolved) {
+ MergeConflictsSolver.this.mContext
+ .sendBroadcast(new Intent(BroadcastSyncManager.SYNC_SUCCESS_ACTION));
+ }
+
+ mCallback.call(null);
+ }
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/SynchronizeService.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/SynchronizeService.java
new file mode 100644
index 0000000..a370985
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/data/network/sync_module/SynchronizeService.java
@@ -0,0 +1,197 @@
+package ru.urfu.taskmanager.data.network.sync_module;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.support.annotation.Nullable;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+import ru.urfu.taskmanager.data.db.DbTasks;
+import ru.urfu.taskmanager.task_manager.models.TaskEntryCouples;
+import ru.urfu.taskmanager.data.network.APICallback;
+import ru.urfu.taskmanager.data.network.APIResponse;
+import ru.urfu.taskmanager.data.network.APIService;
+import ru.urfu.taskmanager.utils.interfaces.Callback;
+import ru.urfu.taskmanager.utils.interfaces.Thenable;
+
+public class SynchronizeService extends Service implements Thenable
+{
+ public static final String EXTRA_KEY = "data";
+
+ private TaskEntryCouples mDisputableEntries;
+ private SparseArray mRemoteMapEntries;
+
+ private APIService mApiService;
+ private DbTasks mDatabase;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mDisputableEntries = new TaskEntryCouples();
+ mRemoteMapEntries = new SparseArray<>();
+ mApiService = User.getActiveUser().getService();
+ mDatabase = DbTasks.getInstance();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId)
+ {
+ boolean loadAll = intent.getBooleanExtra(BroadcastSyncManager.SYNC_AT_FIRST_TIME_KEY, false);
+
+ if (loadAll) {
+ loadDataProcess();
+ } else {
+ startSyncProcess();
+ }
+
+ return START_NOT_STICKY;
+ }
+
+ private void loadDataProcess() {
+
+ mApiService.getUserNotes().send(new APICallback>()
+ {
+ @Override
+ public void onResponse(APIResponse> response) {
+ mDatabase.startTransaction(aVoid -> {
+ for (TaskEntry entry : response.getBody()) {
+ mDatabase.insertEntry(entry);
+ }
+ });
+
+ SynchronizeService.this.onSuccess();
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ SynchronizeService.this.onFailed(t);
+ }
+ });
+ }
+
+ private void startSyncProcess() {
+ List localEntries = mDatabase.getAllEntries();
+
+ mApiService.getUserNotes().send(new APICallback>()
+ {
+ @Override
+ public void onResponse(APIResponse> response)
+ {
+ for (TaskEntry entry : response.getBody()) {
+ mRemoteMapEntries.put(entry.getEntryId(), entry);
+ }
+
+ Queue localQueue = new ConcurrentLinkedQueue<>(localEntries);
+ while (!localQueue.isEmpty())
+ {
+ TaskEntry localEntry = localQueue.poll();
+ TaskEntry remoteEntry = mRemoteMapEntries.get(localEntry.getEntryId());
+
+ if (remoteEntry != null) {
+ System.out.println("local: " + localEntry.getTtlTimestamp());
+ System.out.println("remote: " + remoteEntry.getTtlTimestamp());
+ if (localEntry.hashCode() == remoteEntry.hashCode()) {
+ System.out.println("continue");
+ mRemoteMapEntries.remove(localEntry.getEntryId());
+ continue;
+ }
+
+ if (localEntry.getDeviceIdentifier().equals(remoteEntry.getDeviceIdentifier())) {
+ if (localEntry.getEditedTimestamp() > remoteEntry.getEditedTimestamp()) {
+ mApiService.editNote(localEntry).send(new APICallback()
+ {
+ @Override
+ public void onFailure(Throwable t) {
+ SynchronizeService.this.onFailed(t);
+ }
+ });
+ } else {
+ mDisputableEntries.put(localEntry, remoteEntry);
+ }
+ } else {
+ mDisputableEntries.put(localEntry, remoteEntry);
+ }
+
+ mRemoteMapEntries.remove(localEntry.getEntryId());
+ } else {
+ mApiService.createNote(localEntry).send(new APICallback()
+ {
+ @Override
+ public void onResponse(APIResponse response) {
+ mDatabase.updateEntry(localEntry.setEntryId(response.getBody()));
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ SynchronizeService.this.onFailed(t);
+ }
+ });
+ }
+ }
+
+ while (mRemoteMapEntries.size() != 0) {
+ TaskEntry remoteEntry = mRemoteMapEntries.valueAt(0);
+ if (remoteEntry.getDeviceIdentifier().equals(User.getActiveUser().getDeviceIdentifier())) {
+ mApiService.deleteNote(remoteEntry.getEntryId()).send(new APICallback()
+ {
+ @Override
+ public void onFailure(Throwable t) {
+ SynchronizeService.this.onFailed(t);
+ }
+ });
+ } else {
+ mDatabase.insertEntry(remoteEntry);
+ }
+
+ mRemoteMapEntries.removeAt(0);
+ }
+
+ SynchronizeService.this.onSuccess();
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ SynchronizeService.this.onFailed(t);
+ }
+ });
+ }
+
+ @Override
+ public void onSuccess(Void... results) {
+ if (!mDisputableEntries.isEmpty()) {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(EXTRA_KEY, mDisputableEntries);
+
+ Intent intent = new Intent(BroadcastSyncManager.SYNC_ASK_ACTION);
+ intent.putExtras(bundle);
+
+ sendBroadcast(intent);
+ } else {
+ sendBroadcast(new Intent(BroadcastSyncManager.SYNC_SUCCESS_ACTION));
+ }
+
+ stopSelf();
+ }
+
+ @Override
+ public void onFailed(Throwable t) {
+ t.printStackTrace();
+ sendBroadcast(new Intent(BroadcastSyncManager.SYNC_FAILED_ACTION));
+ stopSelf();
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/presenter/TaskEditorPresenter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/presenter/TaskEditorPresenter.java
similarity index 68%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/presenter/TaskEditorPresenter.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/presenter/TaskEditorPresenter.java
index e63d2c1..086eaec 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/presenter/TaskEditorPresenter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/presenter/TaskEditorPresenter.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.task_manager.task_editor.presenter;
+package ru.urfu.taskmanager.task_manager.editor.presenter;
import ru.urfu.taskmanager.task_manager.models.TaskEntry;
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/presenter/TaskEditorPresenterImpl.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/presenter/TaskEditorPresenterImpl.java
new file mode 100644
index 0000000..88014bf
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/presenter/TaskEditorPresenterImpl.java
@@ -0,0 +1,111 @@
+package ru.urfu.taskmanager.task_manager.editor.presenter;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.color_picker.recent.RecentColorsStorage;
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+import ru.urfu.taskmanager.task_manager.editor.view.TaskEditor;
+import ru.urfu.taskmanager.data.db.DbTasks;
+import ru.urfu.taskmanager.data.network.APIServiceExecutor;
+import ru.urfu.taskmanager.data.db.async.DbAsyncExecutor;
+import ru.urfu.taskmanager.data.db.async.ExecuteControllerAdapter;
+import ru.urfu.taskmanager.utils.interfaces.Callback;
+
+import static android.app.Activity.RESULT_OK;
+import static ru.urfu.taskmanager.task_manager.editor.view.TaskEditorFragment.NON_ID;
+
+public class TaskEditorPresenterImpl implements TaskEditorPresenter
+{
+ private int mItemId;
+ private int mEntryId;
+
+ private TaskEditor mEditor;
+ private TaskValidator mValidator;
+ private DbAsyncExecutor mDbAsyncExecutor;
+ private APIServiceExecutor mAPIServiceExecutor;
+ private RecentColorsStorage mRecentColorsStorage;
+
+ public TaskEditorPresenterImpl(TaskEditor editor) {
+ this.mEditor = editor;
+ this.mItemId = NON_ID;
+ this.mAPIServiceExecutor = User.getActiveUser().getExecutor();
+ this.mDbAsyncExecutor = DbTasks.getInstance().getAsyncExecutor();
+ this.mRecentColorsStorage = RecentColorsStorage.getRepository();
+ this.mValidator = new TaskValidator();
+ init();
+ }
+
+ private void init() {
+ if (mEditor.getEditedItemId() != NON_ID) {
+ mItemId = mEditor.getEditedItemId();
+
+ mDbAsyncExecutor.getEntryById(mItemId,
+ new ExecuteControllerAdapter() {
+ @Override
+ public void onFinish(TaskEntry result) {
+ mEntryId = result.getEntryId();
+ mEditor.initializeEditor(result);
+ mEditor.onImageLoad(result.getImageUrl());
+ }
+ });
+ }
+ }
+
+ @Override
+ public void saveState(TaskEntry state) {
+ ExecuteControllerAdapter onPostExecute = new ExecuteControllerAdapter() {
+ @Override
+ public void onFinish() {
+ mRecentColorsStorage.putItem(state.getColorInt());
+ mEditor.exit(RESULT_OK);
+ }
+ };
+
+ mValidator.validate(state, aVoid -> {
+ long timestamp = System.currentTimeMillis();
+ state.setId(mItemId).setEntryId(mEntryId).setEdited(timestamp);
+
+ switch (mItemId) {
+ case NON_ID:
+ mAPIServiceExecutor.insertEntry(state.setCreated(timestamp), onPostExecute);
+ break;
+ default:
+ mAPIServiceExecutor.updateEntry(state, onPostExecute);
+ break;
+ }
+ });
+ }
+
+ private class TaskValidator {
+ private static final int TITLE_MAX_LENGTH = 20;
+ private static final int DESCRIPTION_MAX_LENGTH = 50;
+
+ private boolean isValid = true;
+
+ private void validate(TaskEntry entry, Callback callback) {
+ isValid = true;
+
+ if (entry.getTitle().isEmpty()) {
+ isValid = false;
+ mEditor.showTitleError(mEditor.getString(R.string.search_hint));
+ }
+
+ if (entry.getTitle().length() > TITLE_MAX_LENGTH) {
+ isValid = false;
+ mEditor.showTitleError(mEditor.getString(R.string.incorrect_length) + " " + TITLE_MAX_LENGTH);
+ }
+
+ if (entry.getDescription().isEmpty()) {
+ isValid = false;
+ mEditor.showDescriptionError(mEditor.getString(R.string.entry_description));
+ }
+
+ if (entry.getDescription().length() > DESCRIPTION_MAX_LENGTH) {
+ isValid = false;
+ mEditor.showTitleError(mEditor.getString(R.string.incorrect_length) + " " + DESCRIPTION_MAX_LENGTH);
+ }
+
+ if (isValid) callback.call(null);
+ }
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/tools/ImageLoader.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/tools/ImageLoader.java
similarity index 82%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/tools/ImageLoader.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/tools/ImageLoader.java
index f05567b..d2a4d37 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/tools/ImageLoader.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/tools/ImageLoader.java
@@ -1,4 +1,4 @@
-package ru.urfu.taskmanager.task_manager.task_editor.tools;
+package ru.urfu.taskmanager.task_manager.editor.tools;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -47,8 +47,9 @@ public void from(String url) {
mBitmap = BitmapFactory.decodeStream(mImageUrl.openConnection().getInputStream());
mView.post(() -> mView.setImageBitmap(mBitmap));
} catch (IOException e) {
- mView.post(() -> Toast.makeText(mView.getContext(),
- mView.getResources().getString(R.string.could_not_load_image), Toast.LENGTH_SHORT).show());
+ e.printStackTrace();
+// mView.post(() -> Toast.makeText(mView.getContext(),
+// mView.getResources().getString(R.string.could_not_load_image), Toast.LENGTH_SHORT).show());
} finally {
quit();
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/EditorPagerFragment.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/EditorPagerFragment.java
new file mode 100644
index 0000000..67a77f5
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/EditorPagerFragment.java
@@ -0,0 +1,90 @@
+package ru.urfu.taskmanager.task_manager.editor.view;
+
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.design.widget.TabLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+import android.view.View;
+
+import ru.urfu.taskmanager.data.db.DbTasks;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.CursorProvider;
+import ru.urfu.taskmanager.task_manager.main.fragments.TaskPagerFragment;
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+
+import static ru.urfu.taskmanager.task_manager.editor.view.TaskEditorFragment.EDITED_ITEM_ID_KEY;
+import static ru.urfu.taskmanager.task_manager.editor.view.TaskEditorFragment.TRANSITION_NAME;
+
+public class EditorPagerFragment extends TaskPagerFragment
+{
+ public static final String EDITOR_PAGER_POSITION = "ru.urfu.taskmanager.task_manager.editor.EDITOR_PAGER_POSITION";
+
+ CursorProvider mDataAdapter;
+ DbTasks mDatabase;
+
+ private EditorPagerFragment(CursorProvider adapter) {
+ mDataAdapter = adapter;
+ mDatabase = DbTasks.getInstance();
+ }
+
+ @Override
+ protected void configViewPager() {
+ super.configViewPager();
+ Integer position = (Integer) getArguments().getSerializable(EDITOR_PAGER_POSITION);
+ position = (position != null) ? position : 0;
+ mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
+ mViewPager.setCurrentItem(position);
+ fab.setVisibility(View.GONE);
+ }
+
+ @Override
+ protected FragmentStatePagerAdapter getPagerAdapter() {
+ return new EditorPagerAdapter(getChildFragmentManager());
+ }
+
+ public static EditorPagerFragment newInstance(Bundle args, CursorProvider adapter) {
+ EditorPagerFragment fragment = new EditorPagerFragment(adapter);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ private class EditorPagerAdapter extends FragmentStatePagerAdapter
+ {
+ private Cursor cursor;
+
+ public EditorPagerAdapter(FragmentManager fm) {
+ super(fm);
+ cursor = (mDataAdapter != null)
+ ? mDataAdapter.getCursor()
+ : mDatabase.getCursor(DbTasksFilter.DEFAULT_BUILDER.build());
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ int editedItemId = getEntryFromPosition(position)
+ .getId();
+
+ Bundle bundle = new Bundle();
+ bundle.putInt(EDITED_ITEM_ID_KEY, editedItemId);
+ bundle.putString(TRANSITION_NAME, "timeBlock_" + position);
+ return TaskEditorFragment.newInstance(bundle);
+ }
+
+ @Override
+ public int getCount() {
+ return cursor.getCount();
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return getEntryFromPosition(position).getTitle();
+ }
+
+ private TaskEntry getEntryFromPosition(int position) {
+ cursor.moveToPosition(position);
+ return mDatabase.getCurrentEntryFromCursor(cursor);
+ }
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/view/TaskEditor.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/TaskEditor.java
similarity index 61%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/view/TaskEditor.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/TaskEditor.java
index 294f253..48f8349 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/view/TaskEditor.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/TaskEditor.java
@@ -1,19 +1,16 @@
-package ru.urfu.taskmanager.task_manager.task_editor.view;
+package ru.urfu.taskmanager.task_manager.editor.view;
-import android.content.Intent;
+import android.support.annotation.StringRes;
import android.view.View;
import ru.urfu.taskmanager.color_picker.listeners.PickerViewStateListener;
import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.utils.interfaces.ActivityWindow;
-public interface TaskEditor extends View.OnClickListener, PickerViewStateListener, ActivityWindow
+public interface TaskEditor extends View.OnClickListener, PickerViewStateListener
{
- Intent getIntent();
+ int getEditedItemId();
- boolean isRestored();
-
- void setToolbarTitle(String title);
+ String getString(@StringRes int stringRes);
void initializeEditor(TaskEntry entryToEdit);
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/TaskEditorFragment.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/TaskEditorFragment.java
new file mode 100644
index 0000000..3426bb1
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/editor/view/TaskEditorFragment.java
@@ -0,0 +1,229 @@
+package ru.urfu.taskmanager.task_manager.editor.view;
+
+import android.graphics.Color;
+import android.graphics.drawable.GradientDrawable;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.design.widget.TextInputLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.ViewCompat;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.github.florent37.singledateandtimepicker.SingleDateAndTimePicker;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.color_picker.PickerView;
+import ru.urfu.taskmanager.color_picker.recent.RecentColors;
+import ru.urfu.taskmanager.task_manager.editor.presenter.TaskEditorPresenter;
+import ru.urfu.taskmanager.task_manager.editor.presenter.TaskEditorPresenterImpl;
+import ru.urfu.taskmanager.task_manager.editor.tools.ImageLoader;
+import ru.urfu.taskmanager.task_manager.main.view.TaskManager;
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+import ru.urfu.taskmanager.utils.tools.TimeUtils;
+
+import static android.content.Context.VIBRATOR_SERVICE;
+import static ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity.REQUEST_CREATE;
+import static ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity.REQUEST_EDIT;
+
+public class TaskEditorFragment extends Fragment implements TaskEditor, SingleDateAndTimePicker.Listener
+{
+ public static final int NON_ID = -1;
+ public static final String EDITED_ITEM_ID_KEY = "ru.urfu.taskmanager.task_manager.editor.EDITED_ITEM_ID";
+ public static final String TRANSITION_NAME = "transitionName";
+
+ private static final int CELL_COUNT = 16;
+
+ TaskManager mManager;
+ TaskEditorPresenter mPresenter;
+
+ SingleDateAndTimePicker mDateTimePicker;
+ TextInputLayout mTitleInputLayout;
+ TextInputLayout mDescInputLayout;
+ ImageView mImageView;
+ PickerView mPickerView;
+ TextView mColorDeadlineTextView;
+ EditText mTitleEditField;
+ EditText mDescEditField;
+ EditText mImageUrlEditField;
+ Button mButtonSave;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return initView(inflater.inflate(R.layout.activity_task_editor, container, false));
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ initialize();
+ }
+
+ private View initView(View view) {
+ mDateTimePicker = (SingleDateAndTimePicker) view.findViewById(R.id.datetime_picker);
+ mColorDeadlineTextView = (TextView) view.findViewById(R.id.color_deadline);
+ mButtonSave = (Button) view.findViewById(R.id.save_button);
+ mDescEditField = (EditText) view.findViewById(R.id.descr_edit_field);
+ mDescInputLayout = (TextInputLayout) view.findViewById(R.id.description_input_layout);
+ mTitleEditField = (EditText) view.findViewById(R.id.title_edit_field);
+ mTitleInputLayout = (TextInputLayout) view.findViewById(R.id.title_input_layout);
+ mImageUrlEditField = (EditText) view.findViewById(R.id.image_url_edit_field);
+ mImageView = (ImageView) view.findViewById(R.id.image_view);
+ mPickerView = (PickerView) view.findViewById(R.id.pickerView);
+
+ mImageUrlEditField.addTextChangedListener(new TextWatcher()
+ {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ onImageLoad(s.toString());
+ }
+ });
+
+ ViewCompat.setTransitionName(mColorDeadlineTextView, getArguments().getString(TRANSITION_NAME));
+
+ return view;
+ }
+
+ @Override
+ public int getEditedItemId() {
+ Integer valueId = (Integer) getArguments().getSerializable(EDITED_ITEM_ID_KEY);
+ return (valueId != null) ? valueId : NON_ID;
+ }
+
+ private void initialize() {
+ mManager = (TaskManager) getActivity();
+
+ mDateTimePicker.setMustBeOnFuture(true);
+ mDateTimePicker.setListener(this);
+
+ mButtonSave.setOnClickListener(this);
+ mPickerView.setCellCount(CELL_COUNT);
+ mPickerView.subscribe(this);
+
+ onColorChanged(mPickerView.getCurrentColor());
+ mColorDeadlineTextView.setOnClickListener(v -> RecentColors.showRecent(getContext(), color -> {
+ mPickerView.setCurrentColor(color);
+ onColorChanged(color);
+ }));
+
+ mPresenter = new TaskEditorPresenterImpl(this);
+ }
+
+ public void initializeEditor(TaskEntry entry) {
+ getActivity().runOnUiThread(() -> {
+ Calendar calendar = new GregorianCalendar();
+ calendar.setTimeInMillis(entry.getTtlTimestamp());
+
+ mDateTimePicker.selectDate(calendar);
+ mDateTimePicker.setSelectorColor(Color.BLACK);
+ mTitleEditField.setText(entry.getTitle());
+ mDescEditField.setText(entry.getDescription());
+ mImageUrlEditField.setText(entry.getImageUrl());
+ mPickerView.setCurrentColor(entry.getColorInt());
+ mColorDeadlineTextView.setText(TimeUtils.getHoursAndMinutesFromUnix(entry.getTtlTimestamp()).toString());
+ onColorChanged(mPickerView.getCurrentColor());
+ });
+ }
+
+ @Override
+ public void onImageLoad(String url) {
+ mImageView.post(() -> ImageLoader.into(mImageView)
+ .from(url));
+ }
+
+ @Override
+ public void showTitleError(String string) {
+ mTitleInputLayout.setError(string);
+ }
+
+ @Override
+ public void showDescriptionError(String string) {
+ mDescInputLayout.setError(string);
+ }
+
+ @Override
+ public void onClick(View v) {
+ mTitleInputLayout.setErrorEnabled(false);
+ mDescInputLayout.setErrorEnabled(false);
+
+ mPresenter.saveState(
+ new TaskEntry()
+ .setTitle(mTitleEditField.getText().toString())
+ .setDescription(mDescEditField.getText().toString())
+ .setTtl(mDateTimePicker.getDate().getTime())
+ .setColor(mPickerView.getCurrentColor())
+ .setImageUrl(mImageUrlEditField.getText().toString())
+ );
+ }
+
+ @Override
+ public void onColorChanged(int color) {
+ GradientDrawable gd = new GradientDrawable();
+ gd.setColor(color);
+ gd.setCornerRadius(100f);
+
+ mColorDeadlineTextView.setBackground(gd);
+ }
+
+ @Override
+ public void editModeEnable() {
+ vibrate();
+ }
+
+ @Override
+ public void editModeDisable() {
+ vibrate();
+ }
+
+ @Override
+ public void theBoundaryIsReached() {
+ vibrate();
+ }
+
+ @Override
+ public void exit(int result) {
+ mManager.getPresenter()
+ .onResult((getEditedItemId() == NON_ID) ? REQUEST_CREATE : REQUEST_EDIT);
+
+ mManager.getSupportFragmentManager()
+ .popBackStack();
+ }
+
+ private void vibrate() {
+ Vibrator vibrator = (Vibrator) getContext().getSystemService(VIBRATOR_SERVICE);
+ vibrator.vibrate(10);
+ }
+
+ @Override
+ public void onDateChanged(String displayed, Date date) {
+ mColorDeadlineTextView.setText(TimeUtils.getHoursAndMinutesFromUnix(date.getTime()).toString());
+ }
+
+ public static TaskEditorFragment newInstance(@Nullable Bundle args) {
+ TaskEditorFragment fragment = new TaskEditorFragment();
+ if (args != null) fragment.setArguments(args);
+ return fragment;
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/adapters/AbstractTaskListAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/adapters/AbstractTaskListAdapter.java
deleted file mode 100644
index 6ec5278..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/adapters/AbstractTaskListAdapter.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package ru.urfu.taskmanager.task_manager.fragments.adapters;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.widget.SimpleCursorAdapter;
-
-import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.utils.db.DbTasksHelper;
-
-
-public class AbstractTaskListAdapter extends SimpleCursorAdapter
-{
- protected static final String OVERDUE = "Просрочено";
-
- protected static final int LAYOUT = R.layout.task_list_item;
-
- protected static final String[] FROM = new String[]{
- DbTasksHelper.TITLE,
- DbTasksHelper.DESCRIPTION,
- DbTasksHelper.TTL,
- DbTasksHelper.DECORATE_COLOR,
- };
-
- protected static final int[] TO = new int[]{
- R.id.task_item_title,
- R.id.task_item_description,
- R.id.task_item_deadline,
- R.id.task_item_color
- };
-
- protected static final String[] ACTIVE_DAYS = new String[]{
- "Сегодня", "Завтра", "Послезавтра"
- };
-
- protected static final String[] COMPLETED_DAYS = new String[]{
- "Сегодня", "Вчера", "Позавчера"
- };
-
- protected AbstractTaskListAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
- super(context, layout, c, from, to, flags);
- }
-}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/adapters/TasksListAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/adapters/TasksListAdapter.java
deleted file mode 100644
index a82cb14..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/adapters/TasksListAdapter.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package ru.urfu.taskmanager.task_manager.fragments.adapters;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.drawable.GradientDrawable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import java.util.Calendar;
-
-import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.utils.db.DbTasks;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
-import ru.urfu.taskmanager.utils.tools.TimeUtils;
-
-public class TasksListAdapter extends AbstractTaskListAdapter
-{
- private final Context mContext;
- private final DbTasksFilter defaultFilter;
- private final DbTasks mDatabase;
-
- public TasksListAdapter(Context context, DbTasksFilter tasksFilter) {
- super(context, LAYOUT, null, FROM, TO, 0);
- this.mContext = context;
- this.defaultFilter = tasksFilter;
- this.mDatabase = DbTasks.getInstance();
- updateData(mDatabase.getCursor(defaultFilter));
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(LAYOUT, parent, false);
-
- ViewHolder holder = new ViewHolder();
- holder.layout = view.findViewById(R.id.task_layout);
- holder.header = view.findViewById(R.id.task_header);
- holder.header_text = (TextView) view.findViewById(R.id.header_text);
- holder.title = (TextView) view.findViewById(R.id.task_item_title);
- holder.description = (TextView) view.findViewById(R.id.task_item_description);
- holder.ttl = (TextView) view.findViewById(R.id.task_item_deadline);
-
- view.setTag(holder);
- return view;
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TaskEntry entry = mDatabase.getCurrentEntryFromCursor(cursor);
- TaskEntry prev = (cursor.moveToPrevious())
- ? mDatabase.getCurrentEntryFromCursor(cursor)
- : null;
-
- GradientDrawable gd = new GradientDrawable();
- gd.setColor(entry.getColorInt());
- gd.setCornerRadius(100f);
-
- ViewHolder holder = (ViewHolder) view.getTag();
-
- holder.title.setText(entry.getTitle());
- holder.description.setText(entry.getDescription());
- holder.ttl.setText(TimeUtils.getHoursAndMinutesFromUnix(entry.getTtlTimestamp()).toString());
- holder.ttl.setBackground(gd);
- attachHeader(holder, entry, prev);
- }
-
- private ViewHolder attachHeader(ViewHolder holder, TaskEntry entry, TaskEntry prev) {
- String entryTitle = getTitleFromEntry(entry);
- if (entryTitle.equals(OVERDUE))
- holder.layout.setAlpha(0.4f);
- else holder.layout.setAlpha(1f);
-
- if (prev != null) {
- String prevTitle = getTitleFromEntry(prev);
-
- if (!entryTitle.equals(prevTitle)) {
- holder.header_text.setText(entryTitle);
- holder.header.setVisibility(View.VISIBLE);
- } else {
- holder.header.setVisibility(View.GONE);
- }
- } else {
- holder.header_text.setText(entryTitle);
- holder.header.setVisibility(View.VISIBLE);
- }
-
- return holder;
- }
-
- private String getTitleFromEntry(TaskEntry entry) {
- if (System.currentTimeMillis() > entry.getTtlTimestamp() & defaultFilter.getType() == DbTasksFilter.ACTIVE_TASK) {
- return OVERDUE;
- } else {
- Calendar entryDate = Calendar.getInstance();
- entryDate.setTimeInMillis(entry.getTtlTimestamp());
- int diffDay = Math.abs(entryDate.get(Calendar.DAY_OF_YEAR) - Calendar.getInstance().get(Calendar.DAY_OF_YEAR));
- return getHeaderTitleByNum(diffDay, entryDate);
- }
- }
-
- private String getHeaderTitleByNum(int num, Calendar entryDate) {
- if (num < 3) {
- switch (defaultFilter.getType()) {
- case DbTasksFilter.ACTIVE_TASK:
- return ACTIVE_DAYS[num];
- case DbTasksFilter.COMPLETED_TASK:
- return COMPLETED_DAYS[num];
- }
- }
-
- return TimeUtils.format(entryDate);
- }
-
- public void updateData(Cursor... cursor) {
- if (cursor.length == 0) {
- updateCursor(mDatabase.getCursor(defaultFilter));
- } else {
- updateCursor(cursor[0]);
- }
- }
-
- private void updateCursor(Cursor cursor) {
- changeCursor(cursor);
- }
-
- public int getDataType() {
- return defaultFilter.getType();
- }
-
- private static class ViewHolder {
- View layout;
- View header;
- TextView header_text;
- TextView title;
- TextView description;
- TextView ttl;
- }
-}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListFragment.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListFragment.java
deleted file mode 100644
index eb2bf92..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListFragment.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package ru.urfu.taskmanager.task_manager.fragments.view;
-
-import android.content.Intent;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ListView;
-
-import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.task_manager.fragments.adapters.TasksListAdapter;
-import ru.urfu.taskmanager.task_manager.main.presenter.TaskManagerPresenter;
-import ru.urfu.taskmanager.task_manager.task_editor.view.TaskEditorActivity_;
-import ru.urfu.taskmanager.utils.db.DbTasksHelper;
-
-import static ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity.ACTION_EDIT;
-import static ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity.REQUEST_EDIT;
-
-public abstract class TaskListFragment extends Fragment
- implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, TaskListView
-{
- protected TaskManagerPresenter mPresenter;
-
- ListView mTaskListView;
- TasksListAdapter mAdapter;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.active_tasks_fragment, container, false);
- return initView(view);
- }
-
- protected View initView(View root) {
- mTaskListView = (ListView) root.findViewById(R.id.task_list);
- mTaskListView.setAdapter(mAdapter = getAdapter());
- mTaskListView.setOnItemClickListener(this);
- mTaskListView.setOnItemLongClickListener(this);
-
- return root;
- }
-
- protected abstract TasksListAdapter getAdapter();
-
- public abstract void onItemClick(AdapterView> parent, View view, int position, long id);
-
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
- Intent intent = new Intent(getActivity(), TaskEditorActivity_.class);
- intent.setAction(ACTION_EDIT);
- intent.putExtra(DbTasksHelper.ID, (int) id);
- startActivityForResult(intent, REQUEST_EDIT);
- return true;
- }
-
- @Override
- public void onUpdate(Cursor... cursor) {
- getActivity().runOnUiThread(() -> mAdapter.updateData(cursor));
- }
-
- @Override
- public Fragment getInstance() {
- return this;
- }
-
- @Override
- public TaskListView bindPresenter(TaskManagerPresenter presenter) {
- this.mPresenter = presenter;
- return this;
- }
-
- @Override
- public int getDataType() {
- return mAdapter.getDataType();
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- mPresenter.onResult(requestCode, resultCode, data);
- }
-
- @Override
- public void showAlert(String message) {
- Snackbar.make(getActivity().getWindow().getDecorView(), message, 2000).show();
- }
-}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListView.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListView.java
deleted file mode 100644
index 8288e57..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListView.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package ru.urfu.taskmanager.task_manager.fragments.view;
-
-import android.database.Cursor;
-import android.support.v4.app.Fragment;
-
-import ru.urfu.taskmanager.task_manager.main.presenter.TaskManagerPresenter;
-import ru.urfu.taskmanager.task_manager.models.OnDataUpdateListener;
-import ru.urfu.taskmanager.utils.interfaces.Showable;
-
-public interface TaskListView extends OnDataUpdateListener, Showable
-{
- TaskListView bindPresenter(TaskManagerPresenter presenter);
-
- int getDataType();
-
- Fragment getInstance();
-}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/FiltersAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/FiltersAdapter.java
index a25b23d..922f826 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/FiltersAdapter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/FiltersAdapter.java
@@ -3,7 +3,7 @@
import android.widget.AdapterView;
import android.widget.ListAdapter;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
public interface FiltersAdapter extends ListAdapter, AdapterView.OnItemClickListener
{
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/OnDataUpdateListener.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/OnDataUpdateListener.java
new file mode 100644
index 0000000..154c500
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/OnDataUpdateListener.java
@@ -0,0 +1,10 @@
+package ru.urfu.taskmanager.task_manager.main.adapters;
+
+import ru.urfu.taskmanager.data.db.DbFilter;
+
+public interface OnDataUpdateListener
+{
+ void onUpdate(T... data);
+
+ void onUpdate(DbFilter filter);
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/SavedFiltersAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/SavedFiltersAdapter.java
index a463cb7..043f988 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/SavedFiltersAdapter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/SavedFiltersAdapter.java
@@ -15,7 +15,7 @@
import ru.urfu.taskmanager.R;
import ru.urfu.taskmanager.task_manager.main.filter.FiltersStorage;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
public class SavedFiltersAdapter extends BaseAdapter implements FiltersAdapter
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/ViewPagerAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/ViewPagerAdapter.java
index cd6201c..142f436 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/ViewPagerAdapter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/adapters/ViewPagerAdapter.java
@@ -7,7 +7,7 @@
import java.util.ArrayList;
import java.util.List;
-import ru.urfu.taskmanager.task_manager.fragments.view.TaskListView;
+import ru.urfu.taskmanager.task_manager.main.fragments.view.TaskListView;
public class ViewPagerAdapter extends FragmentStatePagerAdapter
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterLayoutWrapper.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterLayoutWrapper.java
index 1945d2a..b8b73e7 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterLayoutWrapper.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterLayoutWrapper.java
@@ -4,7 +4,7 @@
import android.view.View;
import ru.urfu.taskmanager.task_manager.main.adapters.FiltersAdapter;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
public class FilterLayoutWrapper
{
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterViewHolder.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterViewHolder.java
index f8ac676..fb64b82 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterViewHolder.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FilterViewHolder.java
@@ -15,8 +15,8 @@
import ru.urfu.taskmanager.R;
import ru.urfu.taskmanager.color_picker.recent.RecentColors;
-import ru.urfu.taskmanager.utils.db.DbTasksHelper;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksHelper;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
import ru.urfu.taskmanager.utils.tools.TimeUtils;
@@ -123,6 +123,9 @@ DbTasksFilter.Builder compileFilterBuilder() {
case 2:
builder.sortBy(DbTasksHelper.TIME_EDITED);
break;
+ case 3:
+ builder.sortBy(DbTasksHelper.ORDER);
+ break;
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FiltersStorage.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FiltersStorage.java
index 65e1f46..e1b07fd 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FiltersStorage.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/filter/FiltersStorage.java
@@ -8,7 +8,7 @@
import java.util.HashMap;
import java.util.Map;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
import ru.urfu.taskmanager.utils.tools.JSONFactory;
public final class FiltersStorage
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/TaskPagerFragment.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/TaskPagerFragment.java
new file mode 100644
index 0000000..86af0e5
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/TaskPagerFragment.java
@@ -0,0 +1,74 @@
+package ru.urfu.taskmanager.task_manager.main.fragments;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.TabLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentStatePagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.task_manager.main.fragments.view.TaskListActive;
+import ru.urfu.taskmanager.task_manager.main.fragments.view.TaskListCompleted;
+import ru.urfu.taskmanager.task_manager.main.view.TaskManager;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TaskPagerAdapter;
+
+public class TaskPagerFragment extends Fragment implements View.OnClickListener
+{
+ protected TaskManager mManager;
+ protected FragmentStatePagerAdapter mPagerAdapter;
+
+ protected ViewPager mViewPager;
+ protected TabLayout mTabLayout;
+
+ protected FloatingActionButton fab;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return initView(inflater.inflate(R.layout.main_fragment, container, false));
+ }
+
+ private View initView(View view) {
+ mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
+ mTabLayout = (TabLayout) view.findViewById(R.id.tablayout);
+ fab = (FloatingActionButton) view.findViewById(R.id.fab);
+ fab.setOnClickListener(this);
+
+ return view;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ mManager = (TaskManager) getActivity();
+ mPagerAdapter = getPagerAdapter();
+ configViewPager();
+ mTabLayout.setupWithViewPager(mViewPager);
+ }
+
+ protected void configViewPager() {
+ mViewPager.setOffscreenPageLimit(2);
+ mViewPager.setAdapter(mPagerAdapter);
+ }
+
+ protected FragmentStatePagerAdapter getPagerAdapter() {
+ return new TaskPagerAdapter(getChildFragmentManager())
+ .addPage(TaskListActive.newInstance(getString(R.string.active_tasks_title)))
+ .addPage(TaskListCompleted.newInstance(getString(R.string.completed_tasks_title)));
+ }
+
+ public static Fragment newInstance(Bundle args) {
+ TaskPagerFragment fragment = new TaskPagerFragment();
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onClick(View v) {
+ mManager.startEditor(null, null, null);
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/AbstractTaskListAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/AbstractTaskListAdapter.java
new file mode 100644
index 0000000..1fff116
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/AbstractTaskListAdapter.java
@@ -0,0 +1,188 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.adapters;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.support.v7.widget.RecyclerView;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.data.db.DbTasksHelper;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.CursorProvider;
+
+
+public abstract class AbstractTaskListAdapter extends RecyclerView.Adapter
+ implements CursorProvider
+{
+ protected static final String OVERDUE = "Просрочено";
+
+ protected static final int LAYOUT = R.layout.task_list_item;
+
+ protected static final String[] FROM = new String[]{
+ DbTasksHelper.TITLE,
+ DbTasksHelper.DESCRIPTION,
+ DbTasksHelper.TTL,
+ DbTasksHelper.DECORATE_COLOR,
+ };
+
+ protected static final int[] TO = new int[]{
+ R.id.task_item_title,
+ R.id.task_item_description,
+ R.id.task_item_deadline,
+ R.id.task_item_color
+ };
+
+ protected static final String[] ACTIVE_DAYS = new String[]{
+ "Сегодня", "Завтра", "Послезавтра"
+ };
+
+ protected static final String[] COMPLETED_DAYS = new String[]{
+ "Сегодня", "Вчера", "Позавчера"
+ };
+
+ private List mMovedPositions;
+
+ private Context mContext;
+
+ private Cursor mCursor;
+
+ private boolean mDataValid;
+
+ private int mRowIdColumn;
+
+ private DataSetObserver mDataSetObserver;
+
+ public AbstractTaskListAdapter(Context context, Cursor cursor) {
+ mContext = context;
+ mCursor = cursor;
+ mDataValid = cursor != null;
+ mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
+ mDataSetObserver = new NotifyingDataSetObserver();
+ if (mCursor != null) {
+ mCursor.registerDataSetObserver(mDataSetObserver);
+ }
+ }
+
+ @Override
+ public void onItemDismiss(int position) {}
+
+ @Override
+ public boolean onItemMove(int fromPosition, int toPosition) {
+ swapPositions(fromPosition, toPosition);
+ notifyItemMoved(fromPosition, toPosition);
+ return true;
+ }
+
+ public Cursor getCursor() {
+ return mCursor;
+ }
+
+ @Override
+ public int getItemCount() {
+ if (mDataValid && mCursor != null) {
+ return mCursor.getCount();
+ }
+ return 0;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
+ return mCursor.getLong(mRowIdColumn);
+ }
+ return 0;
+ }
+
+ @Override
+ public void setHasStableIds(boolean hasStableIds) {
+ super.setHasStableIds(true);
+ }
+
+ public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);
+
+ @Override
+ public void onBindViewHolder(VH viewHolder, int position) {
+ if (!mDataValid) {
+ throw new IllegalStateException("this should only be called when the cursor is valid");
+ }
+ if (!mCursor.moveToPosition(position)) {
+ throw new IllegalStateException("couldn't move cursor to position " + position);
+ }
+ onBindViewHolder(viewHolder, mCursor);
+ }
+
+ /**
+ * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
+ * closed.
+ */
+ public void changeCursor(Cursor cursor) {
+ Cursor old = swapCursor(cursor);
+ if (old != null) {
+ old.close();
+ }
+ }
+
+ /**
+ * Swap in a new Cursor, returning the old Cursor. Unlike
+ * {@link #changeCursor(Cursor)}, the returned old Cursor is not
+ * closed.
+ */
+ public Cursor swapCursor(Cursor newCursor) {
+ if (newCursor == mCursor) {
+ return null;
+ }
+ final Cursor oldCursor = mCursor;
+ if (oldCursor != null && mDataSetObserver != null) {
+ oldCursor.unregisterDataSetObserver(mDataSetObserver);
+ }
+ mCursor = newCursor;
+ if (mCursor != null) {
+ if (mDataSetObserver != null) {
+ mCursor.registerDataSetObserver(mDataSetObserver);
+ }
+ mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
+ mDataValid = true;
+ notifyDataSetChanged();
+ } else {
+ mRowIdColumn = -1;
+ mDataValid = false;
+ notifyDataSetChanged();
+ //There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
+ }
+
+ mMovedPositions = new LinkedList<>();
+ for (int i = 0; i < newCursor.getCount(); i++) {
+ mMovedPositions.add(i);
+ }
+
+ return oldCursor;
+ }
+
+ public void swapPositions(int from, int to) {
+ Collections.swap(mMovedPositions, from, to);
+ }
+
+ public int getMovedPosition(int oldPosition) {
+ return mMovedPositions.get(oldPosition);
+ }
+
+ private class NotifyingDataSetObserver extends DataSetObserver {
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ mDataValid = true;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public void onInvalidated() {
+ super.onInvalidated();
+ mDataValid = false;
+ notifyDataSetChanged();
+ //There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
+ }
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/TaskPagerAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/TaskPagerAdapter.java
new file mode 100644
index 0000000..e150cb4
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/TaskPagerAdapter.java
@@ -0,0 +1,40 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.adapters;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ru.urfu.taskmanager.task_manager.main.fragments.view.TaskListFragment;
+
+public class TaskPagerAdapter extends FragmentStatePagerAdapter
+{
+ private List fragments;
+
+ public TaskPagerAdapter(FragmentManager fm) {
+ super(fm);
+ this.fragments = new ArrayList<>();
+ }
+
+ public TaskPagerAdapter addPage(TaskListFragment fragment) {
+ fragments.add(fragment);
+ return this;
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ return fragments.get(position);
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return fragments.get(position).getTitle();
+ }
+
+ @Override
+ public int getCount() {
+ return fragments.size();
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/TasksListAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/TasksListAdapter.java
new file mode 100644
index 0000000..7151b25
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/adapters/TasksListAdapter.java
@@ -0,0 +1,207 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.adapters;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.drawable.GradientDrawable;
+import android.support.v4.view.MotionEventCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.Calendar;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.data.db.DbFilter;
+import ru.urfu.taskmanager.data.db.DbTasks;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.SimpleDatabase;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.ItemTouchHelperViewHolder;
+import ru.urfu.taskmanager.task_manager.main.fragments.view.TaskListFragment;
+import ru.urfu.taskmanager.task_manager.models.TaskEntry;
+import ru.urfu.taskmanager.utils.tools.TimeUtils;
+
+public class TasksListAdapter extends AbstractTaskListAdapter
+{
+ private final TaskListFragment mFragment;
+ private final SimpleDatabase mDatabase;
+
+ private DbFilter mDefaultFilter;
+
+ public TasksListAdapter(TaskListFragment fragment, DbTasksFilter filter) {
+ super(fragment.getContext(), null);
+ this.mFragment = fragment;
+ this.mDefaultFilter = filter;
+ this.mDatabase = DbTasks.getInstance();
+ updateData(mDatabase.getCursor(mDefaultFilter));
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) {
+ TaskEntry entry = mDatabase.getCurrentEntryFromCursor(cursor);
+ TaskEntry prev = (cursor.moveToPrevious())
+ ? mDatabase.getCurrentEntryFromCursor(cursor)
+ : null;
+
+ GradientDrawable gd = new GradientDrawable();
+ gd.setColor(entry.getColorInt());
+ gd.setCornerRadius(100f);
+
+ viewHolder.title.setText(entry.getTitle());
+ viewHolder.description.setText(entry.getDescription());
+ viewHolder.ttl.setText(TimeUtils.getHoursAndMinutesFromUnix(entry.getTtlTimestamp()).toString());
+ viewHolder.ttl.setBackground(gd);
+
+ ViewCompat.setTransitionName(viewHolder.ttl, String.valueOf(cursor.getPosition()) + mDefaultFilter.getType());
+ attachHeader(viewHolder, entry, prev);
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ LayoutInflater inflater = (LayoutInflater) parent.getContext()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ return new ViewHolder(inflater.inflate(LAYOUT, parent, false));
+ }
+
+ private ViewHolder attachHeader(ViewHolder holder, TaskEntry entry, TaskEntry prev) {
+ String entryTitle = getTitleFromEntry(entry);
+
+ if (entryTitle.equals(OVERDUE))
+ holder.layout.setAlpha(0.4f);
+ else holder.layout.setAlpha(1f);
+
+ if (mDefaultFilter.isOrdered()) {
+ holder.header_text.setText(entryTitle);
+ holder.header.setVisibility(View.VISIBLE);
+ return holder;
+ }
+
+ if (prev != null) {
+ String prevTitle = getTitleFromEntry(prev);
+
+ if (!entryTitle.equals(prevTitle)) {
+ holder.header_text.setText(entryTitle);
+ holder.header.setVisibility(View.VISIBLE);
+ } else {
+ holder.header.setVisibility(View.GONE);
+ }
+ } else {
+ holder.header_text.setText(entryTitle);
+ holder.header.setVisibility(View.VISIBLE);
+ }
+
+ return holder;
+ }
+
+ private String getTitleFromEntry(TaskEntry entry) {
+ if (System.currentTimeMillis() > entry.getTtlTimestamp() & mDefaultFilter.getType() == DbTasksFilter.ACTIVE_TASK) {
+ return OVERDUE;
+ } else {
+ Calendar entryDate = Calendar.getInstance();
+ entryDate.setTimeInMillis(entry.getTtlTimestamp());
+ int diffDay = Math.abs(entryDate.get(Calendar.DAY_OF_YEAR) - Calendar.getInstance().get(Calendar.DAY_OF_YEAR));
+ return getHeaderTitleByNum(diffDay, entryDate);
+ }
+ }
+
+ private String getHeaderTitleByNum(int num, Calendar entryDate) {
+ if (num < 3) {
+ switch (mDefaultFilter.getType()) {
+ case DbTasksFilter.ACTIVE_TASK:
+ return ACTIVE_DAYS[num];
+ case DbTasksFilter.COMPLETED_TASK:
+ return COMPLETED_DAYS[num];
+ }
+ }
+
+ return TimeUtils.format(entryDate);
+ }
+
+ public void updateData(Cursor... cursor) {
+ if (cursor.length == 0) {
+ updateCursor(mDatabase.getCursor(mDefaultFilter));
+ } else {
+ updateCursor(cursor[0]);
+ }
+ }
+
+ public void updateFilter(DbFilter filter) {
+ mDefaultFilter = filter;
+ }
+
+ private void updateCursor(Cursor cursor) {
+ changeCursor(cursor);
+ }
+
+ public int getDataType() {
+ return mDefaultFilter.getType();
+ }
+
+ private void updateOrders() {
+ mDatabase.startTransaction(aVoid -> {
+ for (int position = 0; position < getItemCount(); position++) {
+ TaskEntry current = mDatabase.getEntryById((int) getItemId(getMovedPosition(position)));
+ current.setOrder(position);
+ mDatabase.updateEntry(current);
+ }
+ });
+ }
+
+ public class ViewHolder extends RecyclerView.ViewHolder
+ implements View.OnClickListener, View.OnLongClickListener, ItemTouchHelperViewHolder
+ {
+
+ public View layout;
+ public View header;
+ public TextView header_text;
+ public TextView title;
+ public TextView description;
+ public TextView ttl;
+
+ public ViewHolder(View view) {
+ super(view);
+ this.layout = view.findViewById(R.id.task_layout);
+ this.header = view.findViewById(R.id.task_header);
+ this.header_text = (TextView) view.findViewById(R.id.header_text);
+ this.title = (TextView) view.findViewById(R.id.task_item_title);
+ this.description = (TextView) view.findViewById(R.id.task_item_description);
+ this.ttl = (TextView) view.findViewById(R.id.task_item_deadline);
+
+ layout.setOnClickListener(this);
+ layout.setOnLongClickListener(this);
+
+ layout.setOnTouchListener((v, event) -> {
+ if (mDefaultFilter.isOrdered()) {
+ if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
+ mFragment.onStartDrag(ViewHolder.this);
+ }
+ }
+
+ return false;
+ });
+ }
+
+ @Override
+ public void onClick(View v) {
+ mFragment.onItemClick(this, getAdapterPosition(), TasksListAdapter.this.getItemId(getAdapterPosition()));
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ mFragment.onItemLongClick(this, getAdapterPosition(), TasksListAdapter.this.getItemId(getAdapterPosition()));
+ return true;
+ }
+
+ @Override
+ public void onItemSelected() {}
+
+ @Override
+ public void onItemClear() {
+ updateOrders();
+ }
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/CursorProvider.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/CursorProvider.java
new file mode 100644
index 0000000..af0c027
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/CursorProvider.java
@@ -0,0 +1,10 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.helper;
+
+import android.database.Cursor;
+
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.ItemTouchHelperAdapter;
+
+public interface CursorProvider extends ItemTouchHelperAdapter
+{
+ Cursor getCursor();
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/ItemTouchHelperAdapter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/ItemTouchHelperAdapter.java
new file mode 100644
index 0000000..6b7413c
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/ItemTouchHelperAdapter.java
@@ -0,0 +1,8 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.helper;
+
+public interface ItemTouchHelperAdapter {
+
+ boolean onItemMove(int fromPosition, int toPosition);
+
+ void onItemDismiss(int position);
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/ItemTouchHelperViewHolder.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/ItemTouchHelperViewHolder.java
new file mode 100644
index 0000000..6853a72
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/ItemTouchHelperViewHolder.java
@@ -0,0 +1,8 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.helper;
+
+public interface ItemTouchHelperViewHolder {
+
+ void onItemSelected();
+
+ void onItemClear();
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/OnStartDragListener.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/OnStartDragListener.java
new file mode 100644
index 0000000..f2b09dd
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/OnStartDragListener.java
@@ -0,0 +1,7 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.helper;
+
+import android.support.v7.widget.RecyclerView;
+
+public interface OnStartDragListener {
+ void onStartDrag(RecyclerView.ViewHolder viewHolder);
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/SimpleItemTouchHelperCallback.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/SimpleItemTouchHelperCallback.java
new file mode 100644
index 0000000..5b29eed
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/helper/SimpleItemTouchHelperCallback.java
@@ -0,0 +1,90 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.helper;
+
+import android.graphics.Canvas;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
+
+public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
+
+ public static final float ALPHA_FULL = 1.0f;
+
+ private final ItemTouchHelperAdapter mAdapter;
+
+ public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
+ mAdapter = adapter;
+ }
+
+ @Override
+ public boolean isLongPressDragEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isItemViewSwipeEnabled() {
+ return false;
+ }
+
+ @Override
+ public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
+ if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
+ final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
+ final int swipeFlags = 0;
+ return makeMovementFlags(dragFlags, swipeFlags);
+ } else {
+ final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
+ final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
+ return makeMovementFlags(dragFlags, swipeFlags);
+ }
+ }
+
+ @Override
+ public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
+ if (source.getItemViewType() != target.getItemViewType()) {
+ return false;
+ }
+
+ mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
+ return true;
+ }
+
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
+ mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
+ }
+
+ @Override
+ public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
+ if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
+ final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
+ viewHolder.itemView.setAlpha(alpha);
+ viewHolder.itemView.setTranslationX(dX);
+ } else {
+ super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
+ }
+ }
+
+ @Override
+ public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
+ if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
+ if (viewHolder instanceof ItemTouchHelperViewHolder) {
+ ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
+ itemViewHolder.onItemSelected();
+ }
+ }
+
+ super.onSelectedChanged(viewHolder, actionState);
+ }
+
+ @Override
+ public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
+ super.clearView(recyclerView, viewHolder);
+
+ viewHolder.itemView.setAlpha(ALPHA_FULL);
+
+ if (viewHolder instanceof ItemTouchHelperViewHolder) {
+ ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
+ itemViewHolder.onItemClear();
+ }
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/CustomTransition.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/CustomTransition.java
new file mode 100644
index 0000000..83d79b8
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/CustomTransition.java
@@ -0,0 +1,28 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.view;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.transition.ChangeImageTransform;
+import android.transition.ChangeTransform;
+import android.util.AttributeSet;
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class CustomTransition extends android.transition.TransitionSet
+{
+ public CustomTransition() {
+ init();
+ }
+
+ public CustomTransition(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ private void init() {
+ setOrdering(ORDERING_TOGETHER);
+ addTransition(new android.transition.ChangeBounds()).
+ addTransition(new ChangeTransform()).
+ addTransition(new ChangeImageTransform());
+ }
+}
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListActive.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListActive.java
similarity index 56%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListActive.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListActive.java
index 93814d1..def71ad 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListActive.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListActive.java
@@ -1,47 +1,57 @@
-package ru.urfu.taskmanager.task_manager.fragments.view;
+package ru.urfu.taskmanager.task_manager.main.fragments.view;
+import android.os.Bundle;
import android.support.v7.widget.PopupMenu;
import android.view.Gravity;
-import android.view.View;
-import android.widget.AdapterView;
import com.github.florent37.singledateandtimepicker.dialog.SingleDateAndTimePickerDialog;
import java.util.Date;
import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.task_manager.fragments.adapters.TasksListAdapter;
-import ru.urfu.taskmanager.utils.db.DbTasksHelper;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TasksListAdapter;
+import ru.urfu.taskmanager.data.db.DbTasksHelper;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
public class TaskListActive extends TaskListFragment
{
+ private DbTasksFilter filter;
+
+ public static TaskListActive newInstance(String title) {
+ Bundle args = new Bundle();
+ args.putString(ARG_TITLE_KEY, title);
+
+ TaskListActive fragment = new TaskListActive();
+ fragment.setArguments(args);
+ return fragment;
+ }
+
@Override
protected TasksListAdapter getAdapter() {
- return new TasksListAdapter(getContext(),
- DbTasksFilter.builder()
- .setType(DbTasksFilter.ACTIVE_TASK)
- .sortBy(DbTasksHelper.TTL)
- .build()
- );
+ mManager.getFilterLayoutWrapper().onCompileFilter(builder -> filter = builder.setType(DbTasksFilter.ACTIVE_TASK)
+ .sortBy(DbTasksHelper.TTL)
+ .build());
+
+ return new TasksListAdapter(this, filter);
}
@SuppressWarnings("deprecation")
@Override
- public void onItemClick(AdapterView> parent, View view, int position, long id) {
- PopupMenu popup = new PopupMenu(getContext(), view);
+ public void onItemClick(TasksListAdapter.ViewHolder holder, int position, long id) {
+ PopupMenu popup = new PopupMenu(getContext(), holder.layout);
popup.getMenuInflater().inflate(R.menu.active_task_option_menu, popup.getMenu());
+ popup.setGravity(Gravity.END);
popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.task_is_complete:
- mPresenter.taskIsCompleted((int) id);
+ mManager.getPresenter().taskIsCompleted((int) id);
break;
case R.id.edit_the_task:
- mPresenter.editTheTask((int) id);
+ mManager.getPresenter().editTheTask(position, mAdapter, holder);
break;
case R.id.postpone_the_task: {
- mPresenter.postponeTheTask(
+ mManager.getPresenter().postponeTheTask(
(int) id, (date, entry) ->
new SingleDateAndTimePickerDialog.Builder(getContext())
.mainColor(getResources().getColor(R.color.colorAccent))
@@ -55,13 +65,12 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
}
break;
case R.id.delete_the_task:
- mPresenter.deleteTheTask((int) id);
+ mManager.getPresenter().deleteTheTask((int) id);
break;
}
return true;
});
- popup.setGravity(Gravity.END);
popup.show();
}
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListCompleted.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListCompleted.java
similarity index 58%
rename from Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListCompleted.java
rename to Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListCompleted.java
index 5e9195f..47dd2cf 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/fragments/view/TaskListCompleted.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListCompleted.java
@@ -1,41 +1,50 @@
-package ru.urfu.taskmanager.task_manager.fragments.view;
+package ru.urfu.taskmanager.task_manager.main.fragments.view;
+import android.os.Bundle;
import android.support.v7.widget.PopupMenu;
import android.view.Gravity;
-import android.view.View;
-import android.widget.AdapterView;
import com.github.florent37.singledateandtimepicker.dialog.SingleDateAndTimePickerDialog;
import java.util.Date;
import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.task_manager.fragments.adapters.TasksListAdapter;
-import ru.urfu.taskmanager.utils.db.DbTasksHelper;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksHelper;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TasksListAdapter;
public class TaskListCompleted extends TaskListFragment
{
+ private DbTasksFilter filter;
+
+ public static TaskListCompleted newInstance(String title) {
+ Bundle args = new Bundle();
+ args.putString(ARG_TITLE_KEY, title);
+
+ TaskListCompleted fragment = new TaskListCompleted();
+ fragment.setArguments(args);
+ return fragment;
+ }
+
@Override
protected TasksListAdapter getAdapter() {
- return new TasksListAdapter(getContext(),
- DbTasksFilter.builder()
- .setType(DbTasksFilter.COMPLETED_TASK)
- .sortBy(DbTasksHelper.TTL)
- .build()
- );
+ mManager.getFilterLayoutWrapper().onCompileFilter(builder -> filter = builder.setType(DbTasksFilter.COMPLETED_TASK)
+ .sortBy(DbTasksHelper.TTL)
+ .build());
+
+ return new TasksListAdapter(this, filter);
}
@SuppressWarnings("deprecation")
@Override
- public void onItemClick(AdapterView> parent, View view, int position, long id) {
- PopupMenu popup = new PopupMenu(getContext(), view);
+ public void onItemClick(TasksListAdapter.ViewHolder holder, int position, long id) {
+ PopupMenu popup = new PopupMenu(getContext(), holder.layout);
popup.getMenuInflater().inflate(R.menu.completed_task_option_menu, popup.getMenu());
popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.restore_the_task: {
- mPresenter.restoreTheTask(
+ mManager.getPresenter().restoreTheTask(
(int) id, (date, entry) ->
new SingleDateAndTimePickerDialog.Builder(getContext())
.mainColor(getResources().getColor(R.color.colorAccent))
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListFragment.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListFragment.java
new file mode 100644
index 0000000..2443040
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListFragment.java
@@ -0,0 +1,105 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.view;
+
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import ru.urfu.taskmanager.R;
+import ru.urfu.taskmanager.data.db.DbFilter;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TasksListAdapter;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.OnStartDragListener;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.SimpleItemTouchHelperCallback;
+import ru.urfu.taskmanager.task_manager.main.view.TaskManager;
+
+public abstract class TaskListFragment extends Fragment
+ implements TaskListView, OnStartDragListener
+{
+ public static final String ARG_TITLE_KEY = "ru.urfu.taskmanager.task_manager.ARG_TITLE_KEY";
+ private ItemTouchHelper mItemTouchHelper;
+ protected TaskManager mManager;
+
+ RecyclerView mTaskListView;
+ TasksListAdapter mAdapter;
+
+ @Override
+ public String getTitle() {
+ return getArguments().getString(ARG_TITLE_KEY);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.active_tasks_fragment, container, false);
+ return initView(view);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ mManager = (TaskManager) getActivity();
+ mManager.getPresenter().bindView(this);
+
+ mTaskListView.setLayoutManager(new LinearLayoutManager(getContext()));
+ mTaskListView.setAdapter(mAdapter = getAdapter());
+
+ ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(mAdapter);
+ mItemTouchHelper = new ItemTouchHelper(callback);
+ mItemTouchHelper.attachToRecyclerView(mTaskListView);
+ }
+
+ protected View initView(View root) {
+ mTaskListView = (RecyclerView) root.findViewById(R.id.task_list);
+ return root;
+ }
+
+ protected abstract TasksListAdapter getAdapter();
+
+ public abstract void onItemClick(TasksListAdapter.ViewHolder holder, int position, long id);
+
+ public boolean onItemLongClick(TasksListAdapter.ViewHolder holder, int position, long id) {
+ mManager.startEditor(position, mAdapter, holder);
+ return true;
+ }
+
+ @Override
+ public void onUpdate(Cursor... cursor) {
+ getActivity().runOnUiThread(() -> mAdapter.updateData(cursor));
+ }
+
+ @Override
+ public void onUpdate(DbFilter filter) {
+ getActivity().runOnUiThread(() -> mAdapter.updateFilter(filter));
+ }
+
+ @Override
+ public Fragment getInstance() {
+ return this;
+ }
+
+ @Override
+ public int getDataType() {
+ return mAdapter.getDataType();
+ }
+
+ @Override
+ public void showAlert(String message) {
+ Snackbar.make(getActivity().getWindow().getDecorView(), message, 2000).show();
+ }
+
+ @Override
+ public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
+ mItemTouchHelper.startDrag(viewHolder);
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ mManager.getPresenter().unBindView(this);
+ }
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListView.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListView.java
new file mode 100644
index 0000000..ca1da86
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/fragments/view/TaskListView.java
@@ -0,0 +1,16 @@
+package ru.urfu.taskmanager.task_manager.main.fragments.view;
+
+import android.database.Cursor;
+import android.support.v4.app.Fragment;
+
+import ru.urfu.taskmanager.task_manager.main.adapters.OnDataUpdateListener;
+import ru.urfu.taskmanager.utils.interfaces.Showable;
+
+public interface TaskListView extends OnDataUpdateListener, Showable
+{
+ String getTitle();
+
+ int getDataType();
+
+ Fragment getInstance();
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenter.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenter.java
index d21b947..1038045 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenter.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenter.java
@@ -1,13 +1,14 @@
package ru.urfu.taskmanager.task_manager.main.presenter;
-import android.content.Intent;
import android.net.Uri;
import java.util.Date;
-import ru.urfu.taskmanager.task_manager.fragments.view.TaskListView;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.CursorProvider;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TasksListAdapter;
+import ru.urfu.taskmanager.task_manager.main.fragments.view.TaskListView;
import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
import ru.urfu.taskmanager.utils.interfaces.Callback;
import ru.urfu.taskmanager.utils.interfaces.Coupler;
@@ -15,6 +16,8 @@ public interface TaskManagerPresenter
{
TaskListView bindView(TaskListView view);
+ TaskListView unBindView(TaskListView view);
+
void taskIsCompleted(int id);
void postponeTheTask(int id, Coupler, TaskEntry> coupler);
@@ -23,7 +26,7 @@ public interface TaskManagerPresenter
void restoreTheTask(int id, Coupler, TaskEntry> coupler);
- void editTheTask(int id);
+ void editTheTask(int id, CursorProvider adapter, TasksListAdapter.ViewHolder holder);
void applyFilter(DbTasksFilter.Builder filterBuilder);
@@ -31,7 +34,9 @@ public interface TaskManagerPresenter
void exportData(String path);
- void onResult(int requestCode, int resultCode, Intent data);
+ void importData(Uri path);
+
+ void onResult(int requestCode);
void onDestroy();
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenterImpl.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenterImpl.java
index 9dbef8e..fd1e62e 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenterImpl.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/presenter/TaskManagerPresenterImpl.java
@@ -1,10 +1,8 @@
package ru.urfu.taskmanager.task_manager.main.presenter;
-import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -13,49 +11,55 @@
import java.util.concurrent.atomic.AtomicInteger;
import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.task_manager.fragments.view.TaskListView;
-import ru.urfu.taskmanager.task_manager.main.tools.DataExportController;
-import ru.urfu.taskmanager.task_manager.main.tools.DataImportController;
-import ru.urfu.taskmanager.task_manager.main.tools.BackupManager;
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.data.backup.BackupManager;
+import ru.urfu.taskmanager.data.backup.DataExportController;
+import ru.urfu.taskmanager.data.backup.DataImportController;
+import ru.urfu.taskmanager.data.backup.TasksGenerator;
+import ru.urfu.taskmanager.data.db.DbFilter;
+import ru.urfu.taskmanager.data.db.DbTasks;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.async.DbAsyncExecutor;
+import ru.urfu.taskmanager.data.db.async.ExecuteControllerAdapter;
+import ru.urfu.taskmanager.data.network.APIServiceExecutor;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.CursorProvider;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TasksListAdapter;
+import ru.urfu.taskmanager.task_manager.main.fragments.view.TaskListView;
import ru.urfu.taskmanager.task_manager.main.view.TaskManager;
-import ru.urfu.taskmanager.task_manager.main.tools.TasksGenerator;
import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.utils.db.async.DbAsyncExecutor;
-import ru.urfu.taskmanager.utils.db.DbFilter;
-import ru.urfu.taskmanager.utils.db.DbTasks;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
-import ru.urfu.taskmanager.utils.db.async.ExecuteControllerAdapter;
import ru.urfu.taskmanager.utils.interfaces.Callback;
import ru.urfu.taskmanager.utils.interfaces.Coupler;
-import static android.app.Activity.RESULT_OK;
import static ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity.REQUEST_CREATE;
import static ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity.REQUEST_EDIT;
-import static ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity.REQUEST_IMPORT;
public class TaskManagerPresenterImpl implements TaskManagerPresenter
{
private static final String EXPORTED_FILENAME = "itemlist.ili";
private final TaskManager mManager;
- private final DbAsyncExecutor dbAsyncExecutor;
+ private final APIServiceExecutor mAPIServiceExecutor;
+ private final DbAsyncExecutor mDbAsyncExecutor;
private final BackupManager mDataExporter;
private final List mTasksList;
public TaskManagerPresenterImpl(TaskManager view) {
this.mManager = view;
this.mTasksList = new ArrayList<>();
- this.dbAsyncExecutor = DbTasks.getInstance().getAsyncExecutor();
+ this.mAPIServiceExecutor = User.getActiveUser().getExecutor();
this.mDataExporter = new BackupManager();
+ this.mDbAsyncExecutor = DbTasks.getInstance().getAsyncExecutor();
}
@Override
public void taskIsCompleted(int id) {
+ long timestamp = System.currentTimeMillis();
+
TaskEntry updatedEntry = new TaskEntry(id)
- .setTtl(System.currentTimeMillis())
- .setCompleted(true);
+ .setTtl(timestamp)
+ .setEdited(timestamp);
- dbAsyncExecutor.updateEntry(updatedEntry, new ExecuteControllerAdapter() {
+ mAPIServiceExecutor.updateEntry(updatedEntry, new ExecuteControllerAdapter() {
@Override
public void onFinish() {
notifyDataUpdate();
@@ -65,25 +69,28 @@ public void onFinish() {
@Override
public void postponeTheTask(int id, Coupler, TaskEntry> coupler) {
- dbAsyncExecutor.getEntryById(id, new ExecuteControllerAdapter() {
+ mDbAsyncExecutor.getEntryById(id, new ExecuteControllerAdapter()
+ {
@Override
public void onFinish(TaskEntry entry) {
- coupler.bind(date -> {
- entry.setTtl(date.getTime());
- dbAsyncExecutor.updateEntry(entry, new ExecuteControllerAdapter() {
- @Override
- public void onFinish() {
- notifyDataUpdate();
+ coupler.bind(date -> mAPIServiceExecutor.updateEntry(
+ entry.setTtl(date.getTime())
+ .setEdited(System.currentTimeMillis()),
+ new ExecuteControllerAdapter()
+ {
+ @Override
+ public void onFinish() {
+ notifyDataUpdate();
+ }
}
- });
- }, entry);
+ ), entry);
}
});
}
@Override
public void deleteTheTask(int id) {
- dbAsyncExecutor.removeEntryById(id, new ExecuteControllerAdapter() {
+ mAPIServiceExecutor.removeEntryById(id, new ExecuteControllerAdapter() {
@Override
public void onFinish() {
notifyDataUpdate();
@@ -93,13 +100,13 @@ public void onFinish() {
@Override
public void restoreTheTask(int id, Coupler, TaskEntry> coupler) {
- dbAsyncExecutor.getEntryById(id, new ExecuteControllerAdapter() {
+ mDbAsyncExecutor.getEntryById(id, new ExecuteControllerAdapter()
+ {
@Override
public void onFinish(TaskEntry entry) {
- entry.setCompleted(false);
coupler.bind(date -> {
- entry.setTtl(date.getTime());
- dbAsyncExecutor.updateEntry(entry, new ExecuteControllerAdapter() {
+ entry.setTtl(date.getTime()).setEdited(System.currentTimeMillis());
+ mAPIServiceExecutor.updateEntry(entry, new ExecuteControllerAdapter() {
@Override
public void onFinish() {
notifyDataUpdate();
@@ -111,8 +118,8 @@ public void onFinish() {
}
@Override
- public void editTheTask(int id) {
- mManager.startEditor(id);
+ public void editTheTask(int id, CursorProvider adapter, TasksListAdapter.ViewHolder holder) {
+ mManager.startEditor(id, adapter, holder);
}
@Override
@@ -127,7 +134,7 @@ public void generateBigData() {
@Override
public void exportData(String path) {
- dbAsyncExecutor.getAllEntries(
+ mAPIServiceExecutor.getAllEntries(
new DataExportController<>(
mManager.getBaseContext(), mManager,
path, EXPORTED_FILENAME,
@@ -136,43 +143,47 @@ public void exportData(String path) {
);
}
- private void importData(Uri uri) throws FileNotFoundException {
- InputStream inputStream = mManager.getBaseContext()
- .getContentResolver()
- .openInputStream(uri);
-
- mDataExporter.importFrom(inputStream, TaskEntry.class,
- new DataImportController<>(mManager, dbAsyncExecutor, aVoid -> notifyDataUpdate())
- );
+ @Override
+ public void importData(Uri uri) {
+ InputStream inputStream;
+
+ try {
+ inputStream = mManager.getBaseContext()
+ .getContentResolver()
+ .openInputStream(uri);
+
+ mDataExporter.importFrom(inputStream, TaskEntry.class,
+ new DataImportController<>(mManager, mDbAsyncExecutor, aVoid -> mManager.syncData())
+ );
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
}
@Override
public TaskListView bindView(TaskListView view) {
mTasksList.add(view);
- return view.bindPresenter(this);
+ return view;
}
@Override
- public void onResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == RESULT_OK) {
- switch (requestCode) {
- case REQUEST_CREATE:
- mManager.showAlert(mManager.getResources().getString(R.string.task_was_created));
- break;
- case REQUEST_EDIT:
- mManager.showAlert(mManager.getResources().getString(R.string.task_was_updated));
- break;
- case REQUEST_IMPORT:
- try {
- importData(data.getData());
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- break;
- }
+ public TaskListView unBindView(TaskListView view) {
+ mTasksList.remove(view);
+ return view;
+ }
- notifyDataUpdate();
+ @Override
+ public void onResult(int requestCode) {
+ switch (requestCode) {
+ case REQUEST_CREATE:
+ mManager.showAlert(mManager.getResources().getString(R.string.task_was_created));
+ break;
+ case REQUEST_EDIT:
+ mManager.showAlert(mManager.getResources().getString(R.string.task_was_updated));
+ break;
}
+
+ notifyDataUpdate();
}
private void notifyDataUpdate() {
@@ -190,7 +201,7 @@ private void notifyDataUpdate(DbTasksFilter.Builder builder) {
.setType(taskList.getDataType())
.build();
- dbAsyncExecutor.getCursor(filter, new ExecuteControllerAdapter() {
+ mAPIServiceExecutor.getCursor(filter, new ExecuteControllerAdapter() {
@Override
public void onStart() {
mManager.showProgress();
@@ -200,6 +211,7 @@ public void onStart() {
@Override
public void onFinish(Cursor cursor) {
taskList.onUpdate(cursor);
+ taskList.onUpdate(filter);
if (counter.decrementAndGet() == 0)
mManager.hideProgress();
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManager.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManager.java
index dff7d30..ef8ad55 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManager.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManager.java
@@ -1,10 +1,23 @@
package ru.urfu.taskmanager.task_manager.main.view;
-import android.view.View;
+import android.support.annotation.Nullable;
+import android.support.v4.app.FragmentManager;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.CursorProvider;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TasksListAdapter;
+import ru.urfu.taskmanager.task_manager.main.filter.FilterLayoutWrapper;
+import ru.urfu.taskmanager.task_manager.main.presenter.TaskManagerPresenter;
import ru.urfu.taskmanager.utils.interfaces.Progressive;
-public interface TaskManager extends View.OnClickListener, Progressive
+public interface TaskManager extends Progressive
{
- void startEditor(int id);
+ TaskManagerPresenter getPresenter();
+
+ FilterLayoutWrapper getFilterLayoutWrapper();
+
+ FragmentManager getSupportFragmentManager();
+
+ void syncData();
+
+ void startEditor(@Nullable Integer position, CursorProvider adapter, TasksListAdapter.ViewHolder viewHolder);
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManagerActivity.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManagerActivity.java
index 7540e30..f1ef3cd 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManagerActivity.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/main/view/TaskManagerActivity.java
@@ -2,22 +2,32 @@
import android.Manifest;
import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Configuration;
+import android.net.ConnectivityManager;
+import android.os.Build;
import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
-import android.support.design.widget.TabLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.MenuItemCompat;
-import android.support.v4.view.ViewPager;
+import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.InputType;
+import android.transition.Fade;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
@@ -28,6 +38,7 @@
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
+import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById;
@@ -35,28 +46,33 @@
import java.lang.reflect.Field;
import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.task_manager.fragments.view.TaskListActive;
-import ru.urfu.taskmanager.task_manager.fragments.view.TaskListCompleted;
+import ru.urfu.taskmanager.auth.models.User;
+import ru.urfu.taskmanager.data.db.DbTasksFilter;
+import ru.urfu.taskmanager.data.db.DbTasksHelper;
+import ru.urfu.taskmanager.data.network.sync_module.BroadcastSyncManager;
+import ru.urfu.taskmanager.task_manager.editor.view.EditorPagerFragment;
+import ru.urfu.taskmanager.task_manager.editor.view.TaskEditorFragment;
+import ru.urfu.taskmanager.task_manager.main.fragments.TaskPagerFragment;
+import ru.urfu.taskmanager.task_manager.main.fragments.helper.CursorProvider;
+import ru.urfu.taskmanager.task_manager.main.fragments.adapters.TasksListAdapter;
+import ru.urfu.taskmanager.task_manager.main.fragments.view.CustomTransition;
import ru.urfu.taskmanager.task_manager.main.adapters.FiltersAdapter;
import ru.urfu.taskmanager.task_manager.main.adapters.PermissionsAdapter;
import ru.urfu.taskmanager.task_manager.main.adapters.SavedFiltersAdapter;
-import ru.urfu.taskmanager.task_manager.main.adapters.ViewPagerAdapter;
import ru.urfu.taskmanager.task_manager.main.filter.FilterLayoutWrapper;
import ru.urfu.taskmanager.task_manager.main.presenter.TaskManagerPresenter;
import ru.urfu.taskmanager.task_manager.main.presenter.TaskManagerPresenterImpl;
-import ru.urfu.taskmanager.task_manager.task_editor.view.TaskEditorActivity;
-import ru.urfu.taskmanager.task_manager.task_editor.view.TaskEditorActivity_;
-import ru.urfu.taskmanager.utils.db.DbTasksFilter;
-import ru.urfu.taskmanager.utils.db.DbTasksHelper;
import ru.urfu.taskmanager.utils.tools.DirectoryChooser;
+import static ru.urfu.taskmanager.task_manager.editor.view.EditorPagerFragment.EDITOR_PAGER_POSITION;
+
@EActivity(R.layout.activity_task_list)
public class TaskManagerActivity extends AppCompatActivity
- implements TaskManager, MenuItemCompat.OnActionExpandListener, SearchView.OnQueryTextListener
+ implements TaskManager,
+ MenuItemCompat.OnActionExpandListener,
+ SearchView.OnQueryTextListener,
+ NavigationView.OnNavigationItemSelectedListener
{
- public static final String ACTION_CREATE = "ru.urfu.taskmanager.ACTION_CREATE";
- public static final String ACTION_EDIT = "ru.urfu.taskmanager.ACTION_EDIT";
-
public static final int REQUEST_CREATE = 1;
public static final int REQUEST_EDIT = 2;
public static final int REQUEST_IMPORT = 3;
@@ -69,30 +85,34 @@ private enum ToolbarMode {
NORMAL, SEARCH, FILTER
}
+ private BroadcastReceiver mBroadcastSyncManager;
private FilterLayoutWrapper mFilterLayoutWrapper;
private FiltersAdapter mAdapter;
+ @ViewById(R.id.drawer_layout)
+ DrawerLayout mDrawerLayout;
+
+ @ViewById(R.id.nav_view)
+ NavigationView mNavigationView;
+
+ @ViewById(R.id.fragment_place)
+ FrameLayout mFragmentLayout;
+
+ @ViewById(R.id.nav_landscape_container)
+ FrameLayout mNavigationContainer;
+
@ViewById(R.id.animate_progress_bar)
AnimateHorizontalProgressBar mProgressBar;
@ViewById(R.id.circleProgressBar)
ProgressBar mCircleProgressBar;
- @ViewById(R.id.viewpager)
- ViewPager mViewPager;
-
- @ViewById(R.id.tablayout)
- TabLayout mTabLayout;
-
@ViewById(R.id.toolbar)
Toolbar mToolbar;
@ViewById(R.id.filter_layout)
View mFilterLayout;
- @ViewById(R.id.fab)
- FloatingActionButton floatingActionButton;
-
ProgressDialog mProgressDialog;
Spinner mSearchBySpinner;
@@ -101,30 +121,70 @@ private enum ToolbarMode {
MenuItem mSearchSpinnerItem;
MenuItem mFilterCatalogMenuItem;
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
+ @AfterViews
+ public void initialize() {
+ onConfigurationChanged(getResources().getConfiguration());
+
+ mPresenter = new TaskManagerPresenterImpl(this);
+
setupPermissionController();
- initialize();
+ setupReceiver();
mAdapter = new SavedFiltersAdapter(this, this::onApplyFilter);
mFilterLayoutWrapper = new FilterLayoutWrapper(mFilterLayout)
.setFiltersAdapter(mAdapter)
.onSaveButtonClick(this::onSaveFilter)
.onApplyButtonClick(this::onApplyFilter);
+
+
+ setSupportActionBar(mToolbar);
+ mProgressDialog = new ProgressDialog(this);
+ mNavigationView.setNavigationItemSelectedListener(this);
+
+ getSupportFragmentManager()
+ .beginTransaction()
+ .add(R.id.fragment_place, TaskPagerFragment.newInstance(new Bundle()))
+ .commit();
+
+ showAlert("USER_ID: " + User.getActiveUser().getUserId());
}
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
+ mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
+ mNavigationContainer.removeAllViews();
+ } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+
+ NavigationView navigationView = new NavigationView(this);
+ navigationView.inflateMenu(R.menu.nav_menu_bar);
+ navigationView.setNavigationItemSelectedListener(this);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ navigationView.setElevation(1f);
+ }
- private void initialize() {
- mPresenter = new TaskManagerPresenterImpl(this);
+ mNavigationContainer.addView(navigationView);
+ }
+ }
- setSupportActionBar(mToolbar);
- mViewPager.setOffscreenPageLimit(2);
- setupViewPager(mViewPager);
- mTabLayout.setupWithViewPager(mViewPager);
+ private void setupReceiver() {
+ IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(BroadcastSyncManager.SYNC_ASK_ACTION);
+ filter.addAction(BroadcastSyncManager.SYNC_SUCCESS_ACTION);
+ filter.addAction(BroadcastSyncManager.SYNC_FAILED_ACTION);
+ filter.addAction(BroadcastSyncManager.SYNC_START_ACTION);
+ filter.addAction(BroadcastSyncManager.SYNC_SCHEDULE_ACTION);
+
+ mBroadcastSyncManager = new BroadcastSyncManager(this) {
+ @Override
+ public void onStopSync() {
+ mPresenter.applyFilter(DbTasksFilter.DEFAULT_BUILDER);
+ }
+ };
- mProgressDialog = new ProgressDialog(this);
- floatingActionButton.setOnClickListener(this);
+ registerReceiver(mBroadcastSyncManager, filter);
}
private void setupPermissionController() {
@@ -147,15 +207,6 @@ public void onPermissionsChecked(MultiplePermissionsReport report) {
.check();
}
- private void setupViewPager(ViewPager viewPager) {
- ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
- adapter.add(mPresenter.bindView(new TaskListActive()), getString(R.string.active_tasks_title));
- adapter.add(mPresenter.bindView(new TaskListCompleted()), getString(R.string.completed_tasks_title));
-
- viewPager.setAdapter(adapter);
- viewPager.setCurrentItem(0);
- }
-
private void startToolbarMode(ToolbarMode startedToolbarMode) {
switch (startedToolbarMode) {
case FILTER:
@@ -164,8 +215,7 @@ private void startToolbarMode(ToolbarMode startedToolbarMode) {
mSearchSpinnerItem.setVisible(false);
mFilterCatalogMenuItem.setVisible(true);
- mViewPager.setVisibility(View.INVISIBLE);
- mTabLayout.setVisibility(View.INVISIBLE);
+ mFragmentLayout.setVisibility(View.INVISIBLE);
mFilterLayout.setVisibility(View.VISIBLE);
mToolbar.setTitle(getString(R.string.toolbar_filter_title));
@@ -186,8 +236,7 @@ private void startToolbarMode(ToolbarMode startedToolbarMode) {
mSearchSpinnerItem.setVisible(false);
mFilterCatalogMenuItem.setVisible(false);
- mViewPager.setVisibility(View.VISIBLE);
- mTabLayout.setVisibility(View.VISIBLE);
+ mFragmentLayout.setVisibility(View.VISIBLE);
mFilterLayout.setVisibility(View.GONE);
mFilterMenuItem.setIcon(R.drawable.ic_sort);
@@ -237,7 +286,6 @@ private void onApplyFilter(DbTasksFilter.Builder builder) {
swapFilterLayout();
}
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_task_list, menu);
@@ -267,12 +315,27 @@ public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_IMPORT && resultCode == RESULT_OK) {
+ mPresenter.importData(data.getData());
+ }
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_filter:
swapFilterLayout();
break;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+ switch (item.getItemId()) {
case R.id.action_export:
startDirectoryChooser();
break;
@@ -285,9 +348,17 @@ public boolean onOptionsItemSelected(MenuItem item) {
case R.id.action_generation:
generateBigData();
break;
+ case R.id.action_sync:
+ syncData();
+ break;
}
- return super.onOptionsItemSelected(item);
+ return false;
+ }
+
+ @Override
+ public void syncData() {
+ sendBroadcast(new Intent(BroadcastSyncManager.SYNC_START_ACTION));
}
private void generateBigData() {
@@ -331,28 +402,48 @@ public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
-
@Override
- public void startEditor(int id) {
- Intent intent = new Intent(this, TaskEditorActivity_.class);
- intent.setAction(ACTION_EDIT);
- intent.putExtra(DbTasksHelper.ID, id);
- startActivityForResult(intent, REQUEST_EDIT);
+ public TaskManagerPresenter getPresenter() {
+ return mPresenter;
}
@Override
- public void onClick(View v) {
- Intent intent = new Intent(this, TaskEditorActivity_.class);
- intent.setAction(ACTION_CREATE);
- startActivityForResult(intent, REQUEST_CREATE);
+ public FilterLayoutWrapper getFilterLayoutWrapper() {
+ return mFilterLayoutWrapper;
}
@Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- mPresenter.onResult(requestCode, resultCode, data);
- }
+ public void startEditor(@Nullable Integer position, CursorProvider adapter, TasksListAdapter.ViewHolder holder) {
+ Bundle bundle = new Bundle();
+ bundle.putSerializable(EDITOR_PAGER_POSITION, position);
+
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ Fragment editorFragment;
+
+ if (position == null) {
+ editorFragment = TaskEditorFragment.newInstance(bundle);
+ } else {
+ editorFragment = EditorPagerFragment.newInstance(bundle, adapter);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && holder != null) {
+ editorFragment.setSharedElementEnterTransition(new CustomTransition());
+ editorFragment.setSharedElementReturnTransition(new CustomTransition());
+ editorFragment.setEnterTransition(new Fade(Fade.IN));
+ editorFragment.setExitTransition(new Fade(Fade.OUT));
+ getSupportFragmentManager().getFragments().get(0)
+ .setEnterTransition(new Fade(Fade.IN));
+ getSupportFragmentManager().getFragments().get(0)
+ .setExitTransition(new Fade(Fade.OUT));
+
+ transaction.addSharedElement(holder.ttl, "timeBlock_" + position);
+ }
+ }
+
+ transaction.replace(R.id.fragment_place, editorFragment)
+ .addToBackStack(null)
+ .commit();
+ }
@UiThread
public void startProgressIndicator(int max) {
@@ -372,8 +463,6 @@ public void stopProgressIndicator() {
@UiThread
public void showProgress(String title, String message) {
- if (mProgressDialog.isShowing()) return;
-
mProgressDialog.setTitle(title);
mProgressDialog.setMessage(message);
mProgressDialog.setCancelable(false);
@@ -383,14 +472,14 @@ public void showProgress(String title, String message) {
@UiThread
public void showProgress() {
- mViewPager.setVisibility(View.GONE);
+ mFragmentLayout.setVisibility(View.INVISIBLE);
mCircleProgressBar.setVisibility(View.VISIBLE);
}
@UiThread
public void hideProgress() {
mCircleProgressBar.setVisibility(View.GONE);
- mViewPager.setVisibility(View.VISIBLE);
+ mFragmentLayout.setVisibility(View.VISIBLE);
if (mProgressDialog.isShowing()) mProgressDialog.dismiss();
}
@@ -399,10 +488,10 @@ public void showAlert(String message) {
Snackbar.make(getWindow().getDecorView(), message, SNACKBAR_SHOW_TIME).show();
}
-
@Override
protected void onDestroy() {
mPresenter.onDestroy();
+ unregisterReceiver(mBroadcastSyncManager);
super.onDestroy();
}
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/OnDataUpdateListener.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/OnDataUpdateListener.java
deleted file mode 100644
index ccf2c4f..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/OnDataUpdateListener.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package ru.urfu.taskmanager.task_manager.models;
-
-public interface OnDataUpdateListener
-{
- void onUpdate(T... data);
-}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/TaskEntry.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/TaskEntry.java
index 5e186be..c4a38d5 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/TaskEntry.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/TaskEntry.java
@@ -3,40 +3,74 @@
import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.ColorInt;
+
+import com.google.gson.annotations.SerializedName;
import java.text.ParseException;
+import ru.urfu.taskmanager.auth.models.User;
import ru.urfu.taskmanager.utils.tools.ISO8601;
+import ru.urfu.taskmanager.utils.tools.JSONFactory;
public class TaskEntry implements Parcelable
{
- private int mId;
- private int mComplete;
+ private transient int mAuthorId = User.getActiveUser().getUserId();
+
+ private transient int mId;
+
+ private transient Integer mOrder = null;
+
+ @SerializedName("id")
+ private Integer mEntryId;
+
+ @SerializedName("extra")
+ private String deviceId;
+
+ @SerializedName("title")
+ private String mTitle;
+
+ @SerializedName("description")
+ private String mDescription;
+
+ @SerializedName("created")
+ private String mCreated;
+
+ @SerializedName("edited")
+ private String mEdited;
+
+ @SerializedName("viewed")
+ private String mTimeToLive;
- private String title;
- private String description;
- private String ttl;
- private String created;
- private String edited;
- private String color;
- private String imageUrl;
+ @SerializedName("imageUrl")
+ private String mImageUrl;
+
+ @SerializedName("color")
+ private String mColor;
public TaskEntry() {
}
public TaskEntry(int id) {
this.mId = id;
+ this.mEntryId = null;
+ this.deviceId = User.getActiveUser().getDeviceIdentifier();
}
- private TaskEntry(Parcel in) {
- title = in.readString();
- description = in.readString();
- ttl = in.readString();
- color = in.readString();
- mComplete = in.readInt();
+ protected TaskEntry(Parcel in) {
+ mId = in.readInt();
+ deviceId = in.readString();
+ mTitle = in.readString();
+ mDescription = in.readString();
+ mCreated = in.readString();
+ mEdited = in.readString();
+ mTimeToLive = in.readString();
+ mImageUrl = in.readString();
+ mColor = in.readString();
}
- public static final Creator CREATOR = new Creator() {
+ public static final Creator CREATOR = new Creator()
+ {
@Override
public TaskEntry createFromParcel(Parcel in) {
return new TaskEntry(in);
@@ -48,6 +82,19 @@ public TaskEntry[] newArray(int size) {
}
};
+ public TaskEntry setDeviceIdentifier(String hash) {
+ this.deviceId = hash;
+ return this;
+ }
+
+ public String getDeviceIdentifier() {
+ return deviceId;
+ }
+
+ public int getAuthorId() {
+ return mAuthorId;
+ }
+
public TaskEntry setId(int id) {
this.mId = id;
return this;
@@ -57,40 +104,49 @@ public int getId() {
return mId;
}
+ public TaskEntry setEntryId(int id) {
+ this.mEntryId = id;
+ return this;
+ }
+
+ public Integer getEntryId() {
+ return mEntryId;
+ }
+
public String getTitle() {
- return title;
+ return mTitle;
}
public TaskEntry setTitle(String title) {
- this.title = title;
+ this.mTitle = title;
return this;
}
public String getDescription() {
- return description;
+ return mDescription;
}
public TaskEntry setDescription(String description) {
- this.description = description;
+ this.mDescription = description;
return this;
}
public TaskEntry setImageUrl(String url) {
- this.imageUrl = url;
+ this.mImageUrl = url;
return this;
}
public String getImageUrl() {
- return imageUrl;
+ return mImageUrl;
}
public String getTtl() {
- return ttl;
+ return mTimeToLive;
}
public long getTtlTimestamp() {
try {
- return ISO8601.toTimestamp(ttl);
+ return ISO8601.toTimestamp(mTimeToLive);
} catch (ParseException e) {
e.printStackTrace();
return Long.MIN_VALUE;
@@ -98,22 +154,22 @@ public long getTtlTimestamp() {
}
public TaskEntry setTtl(long ttl) {
- this.ttl = ISO8601.fromTimestamp(ttl);
+ this.mTimeToLive = ISO8601.fromTimestamp(ttl);
return this;
}
public TaskEntry setCreated(long created) {
- this.created = ISO8601.fromTimestamp(created);
+ this.mCreated = ISO8601.fromTimestamp(created);
return this;
}
public String getCreated() {
- return created;
+ return mCreated;
}
public long getCreatedTimestamp() {
try {
- return ISO8601.toTimestamp(created);
+ return ISO8601.toTimestamp(mCreated);
} catch (Exception e) {
e.printStackTrace();
return Long.MIN_VALUE;
@@ -121,17 +177,17 @@ public long getCreatedTimestamp() {
}
public TaskEntry setEdited(long edited) {
- this.edited = ISO8601.fromTimestamp(edited);
+ this.mEdited = ISO8601.fromTimestamp(edited);
return this;
}
public String getEdited() {
- return edited;
+ return mEdited;
}
public long getEditedTimestamp() {
try {
- return ISO8601.toTimestamp(edited);
+ return ISO8601.toTimestamp(mEdited);
} catch (ParseException e) {
e.printStackTrace();
return Long.MIN_VALUE;
@@ -139,38 +195,33 @@ public long getEditedTimestamp() {
}
public String getColor() {
- return color;
+ return mColor;
}
public int getColorInt() {
- return Color.parseColor(color);
+ return Color.parseColor(mColor);
}
- public TaskEntry setColor(int color) {
- this.color = String.format("#%06X", (0xFFFFFF & color));
+ public TaskEntry setColor(@ColorInt int color) {
+ this.mColor = String.format("#%06X", (0xFFFFFF & color));
return this;
}
public boolean isCompleted() {
- return (mComplete == 1);
- }
-
- public String getCompleted() {
- return String.valueOf(mComplete);
- }
-
- public TaskEntry setCompleted(boolean bool) {
- mComplete = (bool) ? 1 : 0;
- return this;
+ return mTimeToLive.equals(mEdited);
}
@Override
public int hashCode() {
int hash = 5;
- hash = 89 * hash + (title != null ? title.hashCode() : 0);
- hash = 89 * hash + (description != null ? description.hashCode() : 0);
- hash = 89 * hash + color.hashCode();
+ hash = 89 * hash + (mTitle != null ? mTitle.hashCode() : 0);
+ hash = 89 * hash + (mDescription != null ? mDescription.hashCode() : 0);
+ hash = 89 * hash + (mCreated != null ? (int) getCreatedTimestamp() : 0);
+ hash = 89 * hash + (mEdited != null ? (int) getEditedTimestamp() : 0);
+ hash = 89 * hash + (mTimeToLive != null ? (int) getTtlTimestamp() : 0);
+ hash = 89 * hash + (mImageUrl != null ? mImageUrl.hashCode() : 0);
+ hash = 89 * hash + (mColor != null ? mColor.hashCode() : 0);
return hash;
}
@@ -179,30 +230,41 @@ public int hashCode() {
public boolean equals(Object obj) {
try {
TaskEntry other = (TaskEntry) obj;
- return this.mId == other.mId;
+ return this.mEntryId.equals(other.mEntryId);
} catch (ClassCastException e) {
return false;
}
}
+ @Override
+ public String toString() {
+ return JSONFactory.toJson(this, TaskEntry.class);
+ }
+
@Override
public int describeContents() {
- return CONTENTS_FILE_DESCRIPTOR;
+ return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mId);
- dest.writeString(title);
- dest.writeString(description);
- dest.writeString(ttl);
- dest.writeString(color);
- dest.writeInt(mComplete);
+ dest.writeString(deviceId);
+ dest.writeString(mTitle);
+ dest.writeString(mDescription);
+ dest.writeString(mCreated);
+ dest.writeString(mEdited);
+ dest.writeString(mTimeToLive);
+ dest.writeString(mImageUrl);
+ dest.writeString(mColor);
}
- @Override
- public String toString() {
- return "[" + "title: " + title + "; " + "description: " + description + "; " +
- "ttl: " + ttl + "; " + "color: " + color + "]";
+ public Integer getOrder() {
+ return mOrder;
+ }
+
+ public TaskEntry setOrder(int mOrder) {
+ this.mOrder = mOrder;
+ return this;
}
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/TaskEntryCouples.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/TaskEntryCouples.java
new file mode 100644
index 0000000..1634e6a
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/models/TaskEntryCouples.java
@@ -0,0 +1,118 @@
+package ru.urfu.taskmanager.task_manager.models;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class TaskEntryCouples
+ implements Parcelable, Iterable
+{
+ private ArrayList data;
+
+ public TaskEntryCouples() {
+ this.data = new ArrayList<>();
+ }
+
+ protected TaskEntryCouples(Parcel in) {
+ data = in.createTypedArrayList(Couple.CREATOR);
+ }
+
+ public static final Creator CREATOR = new Creator()
+ {
+ @Override
+ public TaskEntryCouples createFromParcel(Parcel in) {
+ return new TaskEntryCouples(in);
+ }
+
+ @Override
+ public TaskEntryCouples[] newArray(int size) {
+ return new TaskEntryCouples[size];
+ }
+ };
+
+ public void put(TaskEntry key, TaskEntry value) {
+ data.add(new Couple(key, value));
+ }
+
+ public Couple remove(int index) {
+ return data.remove(index);
+ }
+
+ public boolean remove(Couple couple) {
+ return data.remove(couple);
+ }
+
+ public boolean isEmpty() {
+ return data.isEmpty();
+ }
+
+ public int size() {
+ return data.size();
+ }
+
+ @Override
+ public Iterator iterator() {
+ return data.iterator();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeTypedList(data);
+ }
+
+
+ public static class Couple implements Parcelable
+ {
+ private TaskEntry key;
+ private TaskEntry value;
+
+ private Couple(TaskEntry key, TaskEntry value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ protected Couple(Parcel in) {
+ key = in.readParcelable(TaskEntry.class.getClassLoader());
+ value = in.readParcelable(TaskEntry.class.getClassLoader());
+ }
+
+ public static final Creator CREATOR = new Creator()
+ {
+ @Override
+ public Couple createFromParcel(Parcel in) {
+ return new Couple(in);
+ }
+
+ @Override
+ public Couple[] newArray(int size) {
+ return new Couple[size];
+ }
+ };
+
+ public TaskEntry getKey() {
+ return key;
+ }
+
+ public TaskEntry getValue() {
+ return value;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(key, flags);
+ dest.writeParcelable(value, flags);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/presenter/TaskEditorPresenterImpl.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/presenter/TaskEditorPresenterImpl.java
deleted file mode 100644
index f6f78b3..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/presenter/TaskEditorPresenterImpl.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package ru.urfu.taskmanager.task_manager.task_editor.presenter;
-
-import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.color_picker.recent.RecentColorsStorage;
-import ru.urfu.taskmanager.task_manager.main.view.TaskManagerActivity;
-import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.task_manager.task_editor.view.TaskEditor;
-import ru.urfu.taskmanager.utils.db.async.DbAsyncExecutor;
-import ru.urfu.taskmanager.utils.db.DbTasks;
-import ru.urfu.taskmanager.utils.db.DbTasksHelper;
-import ru.urfu.taskmanager.utils.db.async.ExecuteControllerAdapter;
-import ru.urfu.taskmanager.utils.interfaces.Callback;
-
-import static android.app.Activity.RESULT_OK;
-
-public class TaskEditorPresenterImpl implements TaskEditorPresenter
-{
- private final int INVALID_ID = -1;
-
- private int mItemId;
-
- private TaskEditor mEditor;
- private TaskValidator mValidator;
- private DbAsyncExecutor dbAsyncExecutor;
- private RecentColorsStorage mRecentColorsStorage;
-
- public TaskEditorPresenterImpl(TaskEditor editor) {
- this.mEditor = editor;
- this.dbAsyncExecutor = DbTasks.getInstance().getAsyncExecutor();
- this.mRecentColorsStorage = RecentColorsStorage.getRepository();
- this.mValidator = new TaskValidator();
- init();
- }
-
- private void init() {
- if (mEditor.getIntent().getAction().equals(TaskManagerActivity.ACTION_EDIT)) {
- mEditor.setToolbarTitle(mEditor.getResources().getString(R.string.editor_edit_title));
- mItemId = mEditor.getIntent().getIntExtra(DbTasksHelper.ID, INVALID_ID);
- if (mItemId != INVALID_ID) {
- dbAsyncExecutor.getEntryById(mItemId,
- new ExecuteControllerAdapter() {
- @Override
- public void onFinish(TaskEntry result) {
- if (!mEditor.isRestored())
- mEditor.initializeEditor(result);
- mEditor.onImageLoad(result.getImageUrl());
- }
- });
- }
- }
- }
-
- @Override
- public void saveState(TaskEntry state) {
- mValidator.validate(state, aVoid -> {
- long timestamp = System.currentTimeMillis();
-
- switch (mEditor.getIntent().getAction()) {
- case TaskManagerActivity.ACTION_CREATE:
- dbAsyncExecutor.insertEntry(
- state.setId(mItemId)
- .setCreated(timestamp)
- .setEdited(timestamp)
- );
- break;
- case TaskManagerActivity.ACTION_EDIT:
- dbAsyncExecutor.updateEntry(
- state.setId(mItemId)
- .setEdited(timestamp)
- );
- break;
- }
-
- mRecentColorsStorage.putItem(state.getColorInt());
- mEditor.exit(RESULT_OK);
- });
- }
-
- private class TaskValidator {
- private static final int TITLE_MAX_LENGTH = 20;
- private static final int DESCRIPTION_MAX_LENGTH = 50;
-
- private boolean isValid = true;
-
- private void validate(TaskEntry entry, Callback callback) {
- isValid = true;
-
- if (entry.getTitle().isEmpty()) {
- isValid = false;
- mEditor.showTitleError(mEditor.getResources().getString(R.string.search_hint));
- }
-
- if (entry.getTitle().length() > TITLE_MAX_LENGTH) {
- isValid = false;
- mEditor.showTitleError(mEditor.getResources().getString(R.string.incorrect_length) + " " + TITLE_MAX_LENGTH);
- }
-
- if (entry.getDescription().isEmpty()) {
- isValid = false;
- mEditor.showDescriptionError(mEditor.getResources().getString(R.string.entry_description));
- }
-
- if (entry.getDescription().length() > DESCRIPTION_MAX_LENGTH) {
- isValid = false;
- mEditor.showTitleError(mEditor.getResources().getString(R.string.incorrect_length) + " " + DESCRIPTION_MAX_LENGTH);
- }
-
- if (isValid) callback.call(null);
- }
- }
-}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/view/TaskEditorActivity.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/view/TaskEditorActivity.java
deleted file mode 100644
index 73ce86d..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/task_manager/task_editor/view/TaskEditorActivity.java
+++ /dev/null
@@ -1,245 +0,0 @@
-package ru.urfu.taskmanager.task_manager.task_editor.view;
-
-import android.graphics.Color;
-import android.os.Bundle;
-import android.os.Vibrator;
-import android.support.design.widget.TextInputLayout;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.CardView;
-import android.support.v7.widget.Toolbar;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import com.github.florent37.singledateandtimepicker.SingleDateAndTimePicker;
-
-import org.androidannotations.annotations.EActivity;
-import org.androidannotations.annotations.InstanceState;
-import org.androidannotations.annotations.UiThread;
-import org.androidannotations.annotations.ViewById;
-
-import java.io.IOException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
-import ru.urfu.taskmanager.R;
-import ru.urfu.taskmanager.color_picker.PickerView;
-import ru.urfu.taskmanager.color_picker.recent.RecentColors;
-import ru.urfu.taskmanager.task_manager.models.TaskEntry;
-import ru.urfu.taskmanager.task_manager.task_editor.presenter.TaskEditorPresenter;
-import ru.urfu.taskmanager.task_manager.task_editor.presenter.TaskEditorPresenterImpl;
-import ru.urfu.taskmanager.task_manager.task_editor.tools.ImageLoader;
-
-@EActivity(R.layout.activity_task_editor)
-public class TaskEditorActivity extends AppCompatActivity implements TaskEditor
-{
- private static final String CACHE_KEY = "color_cache";
- private static final String COLOR_KEY = "current_color";
- private static final String DATE_KEY = "selected_date";
- private static final int CELL_COUNT = 16;
-
- TaskEditorPresenter mPresenter;
-
- @ViewById(R.id.datetime_picker)
- SingleDateAndTimePicker mDateTimePicker;
-
- @ViewById(R.id.title_input_layout)
- TextInputLayout mTitleInputLayout;
-
- @ViewById(R.id.description_input_layout)
- TextInputLayout mDescInputLayout;
-
- @ViewById(R.id.image_view)
- ImageView mImageView;
-
- @ViewById(R.id.pickerView)
- PickerView mPickerView;
-
- @ViewById(R.id.cardColor)
- CardView mCardColorView;
-
- @ViewById(R.id.title_edit_field)
- EditText mTitleEditField;
-
- @ViewById(R.id.descr_edit_field)
- EditText mDescEditField;
-
- @ViewById(R.id.image_url_edit_field)
- EditText mImageUrlEditField;
-
- @ViewById(R.id.save_button)
- Button mButtonSave;
-
- boolean mRestored = false;
-
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- if (savedInstanceState != null) mRestored = true;
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- if (getSupportActionBar() != null) {
- getSupportActionBar().setTitle(getString(R.string.editor_create_title));
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setDisplayShowHomeEnabled(true);
- }
-
- setResult(RESULT_CANCELED);
-
- mDateTimePicker.setMustBeOnFuture(true);
- mButtonSave.setOnClickListener(this);
- mPickerView.setCellCount(CELL_COUNT);
- mPickerView.subscribe(this);
-
- mImageUrlEditField.addTextChangedListener(new TextWatcher()
- {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- //Stub!
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- //Stub!
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- onImageLoad(s.toString());
- }
- });
-
- mCardColorView.setCardBackgroundColor(mPickerView.getCurrentColor());
- mCardColorView.setOnClickListener(v -> RecentColors.showRecent(this, color -> {
- mPickerView.setCurrentColor(color);
- mCardColorView.setCardBackgroundColor(color);
- }));
-
- mPresenter = new TaskEditorPresenterImpl(this);
- }
-
- public boolean isRestored() {
- return mRestored;
- }
-
- @UiThread
- public void initializeEditor(TaskEntry entry) {
- Calendar calendar = new GregorianCalendar();
- calendar.setTimeInMillis(entry.getTtlTimestamp());
-
- mDateTimePicker.selectDate(calendar);
- mDateTimePicker.setSelectorColor(Color.BLACK);
- mTitleEditField.setText(entry.getTitle());
- mDescEditField.setText(entry.getDescription());
- mImageUrlEditField.setText(entry.getImageUrl());
- mPickerView.setCurrentColor(entry.getColorInt());
- mCardColorView.setCardBackgroundColor(mPickerView.getCurrentColor());
- }
-
- @Override
- @UiThread
- public void onImageLoad(String url) {
- ImageLoader.into(mImageView)
- .from(url);
- }
-
- @Override
- public void showTitleError(String string) {
- mTitleInputLayout.setError(string);
- }
-
-
- @Override
- public void showDescriptionError(String string) {
- mDescInputLayout.setError(string);
- }
-
- @Override
- public void onClick(View v) {
- mTitleInputLayout.setErrorEnabled(false);
- mDescInputLayout.setErrorEnabled(false);
-
- mPresenter.saveState(
- new TaskEntry()
- .setTitle(mTitleEditField.getText().toString())
- .setDescription(mDescEditField.getText().toString())
- .setTtl(mDateTimePicker.getDate().getTime())
- .setColor(mPickerView.getCurrentColor())
- .setImageUrl(mImageUrlEditField.getText().toString())
- );
- }
-
- @Override
- public void onColorChanged(int color) {
- mCardColorView.setCardBackgroundColor(color);
- }
-
- @Override
- public void editModeEnable() {
- vibrate();
- }
-
- @Override
- public void editModeDisable() {
- vibrate();
- }
-
- @Override
- public void theBoundaryIsReached() {
- vibrate();
- }
-
- private void vibrate() {
- Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
- vibrator.vibrate(10);
- }
-
- @Override
- public boolean onSupportNavigateUp() {
- onBackPressed();
- return true;
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- mPickerView.getColorCache();
- outState.putSerializable(CACHE_KEY, mPickerView.getColorCache());
- outState.putInt(COLOR_KEY, mPickerView.getCurrentColor());
- outState.putSerializable(DATE_KEY, mDateTimePicker.getDate());
- super.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
- Calendar calendar = Calendar.getInstance();
- calendar.setTime((Date) savedInstanceState.getSerializable(DATE_KEY));
- float[][] cache = (float[][]) savedInstanceState.getSerializable(CACHE_KEY);
- int currentColor = savedInstanceState.getInt(COLOR_KEY);
- mPickerView.setColorCache(cache);
- mPickerView.setCellCount(CELL_COUNT);
- mPickerView.setCurrentColor(currentColor);
- mCardColorView.setCardBackgroundColor(mPickerView.getCurrentColor());
- mDateTimePicker.selectDate(calendar);
- }
-
- @Override
- public void setToolbarTitle(String title) {
- if (getSupportActionBar() != null) {
- getSupportActionBar().setTitle(title);
- }
- }
-
- @Override
- public void exit(int result) {
- setResult(result);
- finish();
- }
-}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/interfaces/Thenable.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/interfaces/Thenable.java
new file mode 100644
index 0000000..e1713c4
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/interfaces/Thenable.java
@@ -0,0 +1,7 @@
+package ru.urfu.taskmanager.utils.interfaces;
+
+public interface Thenable
+{
+ void onSuccess(T... results);
+ void onFailed(Throwable t);
+}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/JSONFactory.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/JSONFactory.java
index f0c13f0..fa02641 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/JSONFactory.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/JSONFactory.java
@@ -4,6 +4,7 @@
import com.google.gson.GsonBuilder;
import java.io.IOException;
+import java.lang.reflect.Type;
public class JSONFactory
{
@@ -17,4 +18,8 @@ public static String toJson(T object, Class _class) {
public static T fromJson(String json, Class _class) throws IOException {
return gson.fromJson(json, _class);
}
+
+ public static T fromJson(String json, Type type) throws IOException {
+ return gson.fromJson(json, type);
+ }
}
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/NetworkUtil.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/NetworkUtil.java
new file mode 100644
index 0000000..b271284
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/NetworkUtil.java
@@ -0,0 +1,20 @@
+package ru.urfu.taskmanager.utils.tools;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+public final class NetworkUtil
+{
+ public static boolean networkIsReachable(Context context) {
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ if (null != activeNetwork) {
+ if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) return true;
+ if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) return true;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/TimeUtils.java b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/TimeUtils.java
index b39bfb8..71982ec 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/TimeUtils.java
+++ b/Task3. TaskManager/TaskManager/app/src/main/java/ru/urfu/taskmanager/utils/tools/TimeUtils.java
@@ -15,7 +15,7 @@ public final class TimeUtils
private static final SimpleDateFormat sFormatter = new SimpleDateFormat("dd.MM.yyyy", sLocale);
public static HoursAndMinutes getHoursAndMinutesFromUnix(long timestamp) {
- Calendar calendar = new GregorianCalendar();
+ Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
HoursAndMinutes time = new HoursAndMinutes();
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/drawable/ripple_task_item.xml b/Task3. TaskManager/TaskManager/app/src/main/res/drawable/ripple_task_item.xml
new file mode 100644
index 0000000..2796800
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/drawable/ripple_task_item.xml
@@ -0,0 +1,10 @@
+
+
+ -
+
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout-land/activity_task_editor.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout-land/activity_task_editor.xml
deleted file mode 100644
index 2ae2f24..0000000
--- a/Task3. TaskManager/TaskManager/app/src/main/res/layout-land/activity_task_editor.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout/active_tasks_fragment.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout/active_tasks_fragment.xml
index 41afff9..597caff 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/layout/active_tasks_fragment.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/layout/active_tasks_fragment.xml
@@ -6,7 +6,7 @@
android:layout_height="match_parent"
tools:context=".task_manager.main.view.TaskManagerActivity">
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_editor.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_editor.xml
index c4b817a..3ebb059 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_editor.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_editor.xml
@@ -1,136 +1,139 @@
-
-
-
-
-
-
-
-
-
-
-
+ android:orientation="vertical"
+ android:clickable="true">
-
-
-
-
+
+
+ android:layout_marginBottom="56dp"
+ android:orientation="vertical">
-
+ android:scrollbars="none"/>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:padding="18dp"
+ android:text="@string/complete"
+ android:textSize="18sp"/>
-
-
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_filter.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_filter.xml
index 01372d2..b04e499 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_filter.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_filter.xml
@@ -1,238 +1,244 @@
-
+ android:layout_height="match_parent"
+ android:visibility="invisible">
-
-
-
-
+ android:layout_height="250dp"
+ android:background="@color/colorPrimaryDark"
+ android:visibility="gone"/>
+
+
+ android:orientation="vertical">
-
+ android:orientation="horizontal"
+ android:padding="16dp">
-
+
-
+
-
+
-
+ android:orientation="horizontal"
+ android:padding="16dp">
-
+
-
+
-
-
-
+
-
+ android:background="@color/half_lite_gray"
+ android:checkedButton="@+id/by_single_date_radio"
+ android:gravity="right"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:visibility="gone">
-
+
-
+
-
+
-
+ android:background="@color/half_lite_gray"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:visibility="gone">
-
+
-
+
-
+
-
+
-
-
-
-
-
+ android:orientation="horizontal"
+ android:padding="16dp">
-
+
+
+
+
+
-
+
-
+ android:orientation="horizontal"
+ android:padding="16dp">
-
+
-
+
-
+
-
+ android:orientation="horizontal"
+ android:padding="16dp">
-
+ android:layout_weight="1"
+ android:text="@string/order_by"/>
-
+ android:layout_weight="1"
+ android:checkedButton="@+id/order_front_radio">
-
+
-
+
-
+
-
+
-
+ android:orientation="horizontal"
+ android:padding="16dp">
+
+
+
+
+
+
-
+
-
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_list.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_list.xml
index edf451b..40eff04 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_list.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/layout/activity_task_list.xml
@@ -1,16 +1,19 @@
-
+
+ android:layout_height="match_parent">
-
+
+
-
+
-
-
-
-
-
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
-
+
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout/main_fragment.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout/main_fragment.xml
new file mode 100644
index 0000000..65ef606
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/layout/main_fragment.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout/sync_conflict_layout.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout/sync_conflict_layout.xml
new file mode 100644
index 0000000..a6c5194
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/layout/sync_conflict_layout.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/layout/task_list_item.xml b/Task3. TaskManager/TaskManager/app/src/main/res/layout/task_list_item.xml
index c5b8fd6..9547a2e 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/layout/task_list_item.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/layout/task_list_item.xml
@@ -1,9 +1,11 @@
-
+
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/menu/menu_task_list.xml b/Task3. TaskManager/TaskManager/app/src/main/res/menu/menu_task_list.xml
index 28f04d0..7b0d527 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/menu/menu_task_list.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/menu/menu_task_list.xml
@@ -30,20 +30,4 @@
app:actionLayout="@layout/toolbar_search_spinner"
app:showAsAction="always"/>
-
-
-
-
-
-
-
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/menu/nav_menu_bar.xml b/Task3. TaskManager/TaskManager/app/src/main/res/menu/nav_menu_bar.xml
new file mode 100644
index 0000000..dc9f577
--- /dev/null
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/menu/nav_menu_bar.xml
@@ -0,0 +1,27 @@
+
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/values/colors.xml b/Task3. TaskManager/TaskManager/app/src/main/res/values/colors.xml
index 7fef674..ef7c1e6 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/values/colors.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/values/colors.xml
@@ -7,6 +7,7 @@
#848484
#FFFFFF
#e9e9e9
+ #f4f4f4
#e2e2e2
#000000
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/values/strings.xml b/Task3. TaskManager/TaskManager/app/src/main/res/values/strings.xml
index 6d374d6..49fb442 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/values/strings.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/values/strings.xml
@@ -31,7 +31,7 @@
Название
Примечание
Готово
- Сортировать по дате
+ Сортировать по
Вывод по дате
по дате
по диапазону
@@ -56,11 +56,18 @@
Сбор данных начался
Собрано данных
Не удалось загрузить изображение
+ Конфликт изменений
+ Нажмите на вариант, который хотите сохранить.
+ Не удалось синхронизировать данные
+ Успешно синхронизировано
+ Синхронизация…
+ Не удалось разрешить конфликт
- - Выполнения
- - Создания
- - Редактирования
+ - Дате выполнения
+ - Дате создания
+ - Дате редактирования
+ - Порядку
diff --git a/Task3. TaskManager/TaskManager/app/src/main/res/values/styles.xml b/Task3. TaskManager/TaskManager/app/src/main/res/values/styles.xml
index 4f9f9c7..ffa5b34 100644
--- a/Task3. TaskManager/TaskManager/app/src/main/res/values/styles.xml
+++ b/Task3. TaskManager/TaskManager/app/src/main/res/values/styles.xml
@@ -1,4 +1,4 @@
-
+
+
+
+
+
+