diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5edb4ee
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..0161652
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,73 @@
+apply plugin: 'com.android.application'
+apply plugin: 'io.fabric'
+
+repositories {
+ maven { url 'https://maven.fabric.io/public' }
+}
+
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "com.khammami.imerolium"
+ minSdkVersion 16
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ vectorDrawables.useSupportLibrary = true
+
+ multiDexEnabled true
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ api project(':colorpicker')
+ implementation 'com.android.support:multidex:1.0.3'
+ implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
+ implementation 'com.android.support:preference-v7:28.0.0-alpha3'
+ implementation 'com.android.support:design:28.0.0-alpha3'
+ implementation 'com.android.support:support-v4:28.0.0-alpha3'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.2'
+
+ implementation 'com.google.android.gms:play-services-auth:15.0.1'
+ implementation 'com.google.firebase:firebase-core:16.0.1'
+ implementation 'com.google.firebase:firebase-auth:16.0.2'
+ implementation 'com.google.firebase:firebase-firestore:17.0.2'
+
+ implementation "android.arch.lifecycle:runtime:1.1.1"
+ implementation "android.arch.lifecycle:extensions:1.1.1"
+ annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
+ implementation "android.arch.persistence.room:runtime:1.1.1"
+ annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
+
+ api('com.google.api-client:google-api-client-android:1.23.0') {
+ exclude group: 'com.google.code.findbugs'
+ exclude group: 'org.apache.httpcomponents'
+ exclude group: 'com.google.guava'
+ }
+ api('com.google.apis:google-api-services-people:v1-rev168-1.23.0') {
+ exclude group: 'com.google.code.findbugs'
+ exclude group: 'org.apache.httpcomponents'
+ exclude group: 'com.google.guava'
+ }
+
+ implementation 'com.squareup.picasso:picasso:2.71828'
+
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+ implementation('com.crashlytics.sdk.android:crashlytics:2.9.4@aar') {
+ transitive = true
+ }
+}
+
+apply plugin: 'com.google.gms.google-services'
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/khammami/imerolium/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/khammami/imerolium/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..48bdc2f
--- /dev/null
+++ b/app/src/androidTest/java/com/khammami/imerolium/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.khammami.imerolium;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.khammami.imerolium", appContext.getPackageName());
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2db7461
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/khammami/imerolium/AppExecutors.java b/app/src/main/java/com/khammami/imerolium/AppExecutors.java
new file mode 100644
index 0000000..6609d47
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/AppExecutors.java
@@ -0,0 +1,56 @@
+package com.khammami.imerolium;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+public class AppExecutors {
+
+ // For Singleton instantiation
+ private static final Object LOCK = new Object();
+ private static AppExecutors sInstance;
+ private final Executor diskIO;
+ private final Executor mainThread;
+ private final Executor networkIO;
+
+ private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
+ this.diskIO = diskIO;
+ this.networkIO = networkIO;
+ this.mainThread = mainThread;
+ }
+
+ public static AppExecutors getInstance() {
+ if (sInstance == null) {
+ synchronized (LOCK) {
+ sInstance = new AppExecutors(Executors.newSingleThreadExecutor(),
+ Executors.newFixedThreadPool(3),
+ new MainThreadExecutor());
+ }
+ }
+ return sInstance;
+ }
+
+ public Executor diskIO() {
+ return diskIO;
+ }
+
+ public Executor mainThread() {
+ return mainThread;
+ }
+
+ public Executor networkIO() {
+ return networkIO;
+ }
+
+ private static class MainThreadExecutor implements Executor {
+ private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
+
+ @Override
+ public void execute(@NonNull Runnable command) {
+ mainThreadHandler.post(command);
+ }
+ }
+}
diff --git a/app/src/main/java/com/khammami/imerolium/BaseActivity.java b/app/src/main/java/com/khammami/imerolium/BaseActivity.java
new file mode 100644
index 0000000..c61a2a0
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/BaseActivity.java
@@ -0,0 +1,40 @@
+package com.khammami.imerolium;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.app.AppCompatActivity;
+
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.auth.FirebaseUser;
+import com.khammami.imerolium.ui.LoginActivity;
+import com.khammami.imerolium.ui.MainActivity;
+
+public class BaseActivity extends AppCompatActivity {
+
+ @VisibleForTesting
+ public FirebaseAuth mAuth;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mAuth = FirebaseAuth.getInstance();
+ checkAuth();
+ }
+
+ public void checkAuth() {
+ FirebaseUser currentUser = mAuth.getCurrentUser();
+ if (!(this instanceof LoginActivity) && currentUser == null) {
+ Intent signInIntent = new Intent(this, LoginActivity.class);
+ startActivity(signInIntent);
+ finish();
+ }else if((this instanceof LoginActivity) && currentUser != null){
+ Intent mainIntent = new Intent(this, MainActivity.class);
+ startActivity(mainIntent);
+ finish();
+ }
+ }
+}
diff --git a/app/src/main/java/com/khammami/imerolium/BasicApplication.java b/app/src/main/java/com/khammami/imerolium/BasicApplication.java
new file mode 100644
index 0000000..b2363c1
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/BasicApplication.java
@@ -0,0 +1,43 @@
+package com.khammami.imerolium;
+
+import android.app.Application;
+import android.support.multidex.MultiDexApplication;
+
+import com.crashlytics.android.Crashlytics;
+import com.google.firebase.firestore.FirebaseFirestore;
+import com.google.firebase.firestore.FirebaseFirestoreSettings;
+import com.khammami.imerolium.data.AppRepository;
+import com.khammami.imerolium.data.db.AppDatabase;
+import com.khammami.imerolium.data.net.AppNetworkDataSource;
+
+import io.fabric.sdk.android.Fabric;
+
+public class BasicApplication extends MultiDexApplication {
+ private AppExecutors mAppExecutors;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ //init fabric
+ final Fabric fabric = new Fabric.Builder(this)
+ .kits(new Crashlytics())
+ .debuggable(true)
+ .build();
+ Fabric.with(fabric);
+
+ mAppExecutors = AppExecutors.getInstance();
+ }
+
+ public AppDatabase getDatabase() {
+ return AppDatabase.getInstance(this);
+ }
+
+ public AppNetworkDataSource getNetworkResouce() {
+ return AppNetworkDataSource.getInstance(this, mAppExecutors);
+ }
+
+ public AppRepository getRepository() {
+ return AppRepository.getInstance(getDatabase(), getNetworkResouce(), mAppExecutors);
+ }
+}
diff --git a/app/src/main/java/com/khammami/imerolium/data/AppPreferences.java b/app/src/main/java/com/khammami/imerolium/data/AppPreferences.java
new file mode 100644
index 0000000..5b451e0
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/data/AppPreferences.java
@@ -0,0 +1,55 @@
+package com.khammami.imerolium.data;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.auth.FirebaseUser;
+import com.khammami.imerolium.R;
+
+public class AppPreferences {
+ private static final String TAG = AppPreferences.class.getSimpleName();
+
+ public static final String AGENDA_VIEW = "agenda";
+ public static final String QUILT_VIEW = "quilt";
+
+ public static void setPostListViewType(Context context, String viewType) {
+ SharedPreferences sp = getUserSharePreferences(context);
+ SharedPreferences.Editor editor = sp.edit();
+
+ editor.putString(context.getString(R.string.pref_post_list_view_type_key), viewType);
+ editor.apply();
+ }
+
+ public static String getPostListViewType(Context context) {
+ SharedPreferences sp = getUserSharePreferences(context);
+ return sp.getString(context.getString(R.string.pref_post_list_view_type_key),
+ QUILT_VIEW);
+ }
+
+ private static SharedPreferences getUserSharePreferences(Context context){
+ String userId = FirebaseAuth.getInstance().getUid();
+ return context.getSharedPreferences(userId, Context.MODE_PRIVATE);
+
+ }
+
+ public static void setUserPhotoCover(Context context, String photoUrl) {
+ SharedPreferences sp = getUserSharePreferences(context);
+ SharedPreferences.Editor editor = sp.edit();
+
+ editor.putString(context.getString(R.string.pref_user_cover_key), photoUrl);
+ editor.apply();
+ }
+
+ public static String getUserPhotoCover(Context context) {
+ SharedPreferences sp = getUserSharePreferences(context);
+ return sp.getString(context.getString(R.string.pref_user_cover_key), "");
+ }
+
+ public static boolean isTimeFormat24(Context context) {
+ SharedPreferences sp = getUserSharePreferences(context);
+ return sp.getBoolean(context.getString(R.string.pref_time_format_24h_key), false);
+ }
+}
diff --git a/app/src/main/java/com/khammami/imerolium/data/AppRepository.java b/app/src/main/java/com/khammami/imerolium/data/AppRepository.java
new file mode 100644
index 0000000..53b2025
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/data/AppRepository.java
@@ -0,0 +1,226 @@
+package com.khammami.imerolium.data;
+
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.MutableLiveData;
+import android.arch.lifecycle.Observer;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import com.google.android.gms.tasks.OnCompleteListener;
+import com.google.android.gms.tasks.OnFailureListener;
+import com.google.android.gms.tasks.Task;
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.firestore.CollectionReference;
+import com.google.firebase.firestore.DocumentReference;
+import com.google.firebase.firestore.FirebaseFirestore;
+import com.google.firebase.firestore.QuerySnapshot;
+import com.google.firebase.firestore.WriteBatch;
+import com.khammami.imerolium.AppExecutors;
+import com.khammami.imerolium.data.db.AppDatabase;
+import com.khammami.imerolium.data.net.AppNetworkDataSource;
+import com.khammami.imerolium.model.Post;
+import com.khammami.imerolium.model.SyncPostTask;
+import com.khammami.imerolium.utilities.AppUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AppRepository {
+ private static final String TAG = AppRepository.class.getSimpleName();
+ private static final String USERS_PATH = "users";
+ private static final String POSTS_PATH = "posts";
+
+ private static final Object LOCK = new Object();
+ private static AppRepository sInstance;
+ private final AppExecutors mExecutors;
+ private final AppDatabase db;
+ private final AppNetworkDataSource networkResource;
+ private final FirebaseFirestore mFirestoreDb;
+
+ private final MutableLiveData> remotePosts = new MutableLiveData<>();
+
+ private AppRepository(AppDatabase database, AppNetworkDataSource networkResource, AppExecutors executors) {
+ this.db = database;
+ this.networkResource = networkResource;
+ this.mExecutors = executors;
+
+ //firestore init
+ this.mFirestoreDb = FirebaseFirestore.getInstance();
+}
+
+ public synchronized static AppRepository getInstance(
+ AppDatabase database, AppNetworkDataSource networkSource, AppExecutors executors) {
+ Log.d(TAG, "Getting the repository");
+ if (sInstance == null) {
+ synchronized (LOCK) {
+ sInstance = new AppRepository(database, networkSource, executors);
+ Log.d(TAG, "Made new repository");
+ }
+ }
+ return sInstance;
+ }
+
+ public LiveData> getUserPosts() {
+ return db.postDao().getUserPostList(getCurrentUserId());
+ }
+
+ public void insertPost(final Post post){
+
+ mExecutors.diskIO().execute(new Runnable() {
+ @Override
+ public void run() {
+ //set post id from firestore
+ String postId = getNewFireStoreId(post);
+ post.setId(postId);
+
+ //local
+ db.postDao().insertPost(post);
+
+ //remote
+ mFirestoreDb.collection(USERS_PATH).document(post.getUserId())
+ .collection(POSTS_PATH).document(postId).set(post)
+ .addOnFailureListener(new OnFailureListener() {
+ @Override
+ public void onFailure(@NonNull Exception e) {
+ e.printStackTrace();
+ db.syncPostDao().insertSyncPostTask(
+ AppUtils.createSyncPostTask(post, SyncPostTask.DELETE_ACTION));
+ }
+ });
+ }
+ });
+ }
+
+ public LiveData getPost(String postId) {
+ return db.postDao().getPost(postId);
+ }
+
+ public void updatePost(final Post post) {
+ mExecutors.diskIO().execute(new Runnable() {
+ @Override
+ public void run() {
+ //local
+ db.postDao().updatePost(post);
+
+ //remote
+ getFirestorePostsPath(post.getUserId()).document(post.getId())
+ .set(post).addOnFailureListener(new OnFailureListener() {
+ @Override
+ public void onFailure(@NonNull Exception e) {
+ e.printStackTrace();
+ db.syncPostDao().insertSyncPostTask(
+ AppUtils.createSyncPostTask(post, SyncPostTask.SET_ACTION));
+ }
+ });
+ }
+ });
+
+ }
+
+ public void deletePost(final Post post) {
+ mExecutors.diskIO().execute(new Runnable() {
+ @Override
+ public void run() {
+ db.postDao().deletePost(post.getId());
+
+ getFirestorePostsPath(post.getUserId()).document(post.getId()).delete()
+ .addOnFailureListener(new OnFailureListener() {
+ @Override
+ public void onFailure(@NonNull Exception e) {
+ e.printStackTrace();
+ db.syncPostDao().insertSyncPostTask(
+ AppUtils.createSyncPostTask(post, SyncPostTask.DELETE_ACTION));
+ }
+ });
+ }
+ });
+
+ }
+
+ public LiveData> fetchPostListFromFirestore(){
+ if (getCurrentUserId() != null) {
+ getFirestorePostsPath(getCurrentUserId()).get()
+ .addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+ if (task.isSuccessful()) {
+ List posts = task.getResult().toObjects(Post.class);
+ remotePosts.postValue(posts);
+ } else {
+ remotePosts.postValue(null);
+ Log.d(TAG, "Error getting documents: ", task.getException());
+ }
+ }
+ });
+ }
+
+ return remotePosts;
+ }
+
+ public void updateLocalPost(final List remotePosts) {
+ mExecutors.diskIO().execute(new Runnable() {
+ @Override
+ public void run() {
+ List localPosts = db.postDao().getPostList(getCurrentUserId());
+ //local db empty & remote db contain data
+ if (remotePosts != null && remotePosts.size() > 0 && localPosts.size() == 0) {
+ db.postDao().insertPosts(remotePosts);
+ }
+
+ //remote db empty & local db contain data
+ if (remotePosts != null && remotePosts.size() == 0 && localPosts.size() > 0) {
+ ceateFirestoreBatchWrite(localPosts).commit();
+ }
+
+ //
+ if(remotePosts != null && remotePosts.size() > 0 && localPosts.size() > 0){
+ //List syncTasks = db.syncPostDao().getSyncPostTasks(getCurrentUserId());
+
+ List rTmp = new ArrayList<>(remotePosts);
+ rTmp.removeAll(localPosts);
+
+ //add and update local posts
+ for (Post p : rTmp){
+ Post tmpPost = db.postDao().getPost(p.getId()).getValue();
+ if (tmpPost == null){
+ db.postDao().insertPost(p);
+ } else if (p.getUpdatedAt().after(tmpPost.getUpdatedAt())){
+ db.postDao().updatePost(p);
+ }
+ }
+
+ //batch posts to firestore & firestore rules will take care of add/update data
+ localPosts.removeAll(remotePosts);
+ ceateFirestoreBatchWrite(localPosts).commit();
+ }
+
+ }
+ });
+ }
+
+ private String getNewFireStoreId(Post post){
+ return mFirestoreDb.collection(USERS_PATH).document(post.getUserId())
+ .collection(POSTS_PATH)
+ .document().getId();
+ }
+
+ private CollectionReference getFirestorePostsPath(String userId){
+ return mFirestoreDb.collection(USERS_PATH).document(userId)
+ .collection(POSTS_PATH);
+ }
+
+ private String getCurrentUserId(){
+ return FirebaseAuth.getInstance().getUid();
+ }
+
+ private WriteBatch ceateFirestoreBatchWrite(List posts){
+ WriteBatch batch = mFirestoreDb.batch();
+ for (Post p: posts){
+ DocumentReference pRef = getFirestorePostsPath(getCurrentUserId())
+ .document(p.getId());
+ batch.set(pRef, p);
+ }
+ return batch;
+ }
+}
diff --git a/app/src/main/java/com/khammami/imerolium/data/db/AppDatabase.java b/app/src/main/java/com/khammami/imerolium/data/db/AppDatabase.java
new file mode 100644
index 0000000..d11e16e
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/data/db/AppDatabase.java
@@ -0,0 +1,42 @@
+package com.khammami.imerolium.data.db;
+
+import android.arch.persistence.room.Database;
+import android.arch.persistence.room.Room;
+import android.arch.persistence.room.RoomDatabase;
+import android.arch.persistence.room.TypeConverters;
+import android.content.Context;
+import android.util.Log;
+
+import com.khammami.imerolium.model.Label;
+import com.khammami.imerolium.model.Post;
+import com.khammami.imerolium.model.SyncPostTask;
+
+@Database(entities = {Post.class, Label.class, SyncPostTask.class}, version = 1, exportSchema = false)
+@TypeConverters(DateConverter.class)
+public abstract class AppDatabase extends RoomDatabase {
+
+ private static final String LOG_TAG = AppDatabase.class.getSimpleName();
+ private static final String DATABASE_NAME = "journal_app";
+
+ // For Singleton instantiation
+ private static final Object LOCK = new Object();
+ private static AppDatabase sInstance;
+
+ public static AppDatabase getInstance(Context context) {
+ Log.d(LOG_TAG, "Getting the database");
+ if (sInstance == null) {
+ synchronized (LOCK) {
+ sInstance = Room.databaseBuilder(context.getApplicationContext(),
+ AppDatabase.class, AppDatabase.DATABASE_NAME).build();
+ Log.d(LOG_TAG, "Made new database");
+ }
+ }
+ return sInstance;
+ }
+
+ public abstract PostDao postDao();
+
+ public abstract LabelDao labelDao();
+
+ public abstract SyncPostTaskDao syncPostDao();
+}
diff --git a/app/src/main/java/com/khammami/imerolium/data/db/DateConverter.java b/app/src/main/java/com/khammami/imerolium/data/db/DateConverter.java
new file mode 100644
index 0000000..411e7ea
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/data/db/DateConverter.java
@@ -0,0 +1,17 @@
+package com.khammami.imerolium.data.db;
+
+import android.arch.persistence.room.TypeConverter;
+
+import java.util.Date;
+
+public class DateConverter {
+ @TypeConverter
+ public static Date toDate(Long timestamp) {
+ return timestamp == null ? null : new Date(timestamp);
+ }
+
+ @TypeConverter
+ public static Long toTimestamp(Date date) {
+ return date == null ? null : date.getTime();
+ }
+}
diff --git a/app/src/main/java/com/khammami/imerolium/data/db/LabelDao.java b/app/src/main/java/com/khammami/imerolium/data/db/LabelDao.java
new file mode 100644
index 0000000..047e4a1
--- /dev/null
+++ b/app/src/main/java/com/khammami/imerolium/data/db/LabelDao.java
@@ -0,0 +1,30 @@
+package com.khammami.imerolium.data.db;
+
+import android.arch.lifecycle.LiveData;
+import android.arch.persistence.room.Dao;
+import android.arch.persistence.room.Insert;
+import android.arch.persistence.room.OnConflictStrategy;
+import android.arch.persistence.room.Query;
+import android.arch.persistence.room.Update;
+
+import com.khammami.imerolium.model.Label;
+
+import java.util.List;
+
+@Dao
+public interface LabelDao {
+ @Query("SELECT * FROM labels WHERE userId = :userId")
+ LiveData> getUserLabelList(String userId);
+
+ @Query("SELECT * FROM labels WHERE id = :labelId")
+ LiveData