diff --git a/.gitignore b/.gitignore
index 932b8c2..bfbd8c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,5 +13,4 @@
.externalNativeBuild
.cxx
local.properties
-/.idea/
-/gradle/
+/.idea/
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..83956dc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# SnipMeApp
+Simple application that allows to save and share code snippets in different languages.
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
deleted file mode 100644
index edd4b8c..0000000
--- a/app/build.gradle
+++ /dev/null
@@ -1,147 +0,0 @@
-plugins {
- id 'com.android.application'
- id 'kotlin-android'
- id 'kotlin-kapt'
- id 'kotlin-android-extensions'
- id 'androidx.navigation.safeargs.kotlin'
- id 'com.google.gms.google-services'
-}
-
-def STRING = "String"
-
-android {
- signingConfigs {
- release {
- // NOTE: Create your own keystore.properties file
- def propsFile = rootProject.file('keystore.properties')
- if (propsFile.exists()) {
- def props = new Properties()
- props.load(new FileInputStream(propsFile))
- storeFile = file('../snipplog_keystore.jks')
- storePassword = props['storePassword']
- keyAlias = props['keyAlias']
- keyPassword = props['keyPassword']
- }
- }
- }
-
- compileSdk 33
-
- defaultConfig {
- applicationId "pl.tkadziolka.snipmeandroid"
- minSdk 21
- targetSdk 33
- versionCode 1
- versionName "1.0"
-
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- }
-
- buildTypes {
- def BASE_URL = "BASE_URL"
- def CONTACT_US_PAGE = "CONTACT_US_PAGE"
- def FACEBOOK_PAGE = "FACEBOOK_PAGE"
- def INSTAGRAM_PAGE = "INSTAGRAM_PAGE"
- def GITHUB_PAGE = "GITHUB_PAGE"
- def TWITTER_PAGE = "TWITTER_PAGE"
-
- def PAYPAL_PAGE = "PAYPAL_PAGE"
- def CARD_PAGE = "CARD_PAGE"
-
- def API_BASE_URL = "\"http://91.195.93.3:8000/snip-api/\"" // Must end with '/'
- def FACEBOOK_URL = "\"https://www.facebook.com/SnippLog-100576858857140\""
- def INSTAGRAM_URL = "\"https://www.instagram.com/snipp.log\""
- def GITHUB_URL = "\"https://github.com/SnippLog\""
- def TWITTER_URL = "\"https://twitter.com/SnippLog\""
-
- def PAYPAL_PAY_URL = "\"https://www.paypal.com/donate?hosted_button_id=WZQNYKQFAHAJG\""
- def CARD_PAY_URL = "\"https://www.paypal.com/biz/fund?id=ACCDJCH2JAHDG\""
-
- debug {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
-
- buildConfigField STRING, BASE_URL, API_BASE_URL
- buildConfigField STRING, CONTACT_US_PAGE, FACEBOOK_URL
- buildConfigField STRING, FACEBOOK_PAGE, FACEBOOK_URL
- buildConfigField STRING, INSTAGRAM_PAGE, INSTAGRAM_URL
- buildConfigField STRING, GITHUB_PAGE, GITHUB_URL
- buildConfigField STRING, TWITTER_PAGE, TWITTER_URL
- buildConfigField STRING, PAYPAL_PAGE, PAYPAL_PAY_URL
- buildConfigField STRING, CARD_PAGE, CARD_PAY_URL
- }
-
- release {
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
-
- buildConfigField STRING, BASE_URL, API_BASE_URL
- buildConfigField STRING, CONTACT_US_PAGE, FACEBOOK_URL
- buildConfigField STRING, FACEBOOK_PAGE, FACEBOOK_URL
- buildConfigField STRING, INSTAGRAM_PAGE, INSTAGRAM_URL
- buildConfigField STRING, GITHUB_PAGE, GITHUB_URL
- buildConfigField STRING, TWITTER_PAGE, TWITTER_URL
- buildConfigField STRING, PAYPAL_PAGE, PAYPAL_PAY_URL
- buildConfigField STRING, CARD_PAGE, CARD_PAY_URL
- signingConfig signingConfigs.release
- }
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
- }
- kotlinOptions {
- jvmTarget = "11"
- }
- lintOptions {
- abortOnError false
- }
-}
-
-dependencies {
- implementation project(':flutter')
- // Kotlin
- implementation "org.jetbrains.kotlin:kotlin-stdlib:1.6.10"
- // KTX
- implementation 'androidx.core:core-ktx:1.7.0'
- implementation "androidx.fragment:fragment-ktx:1.4.1"
- implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
- implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
- implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
- implementation "androidx.navigation:navigation-runtime-ktx:$navigation_version"
- implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
- implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
- implementation 'com.google.firebase:firebase-analytics-ktx'
- // Firebase
- implementation platform('com.google.firebase:firebase-bom:28.2.0')
- // RX
- implementation "io.reactivex.rxjava2:rxkotlin:2.4.0"
- implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
- // DI
- implementation "io.insert-koin:koin-android:$koin_version"
- // Network
- implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
- implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
- kapt("com.squareup.moshi:moshi-kotlin-codegen:$moshi_version")
- implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofit_version"
- implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
- implementation "com.squareup.okhttp3:logging-interceptor:4.9.0"
- // Design
- implementation 'androidx.appcompat:appcompat:1.4.1'
- implementation 'com.google.android.material:material:1.5.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
- implementation "androidx.recyclerview:recyclerview:1.2.1"
- implementation 'androidx.annotation:annotation:1.3.0'
- // Utils
- implementation 'com.jakewharton.timber:timber:4.7.1'
- implementation 'com.github.pwittchen:reactivenetwork-rx2:3.0.8'
- implementation "com.github.bumptech.glide:glide:$glide_version"
- kapt "com.github.bumptech.glide:compiler:$glide_version"
- // View
- implementation 'com.github.SnippLog:CodeView-Android:1.3.4'
- // Test
- testImplementation 'junit:junit:4.13.1'
- androidTestImplementation 'androidx.test.ext:junit:1.1.3'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
- testImplementation "io.mockk:mockk:1.10.6"
-}
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000..753034d
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,142 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.kotlin.compose)
+ id("com.google.devtools.ksp")
+}
+
+android {
+ namespace = "dev.snipme.snipmeapp"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "dev.snipme.snipmeapp"
+ minSdk = 31
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+
+ ndk {
+ // Filter for architectures supported by Flutter
+ abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86_64")
+ }
+ }
+
+ buildFeatures{
+ android.buildFeatures.buildConfig=true
+ }
+
+ buildTypes {
+ val BASE_URL = "BASE_URL"
+ val API_BASE_URL = "\"http://91.195.93.3:8000/snip-api/\"" // Must end with '/'
+ val STRING = "String"
+
+ debug {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+
+ buildConfigField(STRING, BASE_URL, API_BASE_URL)
+ }
+
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ buildConfigField(STRING, BASE_URL, API_BASE_URL)
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+
+ buildFeatures {
+ compose = true
+ }
+}
+
+dependencies {
+ implementation(project(":flutter"))
+ // Kotlin
+ implementation(libs.kotlin.stdlib)
+ // AndroidX Libraries
+ implementation(libs.androidx.fragment.ktx)
+ implementation(libs.androidx.lifecycle.livedata.ktx)
+ implementation(libs.androidx.lifecycle.viewmodel.ktx)
+ implementation(libs.androidx.lifecycle.reactivestreams.ktx)
+ implementation(libs.androidx.navigation.runtime.ktx)
+ implementation(libs.androidx.navigation.fragment.ktx)
+ implementation(libs.androidx.navigation.ui.ktx)
+ implementation(libs.firebase.analytics.ktx)
+ implementation(platform(libs.firebase.bom))
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.recyclerview)
+ implementation(libs.androidx.annotation)
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.activity.compose)
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.ui)
+ implementation(libs.androidx.ui.graphics)
+ implementation(libs.androidx.ui.tooling.preview)
+ implementation(libs.androidx.material3)
+
+ // RX Libraries
+ implementation(libs.rxkotlin)
+ implementation(libs.rxandroid)
+
+ // Dependency Injection
+ implementation(platform(libs.koin.bom))
+ implementation(libs.koin.core)
+ implementation(libs.koin.android)
+
+ // Network Libraries
+ implementation(libs.retrofit)
+ ksp(libs.moshi.kotlin.codegen)
+ implementation(libs.moshi.kotlin)
+ implementation(libs.adapter.rxjava2)
+ implementation(libs.converter.moshi)
+ implementation(libs.logging.interceptor)
+ implementation(libs.reactivenetwork.rx2)
+
+ //Local Storage
+ implementation(libs.androidx.room.runtime)
+ annotationProcessor(libs.androidx.room.compiler)
+ ksp(libs.androidx.room.compiler)
+ implementation(libs.androidx.room.rxjava2)
+
+
+ // Utility Libraries
+ implementation(libs.timber)
+ implementation(libs.glide)
+ ksp(libs.compiler)
+
+ //implementation(libs.codeview)
+ implementation(libs.kodeview)
+
+ // Testing Libraries
+ testImplementation(libs.mockk)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(platform(libs.androidx.compose.bom))
+ androidTestImplementation(libs.androidx.ui.test.junit4)
+
+ // Debugging Tools
+ debugImplementation(libs.androidx.ui.tooling)
+ debugImplementation(libs.androidx.ui.test.manifest)
+}
diff --git a/app/google-services.json b/app/google-services.json
deleted file mode 100644
index 914f772..0000000
--- a/app/google-services.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "project_info": {
- "project_number": "556285392569",
- "project_id": "snipme-19906",
- "storage_bucket": "snipme-19906.appspot.com"
- },
- "client": [
- {
- "client_info": {
- "mobilesdk_app_id": "1:556285392569:android:16830cff6f8e77a2c98d68",
- "android_client_info": {
- "package_name": "pl.tkadziolka.snipmeandroid"
- }
- },
- "oauth_client": [
- {
- "client_id": "556285392569-n0m94vrthamlji0tjt08frdrc5aln43t.apps.googleusercontent.com",
- "client_type": 3
- }
- ],
- "api_key": [
- {
- "current_key": "AIzaSyCPlKkKC9iOYPHVV4kcJpr3gIGRnLpu0O4"
- }
- ],
- "services": {
- "appinvite_service": {
- "other_platform_oauth_client": [
- {
- "client_id": "556285392569-n0m94vrthamlji0tjt08frdrc5aln43t.apps.googleusercontent.com",
- "client_type": 3
- }
- ]
- }
- }
- }
- ],
- "configuration_version": "1"
-}
\ No newline at end of file
diff --git a/app/src/androidTest/java/pl/tkadziolka/snipmeandroid/ExampleInstrumentedTest.kt b/app/src/androidTest/java/dev/snipme/snipmeapp/ExampleInstrumentedTest.kt
similarity index 83%
rename from app/src/androidTest/java/pl/tkadziolka/snipmeandroid/ExampleInstrumentedTest.kt
rename to app/src/androidTest/java/dev/snipme/snipmeapp/ExampleInstrumentedTest.kt
index f39dac5..491986e 100644
--- a/app/src/androidTest/java/pl/tkadziolka/snipmeandroid/ExampleInstrumentedTest.kt
+++ b/app/src/androidTest/java/dev/snipme/snipmeapp/ExampleInstrumentedTest.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid
+package dev.snipme.snipmeapp
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -19,6 +19,6 @@ class ExampleInstrumentedTest {
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("pl.tkadziolka.snipmeandroid", appContext.packageName)
+ assertEquals("dev.snipme.snipmeapp", appContext.packageName)
}
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dd14f53..58b4508 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,42 +1,41 @@
-
+
-
+ android:supportsRtl="true">
+ android:name=".MainActivity"
+ android:exported="true"
+ android:theme="@style/Theme.AppCompat.Light.NoActionBar">
-
+ android:theme="@style/Theme.AppCompat.Light.NoActionBar"
+ android:windowSoftInputMode="adjustResize" />
+
+
+
+
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/assets/app_database.db b/app/src/main/assets/app_database.db
new file mode 100644
index 0000000..c233e45
Binary files /dev/null and b/app/src/main/assets/app_database.db differ
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/App.kt b/app/src/main/java/dev/snipme/snipmeapp/App.kt
similarity index 72%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/App.kt
rename to app/src/main/java/dev/snipme/snipmeapp/App.kt
index a4a4773..76e714a 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/App.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/App.kt
@@ -1,12 +1,12 @@
-package pl.tkadziolka.snipmeandroid
+package dev.snipme.snipmeapp
import android.app.Application
-import io.github.kbiakov.codeview.classifier.CodeProcessor
+import dev.snipme.snipmeapp.BuildConfig.*
+import dev.snipme.snipmeapp.di.koinModules
+import dev.snipme.snipmeapp.util.CrashReportingTree
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
-import pl.tkadziolka.snipmeandroid.di.koinModules
-import pl.tkadziolka.snipmeandroid.util.CrashReportingTree
import timber.log.Timber
class App : Application() {
@@ -18,7 +18,7 @@ class App : Application() {
}
initLogs()
// train classifier on app start
- CodeProcessor.init(this)
+// CodeProcessor.init(this)
startKoin {
androidLogger()
androidContext(this@App)
@@ -27,7 +27,7 @@ class App : Application() {
}
private fun initLogs() {
- if (BuildConfig.DEBUG) {
+ if (DEBUG) {
Timber.plant(Timber.DebugTree())
} else {
Timber.plant(CrashReportingTree())
diff --git a/app/src/main/java/dev/snipme/snipmeapp/AppService.kt b/app/src/main/java/dev/snipme/snipmeapp/AppService.kt
new file mode 100644
index 0000000..4d1aa21
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/AppService.kt
@@ -0,0 +1,107 @@
+package dev.snipme.snipmeapp
+
+import android.content.ClipData
+import android.content.ContentValues
+import android.content.Context
+import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
+import android.net.Uri
+import android.os.Environment
+import android.provider.MediaStore
+import androidx.core.content.ContextCompat.startActivity
+import androidx.core.content.FileProvider
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import java.io.File
+import java.io.FileNotFoundException
+import java.text.DateFormat
+import java.util.Date
+
+const val imageMime = "image/png"
+
+class AppService(private val context: Context) {
+ private var imageUri: Uri? = null
+
+ fun getCurrentDateFormatted(): String {
+ return DateFormat.getDateInstance().format(Date())
+ }
+
+ fun storeFile(image: ByteArray, fileName: String, temp: Boolean = false) {
+ val directoryFile = if (temp) context.cacheDir else context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES
+ )
+
+ if (directoryFile == null) throw IllegalStateException("Storage not available")
+ if (!directoryFile.exists()) {
+ directoryFile.mkdirs()
+ }
+
+ val imageFile = File(directoryFile, fileName)
+ val imageUri = FileProvider.getUriForFile(
+ context,
+ "dev.snipme.snipmeapp.fileprovider",
+ imageFile,
+ )
+
+ context.grantUriPermission(
+ "dev.snipme.snipmeapp.fileprovider",
+ imageUri,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
+ )
+
+ imageFile.writeBytes(image)
+ this.imageUri = imageUri
+ }
+
+ fun launchShareIntent(snippet: Snippet) {
+ if (imageUri == null)
+ throw IllegalStateException("Image path is not set. Store image first!")
+
+ val uri = imageUri!! // Store temporary to avoid var change
+ val sendIntent: Intent = Intent().apply {
+ action = Intent.ACTION_SEND
+ type = imageMime
+ clipData = ClipData.newRawUri(snippet.title, uri)
+ setDataAndType(uri, context.contentResolver.getType(uri));
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ putExtra(Intent.EXTRA_TITLE, snippet.title)
+ putExtra(Intent.EXTRA_STREAM, uri)
+ }
+
+ val shareIntent = Intent.createChooser(sendIntent, null)
+ shareIntent.addFlags(FLAG_ACTIVITY_NEW_TASK)
+ startActivity(context, shareIntent, null)
+ }
+
+ fun storeMediaFile(image: ByteArray, name: String) {
+ val directory = "Pictures/SnipMeApp"
+ val contentValues = ContentValues().apply {
+ put(MediaStore.Images.Media.DISPLAY_NAME, name)
+ put(MediaStore.Images.Media.RELATIVE_PATH, directory)
+ put(MediaStore.Images.Media.MIME_TYPE, imageMime)
+ }
+
+ val resolver = context.contentResolver
+ val existingUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon()
+ .appendQueryParameter(MediaStore.Images.Media.DISPLAY_NAME, name)
+ .appendQueryParameter(MediaStore.Images.Media.RELATIVE_PATH, directory)
+ .build()
+
+ val cursor =
+ resolver.query(existingUri, arrayOf(MediaStore.Images.Media._ID), null, null, null)
+ val uri: Uri? = if (cursor != null && cursor.moveToFirst()) {
+ val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
+ Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id.toString())
+ } else {
+ resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
+ }
+ cursor?.close()
+
+ if (uri != null) {
+ resolver.openOutputStream(uri)?.use { outputStream ->
+ outputStream.write(image)
+ }
+ } else {
+ throw FileNotFoundException("Failed to create or update MediaStore record.")
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/MainActivity.kt b/app/src/main/java/dev/snipme/snipmeapp/MainActivity.kt
new file mode 100644
index 0000000..b74f45a
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/MainActivity.kt
@@ -0,0 +1,45 @@
+package dev.snipme.snipmeapp
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import dev.snipme.snipmeapp.channel.EventStreamHandlerPlugin
+import dev.snipme.snipmeapp.channel.StateStreamHandlerPlugin
+import dev.snipme.snipmeapp.channel.details.DetailsModelPlugin
+import dev.snipme.snipmeapp.channel.login.LoginModelPlugin
+import dev.snipme.snipmeapp.channel.main.MainModelPlugin
+import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.embedding.engine.FlutterEngineCache
+import io.flutter.embedding.engine.dart.DartExecutor
+
+class MainActivity : AppCompatActivity() {
+ // TODO Improve flutter enginge management or remove
+ private lateinit var flutterEngine: FlutterEngine
+
+ private val cachedEngineId = "ID_CACHED_FLUTTER_ENGINE"
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ FlutterEngine(this).apply {
+ dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
+
+ plugins.add(
+ setOf(
+ StateStreamHandlerPlugin(),
+ EventStreamHandlerPlugin(),
+ LoginModelPlugin(),
+ MainModelPlugin(),
+ DetailsModelPlugin()
+ )
+ )
+ FlutterEngineCache.getInstance().put(cachedEngineId, this)
+
+ startActivity(
+ FlutterActivity.withCachedEngine(cachedEngineId)
+ .build(baseContext)
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/DataModel.g.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/DataModel.g.kt
new file mode 100644
index 0000000..1003358
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/DataModel.g.kt
@@ -0,0 +1,1055 @@
+// Autogenerated from Pigeon (v24.2.0), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
+
+package dev.snipme.snipmeapp.channel
+
+import android.util.Log
+import io.flutter.plugin.common.BasicMessageChannel
+import io.flutter.plugin.common.BinaryMessenger
+import io.flutter.plugin.common.EventChannel
+import io.flutter.plugin.common.MessageCodec
+import io.flutter.plugin.common.StandardMethodCodec
+import io.flutter.plugin.common.StandardMessageCodec
+import java.io.ByteArrayOutputStream
+import java.nio.ByteBuffer
+
+private fun wrapResult(result: Any?): List {
+ return listOf(result)
+}
+
+private fun wrapError(exception: Throwable): List {
+ return if (exception is FlutterError) {
+ listOf(
+ exception.code,
+ exception.message,
+ exception.details
+ )
+ } else {
+ listOf(
+ exception.javaClass.simpleName,
+ exception.toString(),
+ "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
+ )
+ }
+}
+
+/**
+ * Error class for passing custom error details to Flutter via a thrown PlatformException.
+ * @property code The error code.
+ * @property message The error message.
+ * @property details The error details. Must be a datatype supported by the api codec.
+ */
+class FlutterError (
+ val code: String,
+ override val message: String? = null,
+ val details: Any? = null
+) : Throwable()
+
+enum class SnippetLanguageType(val raw: Int) {
+ C(0),
+ CPP(1),
+ OBJECTIVE_C(2),
+ C_SHARP(3),
+ JAVA(4),
+ BASH(5),
+ PYTHON(6),
+ PERL(7),
+ RUBY(8),
+ SWIFT(9),
+ JAVASCRIPT(10),
+ KOTLIN(11),
+ COFFEESCRIPT(12),
+ RUST(13),
+ BASIC(14),
+ CLOJURE(15),
+ CSS(16),
+ DART(17),
+ ERLANG(18),
+ GO(19),
+ HASKELL(20),
+ LISP(21),
+ LLVM(22),
+ LUA(23),
+ MATLAB(24),
+ ML(25),
+ MUMPS(26),
+ NEMERLE(27),
+ PASCAL(28),
+ R(29),
+ RD(30),
+ SCALA(31),
+ SQL(32),
+ TEX(33),
+ VB(34),
+ VHDL(35),
+ TCL(36),
+ XQUERY(37),
+ YAML(38),
+ MARKDOWN(39),
+ JSON(40),
+ XML(41),
+ PROTO(42),
+ REGEX(43),
+ UNKNOWN(44);
+
+ companion object {
+ fun ofRaw(raw: Int): SnippetLanguageType? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class SnippetFilterType(val raw: Int) {
+ ALL(0),
+ MINE(1),
+ SHARED(2);
+
+ companion object {
+ fun ofRaw(raw: Int): SnippetFilterType? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class UserReaction(val raw: Int) {
+ NONE(0),
+ LIKE(1),
+ DISLIKE(2);
+
+ companion object {
+ fun ofRaw(raw: Int): UserReaction? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class ModelState(val raw: Int) {
+ LOADING(0),
+ LOADED(1),
+ ERROR(2);
+
+ companion object {
+ fun ofRaw(raw: Int): ModelState? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class MainModelEvent(val raw: Int) {
+ NONE(0),
+ ALERT(1),
+ LOGOUT(2);
+
+ companion object {
+ fun ofRaw(raw: Int): MainModelEvent? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class DetailsModelEvent(val raw: Int) {
+ NONE(0),
+ ALERT(1),
+ DELETED(2);
+
+ companion object {
+ fun ofRaw(raw: Int): DetailsModelEvent? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class LoginModelEvent(val raw: Int) {
+ NONE(0),
+ LOGGED(1);
+
+ companion object {
+ fun ofRaw(raw: Int): LoginModelEvent? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class Snippet (
+ val uuid: String? = null,
+ val title: String? = null,
+ val code: SnippetCode? = null,
+ val language: SnippetLanguage? = null,
+ val owner: Owner? = null,
+ val isOwner: Boolean? = null,
+ val timeAgo: String? = null,
+ val voteResult: Long? = null,
+ val userReaction: UserReaction? = null,
+ val isPrivate: Boolean? = null,
+ val isLiked: Boolean? = null,
+ val isDisliked: Boolean? = null,
+ val isSaved: Boolean? = null,
+ val isToDelete: Boolean? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): Snippet {
+ val uuid = pigeonVar_list[0] as String?
+ val title = pigeonVar_list[1] as String?
+ val code = pigeonVar_list[2] as SnippetCode?
+ val language = pigeonVar_list[3] as SnippetLanguage?
+ val owner = pigeonVar_list[4] as Owner?
+ val isOwner = pigeonVar_list[5] as Boolean?
+ val timeAgo = pigeonVar_list[6] as String?
+ val voteResult = pigeonVar_list[7] as Long?
+ val userReaction = pigeonVar_list[8] as UserReaction?
+ val isPrivate = pigeonVar_list[9] as Boolean?
+ val isLiked = pigeonVar_list[10] as Boolean?
+ val isDisliked = pigeonVar_list[11] as Boolean?
+ val isSaved = pigeonVar_list[12] as Boolean?
+ val isToDelete = pigeonVar_list[13] as Boolean?
+ return Snippet(uuid, title, code, language, owner, isOwner, timeAgo, voteResult, userReaction, isPrivate, isLiked, isDisliked, isSaved, isToDelete)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ uuid,
+ title,
+ code,
+ language,
+ owner,
+ isOwner,
+ timeAgo,
+ voteResult,
+ userReaction,
+ isPrivate,
+ isLiked,
+ isDisliked,
+ isSaved,
+ isToDelete,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class SnippetCode (
+ val raw: String? = null,
+ val tokens: List? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): SnippetCode {
+ val raw = pigeonVar_list[0] as String?
+ val tokens = pigeonVar_list[1] as List?
+ return SnippetCode(raw, tokens)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ raw,
+ tokens,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class SyntaxToken (
+ val start: Long? = null,
+ val end: Long? = null,
+ val color: Long? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): SyntaxToken {
+ val start = pigeonVar_list[0] as Long?
+ val end = pigeonVar_list[1] as Long?
+ val color = pigeonVar_list[2] as Long?
+ return SyntaxToken(start, end, color)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ start,
+ end,
+ color,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class SnippetLanguage (
+ val raw: String? = null,
+ val type: SnippetLanguageType? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): SnippetLanguage {
+ val raw = pigeonVar_list[0] as String?
+ val type = pigeonVar_list[1] as SnippetLanguageType?
+ return SnippetLanguage(raw, type)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ raw,
+ type,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class Owner (
+ val id: Long? = null,
+ val login: String? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): Owner {
+ val id = pigeonVar_list[0] as Long?
+ val login = pigeonVar_list[1] as String?
+ return Owner(id, login)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ id,
+ login,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class SnippetFilter (
+ val languages: List? = null,
+ val selectedLanguages: List? = null,
+ val scopes: List? = null,
+ val selectedScope: String? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): SnippetFilter {
+ val languages = pigeonVar_list[0] as List?
+ val selectedLanguages = pigeonVar_list[1] as List?
+ val scopes = pigeonVar_list[2] as List?
+ val selectedScope = pigeonVar_list[3] as String?
+ return SnippetFilter(languages, selectedLanguages, scopes, selectedScope)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ languages,
+ selectedLanguages,
+ scopes,
+ selectedScope,
+ )
+ }
+}
+
+/**
+ * Generated class from Pigeon that represents data sent in messages.
+ * This class should not be extended by any user class outside of the generated file.
+ */
+sealed class ModelStateData
+/**
+ * Generated class from Pigeon that represents data sent in messages.
+ * This class should not be extended by any user class outside of the generated file.
+ */
+sealed class ModelEventData
+/** Generated class from Pigeon that represents data sent in messages. */
+data class MainModelStateData (
+ val state: ModelState? = null,
+ val isLoading: Boolean? = null,
+ val data: List? = null,
+ val filter: SnippetFilter? = null,
+ val error: String? = null
+) : ModelStateData()
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): MainModelStateData {
+ val state = pigeonVar_list[0] as ModelState?
+ val isLoading = pigeonVar_list[1] as Boolean?
+ val data = pigeonVar_list[2] as List?
+ val filter = pigeonVar_list[3] as SnippetFilter?
+ val error = pigeonVar_list[4] as String?
+ return MainModelStateData(state, isLoading, data, filter, error)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ state,
+ isLoading,
+ data,
+ filter,
+ error,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class MainModelEventData (
+ val event: MainModelEvent? = null,
+ val message: String? = null
+) : ModelEventData()
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): MainModelEventData {
+ val event = pigeonVar_list[0] as MainModelEvent?
+ val message = pigeonVar_list[1] as String?
+ return MainModelEventData(event, message)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ event,
+ message,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class DetailsModelStateData (
+ val state: ModelState? = null,
+ val isLoading: Boolean? = null,
+ val data: Snippet? = null,
+ val error: String? = null
+) : ModelStateData()
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): DetailsModelStateData {
+ val state = pigeonVar_list[0] as ModelState?
+ val isLoading = pigeonVar_list[1] as Boolean?
+ val data = pigeonVar_list[2] as Snippet?
+ val error = pigeonVar_list[3] as String?
+ return DetailsModelStateData(state, isLoading, data, error)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ state,
+ isLoading,
+ data,
+ error,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class DetailsModelEventData (
+ val event: DetailsModelEvent? = null,
+ val value: String? = null
+) : ModelEventData()
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): DetailsModelEventData {
+ val event = pigeonVar_list[0] as DetailsModelEvent?
+ val value = pigeonVar_list[1] as String?
+ return DetailsModelEventData(event, value)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ event,
+ value,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class LoginModelStateData (
+ val state: ModelState? = null,
+ val isLoading: Boolean? = null
+) : ModelStateData()
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): LoginModelStateData {
+ val state = pigeonVar_list[0] as ModelState?
+ val isLoading = pigeonVar_list[1] as Boolean?
+ return LoginModelStateData(state, isLoading)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ state,
+ isLoading,
+ )
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class LoginModelEventData (
+ val event: LoginModelEvent? = null
+) : ModelEventData()
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): LoginModelEventData {
+ val event = pigeonVar_list[0] as LoginModelEvent?
+ return LoginModelEventData(event)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ event,
+ )
+ }
+}
+private open class DataModelPigeonCodec : StandardMessageCodec() {
+ override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
+ return when (type) {
+ 129.toByte() -> {
+ return (readValue(buffer) as Long?)?.let {
+ SnippetLanguageType.ofRaw(it.toInt())
+ }
+ }
+ 130.toByte() -> {
+ return (readValue(buffer) as Long?)?.let {
+ SnippetFilterType.ofRaw(it.toInt())
+ }
+ }
+ 131.toByte() -> {
+ return (readValue(buffer) as Long?)?.let {
+ UserReaction.ofRaw(it.toInt())
+ }
+ }
+ 132.toByte() -> {
+ return (readValue(buffer) as Long?)?.let {
+ ModelState.ofRaw(it.toInt())
+ }
+ }
+ 133.toByte() -> {
+ return (readValue(buffer) as Long?)?.let {
+ MainModelEvent.ofRaw(it.toInt())
+ }
+ }
+ 134.toByte() -> {
+ return (readValue(buffer) as Long?)?.let {
+ DetailsModelEvent.ofRaw(it.toInt())
+ }
+ }
+ 135.toByte() -> {
+ return (readValue(buffer) as Long?)?.let {
+ LoginModelEvent.ofRaw(it.toInt())
+ }
+ }
+ 136.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ Snippet.fromList(it)
+ }
+ }
+ 137.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ SnippetCode.fromList(it)
+ }
+ }
+ 138.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ SyntaxToken.fromList(it)
+ }
+ }
+ 139.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ SnippetLanguage.fromList(it)
+ }
+ }
+ 140.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ Owner.fromList(it)
+ }
+ }
+ 141.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ SnippetFilter.fromList(it)
+ }
+ }
+ 142.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ MainModelStateData.fromList(it)
+ }
+ }
+ 143.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ MainModelEventData.fromList(it)
+ }
+ }
+ 144.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ DetailsModelStateData.fromList(it)
+ }
+ }
+ 145.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ DetailsModelEventData.fromList(it)
+ }
+ }
+ 146.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ LoginModelStateData.fromList(it)
+ }
+ }
+ 147.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ LoginModelEventData.fromList(it)
+ }
+ }
+ else -> super.readValueOfType(type, buffer)
+ }
+ }
+ override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
+ when (value) {
+ is SnippetLanguageType -> {
+ stream.write(129)
+ writeValue(stream, value.raw)
+ }
+ is SnippetFilterType -> {
+ stream.write(130)
+ writeValue(stream, value.raw)
+ }
+ is UserReaction -> {
+ stream.write(131)
+ writeValue(stream, value.raw)
+ }
+ is ModelState -> {
+ stream.write(132)
+ writeValue(stream, value.raw)
+ }
+ is MainModelEvent -> {
+ stream.write(133)
+ writeValue(stream, value.raw)
+ }
+ is DetailsModelEvent -> {
+ stream.write(134)
+ writeValue(stream, value.raw)
+ }
+ is LoginModelEvent -> {
+ stream.write(135)
+ writeValue(stream, value.raw)
+ }
+ is Snippet -> {
+ stream.write(136)
+ writeValue(stream, value.toList())
+ }
+ is SnippetCode -> {
+ stream.write(137)
+ writeValue(stream, value.toList())
+ }
+ is SyntaxToken -> {
+ stream.write(138)
+ writeValue(stream, value.toList())
+ }
+ is SnippetLanguage -> {
+ stream.write(139)
+ writeValue(stream, value.toList())
+ }
+ is Owner -> {
+ stream.write(140)
+ writeValue(stream, value.toList())
+ }
+ is SnippetFilter -> {
+ stream.write(141)
+ writeValue(stream, value.toList())
+ }
+ is MainModelStateData -> {
+ stream.write(142)
+ writeValue(stream, value.toList())
+ }
+ is MainModelEventData -> {
+ stream.write(143)
+ writeValue(stream, value.toList())
+ }
+ is DetailsModelStateData -> {
+ stream.write(144)
+ writeValue(stream, value.toList())
+ }
+ is DetailsModelEventData -> {
+ stream.write(145)
+ writeValue(stream, value.toList())
+ }
+ is LoginModelStateData -> {
+ stream.write(146)
+ writeValue(stream, value.toList())
+ }
+ is LoginModelEventData -> {
+ stream.write(147)
+ writeValue(stream, value.toList())
+ }
+ else -> super.writeValue(stream, value)
+ }
+ }
+}
+
+val DataModelPigeonMethodCodec = StandardMethodCodec(DataModelPigeonCodec());
+
+
+private class DataModelPigeonStreamHandler(
+ val wrapper: DataModelPigeonEventChannelWrapper
+) : EventChannel.StreamHandler {
+ var pigeonSink: PigeonEventSink? = null
+
+ override fun onListen(p0: Any?, sink: EventChannel.EventSink) {
+ pigeonSink = PigeonEventSink(sink)
+ wrapper.onListen(p0, pigeonSink!!)
+ }
+
+ override fun onCancel(p0: Any?) {
+ pigeonSink = null
+ wrapper.onCancel(p0)
+ }
+}
+
+interface DataModelPigeonEventChannelWrapper {
+ open fun onListen(p0: Any?, sink: PigeonEventSink) {}
+
+ open fun onCancel(p0: Any?) {}
+}
+
+class PigeonEventSink(private val sink: EventChannel.EventSink) {
+ fun success(value: T) {
+ sink.success(value)
+ }
+
+ fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
+ sink.error(errorCode, errorMessage, errorDetails)
+ }
+
+ fun endOfStream() {
+ sink.endOfStream()
+ }
+}
+
+abstract class ChannelStateStreamHandler : DataModelPigeonEventChannelWrapper {
+ companion object {
+ fun register(messenger: BinaryMessenger, streamHandler: ChannelStateStreamHandler, instanceName: String = "") {
+ var channelName: String = "dev.flutter.pigeon.flutter_module.ChannelModelEventApi.channelState"
+ if (instanceName.isNotEmpty()) {
+ channelName += ".$instanceName"
+ }
+ val internalStreamHandler = DataModelPigeonStreamHandler(streamHandler)
+ EventChannel(messenger, channelName, DataModelPigeonMethodCodec).setStreamHandler(internalStreamHandler)
+ }
+ }
+}
+
+abstract class ChannelEventStreamHandler : DataModelPigeonEventChannelWrapper {
+ companion object {
+ fun register(messenger: BinaryMessenger, streamHandler: ChannelEventStreamHandler, instanceName: String = "") {
+ var channelName: String = "dev.flutter.pigeon.flutter_module.ChannelModelEventApi.channelEvent"
+ if (instanceName.isNotEmpty()) {
+ channelName += ".$instanceName"
+ }
+ val internalStreamHandler = DataModelPigeonStreamHandler(streamHandler)
+ EventChannel(messenger, channelName, DataModelPigeonMethodCodec).setStreamHandler(internalStreamHandler)
+ }
+ }
+}
+
+/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+interface ChannelMainModel {
+ fun resetEvent()
+ fun initState()
+ fun filterLanguage(language: String, isSelected: Boolean)
+ fun filterScope(scope: String)
+ fun logOut()
+
+ companion object {
+ /** The codec used by ChannelMainModel. */
+ val codec: MessageCodec by lazy {
+ DataModelPigeonCodec()
+ }
+ /** Sets up an instance of `ChannelMainModel` to handle messages through the `binaryMessenger`. */
+ @JvmOverloads
+ fun setUp(binaryMessenger: BinaryMessenger, api: ChannelMainModel?, messageChannelSuffix: String = "") {
+ val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
+ val taskQueue = binaryMessenger.makeBackgroundTaskQueue()
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelMainModel.resetEvent$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.resetEvent()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelMainModel.initState$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.initState()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelMainModel.filterLanguage$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val languageArg = args[0] as String
+ val isSelectedArg = args[1] as Boolean
+ val wrapped: List = try {
+ api.filterLanguage(languageArg, isSelectedArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelMainModel.filterScope$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val scopeArg = args[0] as String
+ val wrapped: List = try {
+ api.filterScope(scopeArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelMainModel.logOut$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.logOut()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ }
+ }
+}
+/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+interface ChannelDetailsModel {
+ fun resetEvent()
+ fun load(uuid: String)
+ fun toggleFavorite()
+ fun saveImage(image: ByteArray)
+ fun copyToClipboard()
+ fun shareImage(image: ByteArray)
+ fun delete()
+
+ companion object {
+ /** The codec used by ChannelDetailsModel. */
+ val codec: MessageCodec by lazy {
+ DataModelPigeonCodec()
+ }
+ /** Sets up an instance of `ChannelDetailsModel` to handle messages through the `binaryMessenger`. */
+ @JvmOverloads
+ fun setUp(binaryMessenger: BinaryMessenger, api: ChannelDetailsModel?, messageChannelSuffix: String = "") {
+ val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelDetailsModel.resetEvent$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.resetEvent()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelDetailsModel.load$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val uuidArg = args[0] as String
+ val wrapped: List = try {
+ api.load(uuidArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelDetailsModel.toggleFavorite$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.toggleFavorite()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelDetailsModel.saveImage$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val imageArg = args[0] as ByteArray
+ val wrapped: List = try {
+ api.saveImage(imageArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelDetailsModel.copyToClipboard$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.copyToClipboard()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelDetailsModel.shareImage$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val imageArg = args[0] as ByteArray
+ val wrapped: List = try {
+ api.shareImage(imageArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelDetailsModel.delete$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.delete()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ }
+ }
+}
+/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+interface ChannelLoginModel {
+ fun loginOrRegister(email: String, password: String)
+ fun checkLoginState()
+ fun resetEvent()
+
+ companion object {
+ /** The codec used by ChannelLoginModel. */
+ val codec: MessageCodec by lazy {
+ DataModelPigeonCodec()
+ }
+ /** Sets up an instance of `ChannelLoginModel` to handle messages through the `binaryMessenger`. */
+ @JvmOverloads
+ fun setUp(binaryMessenger: BinaryMessenger, api: ChannelLoginModel?, messageChannelSuffix: String = "") {
+ val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelLoginModel.loginOrRegister$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val emailArg = args[0] as String
+ val passwordArg = args[1] as String
+ val wrapped: List = try {
+ api.loginOrRegister(emailArg, passwordArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelLoginModel.checkLoginState$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.checkLoginState()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_module.ChannelLoginModel.resetEvent$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.resetEvent()
+ listOf(null)
+ } catch (exception: Throwable) {
+ wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/EventStreamHandlerPlugin.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/EventStreamHandlerPlugin.kt
new file mode 100644
index 0000000..a0230cf
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/EventStreamHandlerPlugin.kt
@@ -0,0 +1,48 @@
+package dev.snipme.snipmeapp.channel
+
+import io.flutter.embedding.engine.plugins.FlutterPlugin
+import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
+import io.flutter.plugin.common.BinaryMessenger
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
+
+class FlowChannelEventStreamHandler : ChannelEventStreamHandler() {
+ private val scope = CoroutineScope(Dispatchers.Main)
+ private val sinkFlow = MutableSharedFlow(
+ replay = 3,
+ onBufferOverflow = DROP_OLDEST
+ )
+
+ fun onSetup(messenger: BinaryMessenger) {
+ register(messenger, this)
+ }
+
+ override fun onListen(p0: Any?, sink: PigeonEventSink) {
+ sinkFlow.onEach { sink.success(it) }.launchIn(scope)
+ }
+
+ override fun onCancel(p0: Any?) {
+ sinkFlow.resetReplayCache()
+ }
+
+ fun zip(flow: Flow) {
+ flow.onEach { sinkFlow.emit(it) }.launchIn(scope)
+ }
+}
+
+class EventStreamHandlerPlugin : FlutterPlugin, KoinComponent {
+ private val eventStream by inject()
+
+ override fun onAttachedToEngine(binding: FlutterPluginBinding) {
+ eventStream.onSetup(binding.binaryMessenger)
+ }
+
+ override fun onDetachedFromEngine(binding: FlutterPluginBinding) {}
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/ModelPlugin.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/ModelPlugin.kt
new file mode 100644
index 0000000..82ae9e5
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/ModelPlugin.kt
@@ -0,0 +1,95 @@
+package dev.snipme.snipmeapp.channel
+
+import android.text.Spanned
+import android.text.format.DateUtils
+import android.text.style.ForegroundColorSpan
+import androidx.core.text.getSpans
+import io.flutter.embedding.engine.plugins.FlutterPlugin
+import io.flutter.plugin.common.BinaryMessenger
+import org.koin.core.component.KoinComponent
+import dev.snipme.snipmeapp.domain.reaction.UserReaction
+import dev.snipme.snipmeapp.domain.snippets.*
+import java.util.*
+import dev.snipme.snipmeapp.channel.Snippet as ChannelSnippet
+import dev.snipme.snipmeapp.channel.SnippetCode as ChannelSnippetCode
+import dev.snipme.snipmeapp.channel.SnippetLanguage as ChannelSnippetLanguage
+import dev.snipme.snipmeapp.channel.SnippetLanguageType as ChannelSnippetLanguageType
+import dev.snipme.snipmeapp.channel.UserReaction as ChannelUserReaction
+import dev.snipme.snipmeapp.channel.SyntaxToken as ChannelSyntaxToken
+import dev.snipme.snipmeapp.channel.Owner as ChannelOwner
+
+abstract class ModelPlugin : FlutterPlugin, KoinComponent {
+
+ abstract fun onSetup(messenger: BinaryMessenger, channelModel: T?)
+
+ override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
+ onSetup(binding.binaryMessenger, this as T)
+ }
+
+ override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
+ onSetup(binding.binaryMessenger, null)
+ }
+}
+
+fun Snippet.toModelData(): ChannelSnippet =
+ ChannelSnippet(
+ uuid = uuid,
+ title = title,
+ code = code.toModelSnippetCode(),
+ language = language.toModelSnippetLanguage(),
+ owner = owner.toModelOwner(),
+ isOwner = isOwner,
+ voteResult = (numberOfLikes - numberOfDislikes).toLong(),
+ userReaction = userReaction.toModelUserReaction(),
+ isLiked = userReaction.toModelReactionState(UserReaction.LIKE),
+ isDisliked = userReaction.toModelReactionState(UserReaction.DISLIKE),
+ isPrivate = visibility == SnippetVisibility.PRIVATE,
+ isSaved = calculateSavedState(isOwner, visibility),
+ isToDelete = isOwner,
+ timeAgo = DateUtils.getRelativeTimeSpanString(
+ modifiedAt.time,
+ Date().time,
+ DateUtils.SECOND_IN_MILLIS
+ ).toString()
+ )
+
+private fun Owner.toModelOwner() = ChannelOwner(id = id.toLong(), login = login)
+
+private fun SnippetCode.toModelSnippetCode() =
+ ChannelSnippetCode(
+ raw = raw,
+ tokens = highlighted.getSpans().map { span ->
+ span.toSyntaxToken(highlighted)
+ },
+ )
+
+private fun SnippetLanguage.toModelSnippetLanguage() =
+ ChannelSnippetLanguage(
+ raw = raw,
+ type = ChannelSnippetLanguageType.valueOf(type.name),
+ )
+
+private fun UserReaction.toModelUserReaction(): ChannelUserReaction =
+ when (this) {
+ UserReaction.LIKE -> ChannelUserReaction.LIKE
+ UserReaction.DISLIKE -> ChannelUserReaction.DISLIKE
+ else -> ChannelUserReaction.NONE
+ }
+
+private fun UserReaction.toModelReactionState(reaction: UserReaction) =
+ if (this == UserReaction.NONE) null else this == reaction
+
+private fun calculateSavedState(
+ isOwner: Boolean,
+ visibility: SnippetVisibility
+): Boolean? {
+ if (isOwner.not()) return null
+ return visibility == SnippetVisibility.PRIVATE
+}
+
+private fun ForegroundColorSpan.toSyntaxToken(spannable: Spanned) =
+ ChannelSyntaxToken(
+ start = spannable.getSpanStart(this).toLong(),
+ end = spannable.getSpanEnd(this).toLong(),
+ color = foregroundColor.toLong(),
+ )
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/StateStreamHandlerPlugin.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/StateStreamHandlerPlugin.kt
new file mode 100644
index 0000000..3bd5dc3
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/StateStreamHandlerPlugin.kt
@@ -0,0 +1,48 @@
+package dev.snipme.snipmeapp.channel
+
+import io.flutter.embedding.engine.plugins.FlutterPlugin
+import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
+import io.flutter.plugin.common.BinaryMessenger
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
+
+class FlowChannelStateStreamHandler : ChannelStateStreamHandler() {
+ private val scope = CoroutineScope(Dispatchers.Main)
+ private val sinkFlow = MutableSharedFlow(
+ replay = 3,
+ onBufferOverflow = DROP_OLDEST
+ )
+
+ fun onSetup(messenger: BinaryMessenger) {
+ register(messenger, this)
+ }
+
+ override fun onListen(p0: Any?, sink: PigeonEventSink) {
+ sinkFlow.onEach { sink.success(it) }.launchIn(scope)
+ }
+
+ override fun onCancel(p0: Any?) {
+ sinkFlow.resetReplayCache()
+ }
+
+ fun zip(flow: Flow) {
+ flow.onEach { sinkFlow.emit(it) }.launchIn(scope)
+ }
+}
+
+class StateStreamHandlerPlugin : FlutterPlugin, KoinComponent {
+ private val stateStream by inject()
+
+ override fun onAttachedToEngine(binding: FlutterPluginBinding) {
+ stateStream.onSetup(binding.binaryMessenger)
+ }
+
+ override fun onDetachedFromEngine(binding: FlutterPluginBinding) {}
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/details/DetailsModel.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/details/DetailsModel.kt
new file mode 100644
index 0000000..c97cb3f
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/details/DetailsModel.kt
@@ -0,0 +1,167 @@
+package dev.snipme.snipmeapp.channel.details
+
+import dev.snipme.snipmeapp.channel.error.ErrorParsable
+import dev.snipme.snipmeapp.channel.session.SessionModel
+import dev.snipme.snipmeapp.domain.clipboard.AddToClipboardUseCase
+import dev.snipme.snipmeapp.domain.error.exception.ConnectionException
+import dev.snipme.snipmeapp.domain.error.exception.ContentNotFoundException
+import dev.snipme.snipmeapp.domain.error.exception.ForbiddenActionException
+import dev.snipme.snipmeapp.domain.error.exception.NetworkNotAvailableException
+import dev.snipme.snipmeapp.domain.error.exception.NotAuthorizedException
+import dev.snipme.snipmeapp.domain.error.exception.RemoteException
+import dev.snipme.snipmeapp.domain.error.exception.SessionExpiredException
+import dev.snipme.snipmeapp.domain.message.ErrorMessages
+import dev.snipme.snipmeapp.domain.reaction.GetTargetUserReactionUseCase
+import dev.snipme.snipmeapp.domain.reaction.SetUserReactionUseCase
+import dev.snipme.snipmeapp.domain.reaction.UserReaction
+import dev.snipme.snipmeapp.domain.share.ShareSnippetUseCase
+import dev.snipme.snipmeapp.domain.snippet.DeleteSnippetUseCase
+import dev.snipme.snipmeapp.domain.snippet.GetSingleSnippetUseCase
+import dev.snipme.snipmeapp.domain.snippet.SaveSnippetUseCase
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.rxkotlin.plusAssign
+import io.reactivex.rxkotlin.subscribeBy
+import io.reactivex.schedulers.Schedulers
+import kotlinx.coroutines.flow.MutableStateFlow
+import timber.log.Timber
+
+class DetailsModel(
+ private val errorMessages: ErrorMessages,
+ private val getSnippet: GetSingleSnippetUseCase,
+ private val clipboard: AddToClipboardUseCase,
+ private val getTargetReaction: GetTargetUserReactionUseCase,
+ private val setUserReaction: SetUserReactionUseCase,
+ private val saveSnippet: SaveSnippetUseCase,
+ private val shareSnippet: ShareSnippetUseCase,
+ private val deleteSnippet: DeleteSnippetUseCase,
+ private val session: SessionModel
+) : ErrorParsable {
+ private val disposables = CompositeDisposable()
+
+ private val mutableState = MutableStateFlow(Loading)
+ val state = mutableState
+
+ private val mutableEvent = MutableStateFlow(Idle)
+ val event = mutableEvent
+
+ override fun parseError(throwable: Throwable) {
+ when (throwable) {
+ is ConnectionException -> setState(Error(errorMessages.parse(throwable)))
+ is ContentNotFoundException -> setState(Error(errorMessages.parse(throwable)))
+ is ForbiddenActionException -> setState(Error(errorMessages.parse(throwable)))
+ is NetworkNotAvailableException -> setState(Error(errorMessages.parse(throwable)))
+ is NotAuthorizedException -> session.logOut { mutableEvent.value = Logout }
+ is RemoteException -> setState(Error(errorMessages.parse(throwable)))
+ is SessionExpiredException -> session.logOut { mutableEvent.value = Logout }
+ else -> setState(Error(errorMessages.parse(throwable)))
+ }
+ }
+
+ fun load(uuid: String) {
+ setState(Loading)
+ getSnippet(uuid)
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onSuccess = { setState(Loaded(it)) },
+ onError = {
+ Timber.e("Couldn't load snippets, error = $it")
+ parseError(it)
+ }
+ ).also { disposables += it }
+ }
+
+ fun toggleFavorite() {
+ // TODO Implement
+ }
+
+ fun copyToClipboard() {
+ getSnippet()?.let {
+ clipboard(it.title, it.code.raw)
+ }
+ }
+
+ fun save(image: ByteArray) {
+ Timber.d("Saving snippet image ${image.size}")
+ try {
+ getSnippet()?.let {
+ saveSnippet(image, it)
+ Timber.d("Snippet ${it.title} saved")
+ }
+ mutableEvent.value = Alert("Snippet saved")
+ } catch (e: Exception) {
+ Timber.e("Couldn't save snippet, error = $e")
+ mutableEvent.value = Alert(errorMessages.generic)
+ }
+ }
+
+ fun share(image: ByteArray) {
+ try {
+ getSnippet()?.let {
+ shareSnippet(image, it)
+ }
+ mutableEvent.value = Alert("Snippet shared")
+ } catch (e: Exception) {
+ Timber.e("Couldn't share snippet, error = $e")
+ mutableEvent.value = Alert(errorMessages.generic)
+ }
+ }
+
+ fun delete() {
+ getSnippet()?.let {
+ setState(Loading)
+ deleteSnippet(it.uuid)
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onComplete = { mutableEvent.value = Deleted },
+ onError = { error ->
+ Timber.e("Couldn't delete snippet, error = $error")
+ parseError(error)
+ }
+ ).also { disposables += it }
+ }
+ }
+
+ private fun changeReaction(newReaction: UserReaction) {
+ // Immediately show change to user
+ val previousState = getLoaded() ?: return
+ val targetReaction = getTargetReaction(previousState.snippet, newReaction)
+ setState(previousState.run { copy(snippet = snippet.copy(userReaction = targetReaction)) })
+
+ setUserReaction(previousState.snippet, newReaction)
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onSuccess = { snippet -> mutableState.value = Loaded(snippet) },
+ onError = {
+ // Revert changes
+ Timber.e("Couldn't change user reaction, error = $it")
+ mutableEvent.value = Alert(errorMessages.generic)
+ setState(previousState)
+ }
+ ).also { disposables += it }
+ }
+
+ private fun getSnippet(): Snippet? = getLoaded()?.snippet
+
+ private fun getLoaded() =
+ if (state.value is Loaded) {
+ (state.value as Loaded)
+ } else {
+ null
+ }
+
+ private fun setState(newState: DetailsViewState?) {
+ newState?.let { mutableState.value = it }
+ }
+}
+
+sealed class DetailsViewState
+data object Loading : DetailsViewState()
+data class Loaded(val snippet: Snippet) : DetailsViewState()
+data class Error(val error: String?) : DetailsViewState()
+
+sealed class DetailsEvent
+data object Idle : DetailsEvent()
+data object Deleted : DetailsEvent()
+data class Alert(val message: String) : DetailsEvent()
+data object Logout : DetailsEvent()
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/details/DetailsModelPlugin.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/details/DetailsModelPlugin.kt
new file mode 100644
index 0000000..55496d6
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/details/DetailsModelPlugin.kt
@@ -0,0 +1,83 @@
+package dev.snipme.snipmeapp.channel.details
+
+import dev.snipme.snipmeapp.channel.ChannelDetailsModel
+import dev.snipme.snipmeapp.channel.FlowChannelEventStreamHandler
+import dev.snipme.snipmeapp.channel.FlowChannelStateStreamHandler
+import dev.snipme.snipmeapp.channel.ModelPlugin
+import dev.snipme.snipmeapp.channel.toModelData
+import io.flutter.plugin.common.BinaryMessenger
+import kotlinx.coroutines.flow.map
+import org.koin.core.component.inject
+import dev.snipme.snipmeapp.channel.DetailsModelEvent as ChannelDetailsModelEvent
+import dev.snipme.snipmeapp.channel.DetailsModelEventData as ChannelDetailsModelEventData
+import dev.snipme.snipmeapp.channel.DetailsModelStateData as ChannelDetailsModelStateData
+import dev.snipme.snipmeapp.channel.ModelState as ChannelModelState
+
+class DetailsModelPlugin : ModelPlugin(), ChannelDetailsModel {
+ private val model: DetailsModel by inject()
+ private val channelStateFlow by inject()
+ private val channelEventFlow by inject()
+
+ override fun onSetup(messenger: BinaryMessenger, channelModel: ChannelDetailsModel?) {
+ ChannelDetailsModel.setUp(messenger, channelModel)
+ channelStateFlow.zip(model.state.map { getModelState(it) })
+ channelEventFlow.zip(model.event.map { getModelEvent(it) })
+ }
+
+ override fun resetEvent() {
+ model.event.value = Idle
+ }
+
+ override fun load(uuid: String) {
+ model.load(uuid)
+ }
+
+ override fun toggleFavorite() {
+ model.toggleFavorite()
+ }
+
+ override fun saveImage(image: ByteArray) {
+ model.save(image)
+ }
+
+ override fun copyToClipboard() {
+ model.copyToClipboard()
+ }
+
+ override fun shareImage(image: ByteArray) {
+ model.share(image)
+ }
+
+ override fun delete() {
+ model.delete()
+ }
+
+ private fun getModelState(viewState: DetailsViewState): ChannelDetailsModelStateData {
+ return ChannelDetailsModelStateData(
+ state = viewState.toModelState(),
+ isLoading = viewState is Loading,
+ data = (viewState as? Loaded)?.snippet?.toModelData(),
+ )
+ }
+
+ private fun getModelEvent(event: DetailsEvent): ChannelDetailsModelEventData {
+ return ChannelDetailsModelEventData(
+ event = event.toModelEvent(),
+ value = (event as? Alert)?.message.orEmpty()
+ )
+ }
+
+ private fun DetailsViewState.toModelState() =
+ when (this) {
+ Loading -> ChannelModelState.LOADING
+ is Loaded -> ChannelModelState.LOADED
+ else -> ChannelModelState.ERROR
+ }
+
+ private fun DetailsEvent.toModelEvent() =
+ when (this) {
+ is Deleted -> ChannelDetailsModelEvent.DELETED
+ is Alert -> ChannelDetailsModelEvent.ALERT
+ else -> ChannelDetailsModelEvent.NONE
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/ui/error/ErrorParsable.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/error/ErrorParsable.kt
similarity index 60%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/ui/error/ErrorParsable.kt
rename to app/src/main/java/dev/snipme/snipmeapp/channel/error/ErrorParsable.kt
index 66ec2d2..6db36db 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/ui/error/ErrorParsable.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/error/ErrorParsable.kt
@@ -1,6 +1,5 @@
-package pl.tkadziolka.snipmeandroid.ui.error
+package dev.snipme.snipmeapp.channel.error
interface ErrorParsable {
-
fun parseError(throwable: Throwable)
}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/login/LoginModel.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/login/LoginModel.kt
new file mode 100644
index 0000000..ed1cc70
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/login/LoginModel.kt
@@ -0,0 +1,137 @@
+package dev.snipme.snipmeapp.channel.login
+
+import dev.snipme.snipmeapp.channel.error.ErrorParsable
+import dev.snipme.snipmeapp.domain.auth.InitialLoginUseCase
+import dev.snipme.snipmeapp.domain.auth.LoginInteractor
+import dev.snipme.snipmeapp.domain.error.exception.ConnectionException
+import dev.snipme.snipmeapp.domain.error.exception.ContentNotFoundException
+import dev.snipme.snipmeapp.domain.error.exception.ForbiddenActionException
+import dev.snipme.snipmeapp.domain.error.exception.NetworkNotAvailableException
+import dev.snipme.snipmeapp.domain.error.exception.NotAuthorizedException
+import dev.snipme.snipmeapp.domain.error.exception.RemoteException
+import dev.snipme.snipmeapp.domain.error.exception.SessionExpiredException
+import dev.snipme.snipmeapp.domain.message.ErrorMessages
+import dev.snipme.snipmeapp.util.extension.inProgress
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.disposables.Disposable
+import io.reactivex.rxkotlin.plusAssign
+import io.reactivex.rxkotlin.subscribeBy
+import io.reactivex.schedulers.Schedulers
+import kotlinx.coroutines.flow.MutableStateFlow
+import timber.log.Timber
+import java.util.concurrent.TimeUnit
+
+class LoginModel(
+ private val errorMessages: ErrorMessages,
+ private val interactor: LoginInteractor,
+ private val initialLogin: InitialLoginUseCase,
+) : ErrorParsable {
+ private val disposables = CompositeDisposable()
+ private var identifyDisposable: Disposable? = null
+ private var loginDisposable: Disposable? = null
+ private var registerDisposable: Disposable? = null
+
+ private val mutableState = MutableStateFlow(Loading)
+ val state = mutableState
+
+ private val mutableEvent = MutableStateFlow(Idle)
+ val event = mutableEvent
+
+ override fun parseError(throwable: Throwable) {
+ when (throwable) {
+ is ConnectionException -> setEvent(Error(errorMessages.parse(throwable)))
+ is ContentNotFoundException -> setEvent(Error(errorMessages.parse(throwable)))
+ is ForbiddenActionException -> setEvent(Error(errorMessages.alreadyRegistered))
+ is NetworkNotAvailableException -> setEvent(Error(errorMessages.parse(throwable)))
+ is NotAuthorizedException -> setEvent(Error(errorMessages.parse(throwable)))
+ is RemoteException -> setEvent(Error(errorMessages.parse(throwable)))
+ is SessionExpiredException -> setEvent(Error(errorMessages.parse(throwable)))
+ else -> setEvent(Error(errorMessages.parse(throwable)))
+ }
+ }
+
+ fun init() {
+ initialLogin()
+ .delay(3, TimeUnit.SECONDS)
+ .subscribeOn(Schedulers.io())
+ .doOnEvent { setState(Loaded) }
+ .subscribeBy(
+ onComplete = { setEvent(Logged) },
+ onError = {
+ if (it !is NotAuthorizedException) {
+ Timber.e("Couldn't get token or user, error = $it")
+ }
+ }
+ ).also { disposables += it }
+ }
+
+ fun loginOrRegister(email: String, password: String) {
+ if (identifyDisposable.inProgress()) return
+
+ identifyDisposable = interactor.identify(email)
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onSuccess = { identified -> publishIdentified(email, password, identified) },
+ onError = {
+ Timber.d("Couldn't identify user = $email, error = $it")
+ parseError(it)
+ }
+ ).also { disposables += it }
+ }
+
+ fun login(email: String, password: String) {
+ if (loginDisposable.inProgress()) return
+
+ loginDisposable = interactor.login(email, password)
+ .subscribeOn(Schedulers.io())
+ .doOnEvent { setState(Loaded) }
+ .subscribeBy(
+ onComplete = { setEvent(Logged) },
+ onError = {
+ Timber.d("Couldn't login user = $email, error = $it")
+ parseError(it)
+ }
+ ).also { disposables += it }
+ }
+
+ fun register(email: String, password: String) {
+ if (registerDisposable.inProgress()) return
+
+ registerDisposable = interactor.register(email, password, email)
+ .subscribeOn(Schedulers.io())
+ .doOnEvent { setState(Loaded) }
+ .subscribeBy(
+ onComplete = { setEvent(Logged) },
+ onError = {
+ Timber.d("Couldn't register user = $email, error = $it")
+ parseError(it)
+ }
+ ).also { disposables += it }
+ }
+
+ private fun publishIdentified(email: String, password: String, identified: Boolean) {
+ if (identified) {
+ login(email, password)
+ } else {
+ register(email, password)
+ }
+ }
+
+ private fun setEvent(event: LoginEvent) {
+ mutableEvent.value = event
+ }
+
+ private fun setState(state: LoginState) {
+ mutableState.value = state
+ }
+}
+
+
+sealed class LoginState
+data object Loading : LoginState()
+data object Loaded : LoginState()
+
+sealed class LoginEvent
+data object Idle : LoginEvent()
+data object Logged : LoginEvent()
+data class Error(val message: String?) : LoginEvent()
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/login/LoginModelPlugin.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/login/LoginModelPlugin.kt
new file mode 100644
index 0000000..e0b319c
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/login/LoginModelPlugin.kt
@@ -0,0 +1,62 @@
+package dev.snipme.snipmeapp.channel.login
+
+import dev.snipme.snipmeapp.channel.ChannelLoginModel
+import dev.snipme.snipmeapp.channel.FlowChannelEventStreamHandler
+import dev.snipme.snipmeapp.channel.FlowChannelStateStreamHandler
+import dev.snipme.snipmeapp.channel.ModelPlugin
+import io.flutter.plugin.common.BinaryMessenger
+import kotlinx.coroutines.flow.map
+import org.koin.core.component.inject
+import dev.snipme.snipmeapp.channel.LoginModelEvent as ChannelLoginModelEvent
+import dev.snipme.snipmeapp.channel.LoginModelEventData as ChannelLoginModelEventData
+import dev.snipme.snipmeapp.channel.LoginModelStateData as ChannelLoginModelStateData
+import dev.snipme.snipmeapp.channel.ModelState as ChannelModelState
+
+class LoginModelPlugin : ModelPlugin(), ChannelLoginModel {
+ private val model: LoginModel by inject()
+ private val channelStateFlow by inject()
+ private val channelEventFlow by inject()
+
+ override fun resetEvent() {
+ model.event.value = Idle
+ }
+
+ override fun onSetup(messenger: BinaryMessenger, channelModel: ChannelLoginModel?) {
+ ChannelLoginModel.setUp(messenger, channelModel)
+ channelStateFlow.zip(model.state.map { getModelState(it) })
+ channelEventFlow.zip(model.event.map { getModelEvent(it) })
+ }
+
+ override fun checkLoginState() {
+ model.init()
+ }
+
+ override fun loginOrRegister(email: String, password: String) {
+ model.loginOrRegister(email, password)
+ }
+
+ private fun getModelEvent(loginEvent: LoginEvent): ChannelLoginModelEventData {
+ return ChannelLoginModelEventData(
+ event = loginEvent.toModelLoginEvent()
+ )
+ }
+
+ private fun getModelState(loginState: LoginState): ChannelLoginModelStateData {
+ return ChannelLoginModelStateData(
+ state = loginState.toModelLoginState(),
+ isLoading = loginState is Loading
+ )
+ }
+
+ private fun LoginState.toModelLoginState() =
+ when (this) {
+ Loaded -> ChannelModelState.LOADED
+ else -> ChannelModelState.LOADING
+ }
+
+ private fun LoginEvent.toModelLoginEvent() =
+ when (this) {
+ Logged -> ChannelLoginModelEvent.LOGGED
+ else -> ChannelLoginModelEvent.NONE
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/main/MainModel.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/main/MainModel.kt
new file mode 100644
index 0000000..d8263a8
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/main/MainModel.kt
@@ -0,0 +1,179 @@
+package dev.snipme.snipmeapp.channel.main
+
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.rxkotlin.plusAssign
+import io.reactivex.rxkotlin.subscribeBy
+import io.reactivex.schedulers.Schedulers
+import kotlinx.coroutines.flow.MutableStateFlow
+import dev.snipme.snipmeapp.channel.session.SessionModel
+import dev.snipme.snipmeapp.domain.error.exception.*
+import dev.snipme.snipmeapp.domain.filter.*
+import dev.snipme.snipmeapp.domain.message.ErrorMessages
+import dev.snipme.snipmeapp.domain.snippet.ObserveSnippetUpdatesUseCase
+import dev.snipme.snipmeapp.domain.snippets.*
+import dev.snipme.snipmeapp.domain.user.GetSingleUserUseCase
+import dev.snipme.snipmeapp.domain.user.User
+import dev.snipme.snipmeapp.channel.error.ErrorParsable
+import timber.log.Timber
+
+private const val ONE_PAGE = 1
+
+class MainModel(
+ private val errorMessages: ErrorMessages,
+ private val getUser: GetSingleUserUseCase,
+ private val getSnippets: GetSnippetsUseCase,
+ private val observeUpdates: ObserveSnippetUpdatesUseCase,
+ private val hasMore: HasMoreSnippetPagesUseCase,
+ private val getLanguageFilters: GetLanguageFiltersUseCase,
+ private val filterSnippetsByLanguage: FilterSnippetsByLanguageUseCase,
+ private val filterSnippetsByScope: FilterSnippetsByScopeUseCase,
+ private val updateFilterLanguage: UpdateSnippetFiltersLanguageUseCase,
+ private val session: SessionModel
+) : ErrorParsable {
+ private val disposables = CompositeDisposable()
+
+ private val mutableEvent = MutableStateFlow(Startup)
+ val event = mutableEvent
+
+ private val mutableState = MutableStateFlow(Loading)
+ val state = mutableState
+
+ private var cachedSnippets = emptyList()
+ private var scopedSnippets = emptyList()
+ private lateinit var filterState: SnippetFilters
+
+ override fun parseError(throwable: Throwable) {
+ when (throwable) {
+ is ConnectionException -> mutableState.value = Error(errorMessages.parse(throwable))
+ is ContentNotFoundException -> mutableState.value =
+ Error(errorMessages.parse(throwable))
+ is ForbiddenActionException -> mutableState.value =
+ Error(errorMessages.parse(throwable))
+ is NetworkNotAvailableException -> mutableState.value =
+ Error(errorMessages.parse(throwable))
+ is NotAuthorizedException -> session.logOut { mutableEvent.value = Logout }
+ is RemoteException -> mutableState.value = Error(errorMessages.parse(throwable))
+ is SessionExpiredException -> session.logOut { mutableEvent.value = Logout }
+ else -> mutableState.value = Error(errorMessages.parse(throwable))
+ }
+ }
+
+ init {
+ observeUpdates()
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onNext = { initState() },
+ onError = { Timber.e("Couldn't refresh snippet updates, error = $it") }
+ ).also { disposables += it }
+ }
+
+ fun initState() {
+ mutableState.value = Loading
+ filterState = SnippetFilters(
+ languages = listOf(SNIPPET_FILTER_ALL),
+ selectedLanguages = listOf(SNIPPET_FILTER_ALL),
+ scopes = listOf("All", "Private", "Public"),
+ selectedScope = "All"
+ )
+
+ getUser()
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onSuccess = { user -> loadSnippets(user) },
+ onError = {
+ Timber.e("Couldn't load user, error = $it")
+ parseError(it)
+ }
+ ).also { disposables += it }
+ }
+
+ fun filterLanguage(language: String, isSelected: Boolean) {
+ getLoadedState()?.let {
+ filterState = updateFilterLanguage(filterState, language, isSelected)
+ val filteredSnippets =
+ filterSnippetsByLanguage(scopedSnippets, filterState.selectedLanguages)
+ state.value = it.copy(snippets = filteredSnippets, filters = filterState)
+ }
+ }
+
+ fun filterScope(scope: String) {
+ getLoadedState()?.let {
+ filterState = filterState.copy(selectedScope = scope)
+ scopedSnippets = filterSnippetsByScope(cachedSnippets, scope)
+ val updatedFilters = getLanguageFilters(scopedSnippets)
+ filterState = filterState.copy(
+ languages = updatedFilters,
+ selectedLanguages = listOf(SNIPPET_FILTER_ALL),
+ )
+ state.value = it.copy(snippets = scopedSnippets, filters = filterState)
+ }
+ }
+
+ fun logOut() {
+ session.logOut { mutableEvent.value = Logout }
+ }
+
+ private fun loadNextPage() {
+ getLoadedState()?.let { state ->
+ hasMore(SnippetScope.ALL, state.pages)
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onSuccess = { hasMore ->
+ if (hasMore) {
+ loadSnippets(state.user, pages = state.pages + ONE_PAGE)
+ }
+ },
+ onError = {
+ Timber.e("Couldn't check next page, error = $it")
+ mutableEvent.value = Alert(errorMessages.parse(it))
+ })
+ .also { disposables += it }
+ }
+ }
+
+ private fun loadSnippets(
+ user: User,
+ pages: Int = 1,
+ scope: SnippetScope = SnippetScope.ALL
+ ) {
+ getSnippets(scope, pages)
+ .subscribeOn(Schedulers.io())
+ .subscribeBy(
+ onSuccess = {
+ cachedSnippets = it
+ scopedSnippets = cachedSnippets
+ val updatedFilters = getLanguageFilters(cachedSnippets)
+ filterState = filterState.copy(languages = updatedFilters)
+ mutableState.value = Loaded(
+ user,
+ it,
+ pages,
+ filterState
+ )
+ loadNextPage()
+ },
+ onError = {
+ Timber.e("Couldn't load snippets, error = $it")
+ parseError(it)
+ }
+ ).also { disposables += it }
+ }
+
+ private fun getLoadedState(): Loaded? = state.value as? Loaded
+}
+
+sealed class MainViewState
+data object Loading : MainViewState()
+data class Loaded(
+ val user: User,
+ val snippets: List,
+ val pages: Int,
+ val filters: SnippetFilters
+) : MainViewState()
+
+data class Error(val message: String?) : MainViewState()
+
+sealed class MainEvent
+data object Startup : MainEvent()
+data class Alert(val message: String) : MainEvent()
+data object Logout : MainEvent()
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/channel/main/MainModelPlugin.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/main/MainModelPlugin.kt
new file mode 100644
index 0000000..3075199
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/main/MainModelPlugin.kt
@@ -0,0 +1,93 @@
+package dev.snipme.snipmeapp.channel.main
+
+import dev.snipme.snipmeapp.channel.FlowChannelEventStreamHandler
+import dev.snipme.snipmeapp.channel.FlowChannelStateStreamHandler
+import dev.snipme.snipmeapp.channel.ModelPlugin
+import dev.snipme.snipmeapp.channel.toModelData
+import dev.snipme.snipmeapp.channel.ChannelMainModel
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.snippets.SnippetFilters
+import io.flutter.plugin.common.BinaryMessenger
+import kotlinx.coroutines.flow.map
+import org.koin.core.component.inject
+import dev.snipme.snipmeapp.channel.MainModelEvent as ChannelMainModelEvent
+import dev.snipme.snipmeapp.channel.MainModelEventData as ChannelMainModelEventData
+import dev.snipme.snipmeapp.channel.MainModelStateData as ChannelMainModelStateData
+import dev.snipme.snipmeapp.channel.ModelState as ChannelModelState
+import dev.snipme.snipmeapp.channel.SnippetFilter as ChannelSnippetFilter
+
+class MainModelPlugin : ModelPlugin(), ChannelMainModel {
+ private val model: MainModel by inject()
+ private val channelStateFlow by inject()
+ private val channelEventFlow by inject()
+
+ override fun onSetup(
+ messenger: BinaryMessenger,
+ channelModel: ChannelMainModel?
+ ) {
+ ChannelMainModel.setUp(messenger, channelModel)
+ channelStateFlow.zip(model.state.map { getState(it) })
+ channelEventFlow.zip(model.event.map { getEvent(it) })
+ }
+
+ override fun resetEvent() {
+ model.event.value = Startup
+ }
+
+ override fun initState() {
+ model.initState()
+ }
+
+ override fun filterLanguage(language: String, isSelected: Boolean) {
+ model.filterLanguage(language, isSelected)
+ }
+
+ override fun filterScope(scope: String) {
+ model.filterScope(scope)
+ }
+
+ override fun logOut() {
+ model.logOut()
+ }
+
+ private fun getState(viewState: MainViewState): ChannelMainModelStateData {
+ return ChannelMainModelStateData(
+ state = viewState.toModelState(),
+ isLoading = viewState is Loading,
+ data = (viewState as? Loaded)?.snippets?.toModelData(),
+ filter = (viewState as? Loaded)?.filters?.toModelFilter(),
+ )
+ }
+
+ private fun getEvent(viewEvent: MainEvent): ChannelMainModelEventData {
+ return ChannelMainModelEventData(
+ event = viewEvent.toModelEvent(),
+ message = (viewEvent as? Alert)?.message,
+ )
+ }
+
+ private fun MainEvent.toModelEvent() =
+ when (this) {
+ is Alert -> ChannelMainModelEvent.ALERT
+ is Logout -> ChannelMainModelEvent.LOGOUT
+ else -> ChannelMainModelEvent.NONE
+ }
+
+ private fun MainViewState.toModelState() =
+ when (this) {
+ Loading -> ChannelModelState.LOADING
+ is Loaded -> ChannelModelState.LOADED
+ is Error -> ChannelModelState.ERROR
+ }
+
+ private fun List.toModelData() = map { it.toModelData() }
+
+ private fun SnippetFilters.toModelFilter(): ChannelSnippetFilter {
+ return ChannelSnippetFilter(
+ languages = languages,
+ selectedLanguages = selectedLanguages,
+ scopes = scopes,
+ selectedScope = selectedScope,
+ )
+ }
+}
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/bridge/session/SessionModel.kt b/app/src/main/java/dev/snipme/snipmeapp/channel/session/SessionModel.kt
similarity index 77%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/bridge/session/SessionModel.kt
rename to app/src/main/java/dev/snipme/snipmeapp/channel/session/SessionModel.kt
index 2474e90..e2c44ce 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/bridge/session/SessionModel.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/channel/session/SessionModel.kt
@@ -1,11 +1,11 @@
-package pl.tkadziolka.snipmeandroid.bridge.session
+package dev.snipme.snipmeapp.channel.session
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.schedulers.Schedulers
-import pl.tkadziolka.snipmeandroid.domain.auth.LogoutUserUseCase
-import pl.tkadziolka.snipmeandroid.util.extension.inProgress
+import dev.snipme.snipmeapp.domain.auth.LogoutUserUseCase
+import dev.snipme.snipmeapp.util.extension.inProgress
class SessionModel(
private val logout: LogoutUserUseCase
diff --git a/app/src/main/java/dev/snipme/snipmeapp/di/ChannelModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/ChannelModule.kt
new file mode 100644
index 0000000..e5e49a7
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/ChannelModule.kt
@@ -0,0 +1,18 @@
+package dev.snipme.snipmeapp.di
+
+import dev.snipme.snipmeapp.channel.FlowChannelEventStreamHandler
+import dev.snipme.snipmeapp.channel.FlowChannelStateStreamHandler
+import dev.snipme.snipmeapp.channel.details.DetailsModel
+import dev.snipme.snipmeapp.channel.login.LoginModel
+import dev.snipme.snipmeapp.channel.main.MainModel
+import dev.snipme.snipmeapp.channel.session.SessionModel
+import org.koin.dsl.module
+
+internal val channelModule = module {
+ single { FlowChannelStateStreamHandler() }
+ single { FlowChannelEventStreamHandler() }
+ single { SessionModel(get()) }
+ single { LoginModel(get(), get(), get()) }
+ single { MainModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
+ single { DetailsModel(get(), get(), get(), get(), get(), get(), get(), get(), get()) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/di/KoinConfig.kt b/app/src/main/java/dev/snipme/snipmeapp/di/KoinConfig.kt
similarity index 66%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/di/KoinConfig.kt
rename to app/src/main/java/dev/snipme/snipmeapp/di/KoinConfig.kt
index 99e88f6..001117a 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/di/KoinConfig.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/KoinConfig.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.di
+package dev.snipme.snipmeapp.di
val koinModules = listOf(
mapperFilterModule,
@@ -9,7 +9,5 @@ val koinModules = listOf(
utilModule,
useCaseModule,
interactorModule,
- navigatorModule,
- viewModelModule,
- modelModule
+ channelModule
)
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/di/MapperFilterModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/MapperFilterModule.kt
new file mode 100644
index 0000000..e6fc98d
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/MapperFilterModule.kt
@@ -0,0 +1,10 @@
+package dev.snipme.snipmeapp.di
+
+import org.koin.dsl.module
+import dev.snipme.snipmeapp.domain.language.AvailableLanguageFilter
+import dev.snipme.snipmeapp.domain.snippets.SnippetResponseMapper
+
+internal val mapperFilterModule = module {
+ factory { SnippetResponseMapper() }
+ factory { AvailableLanguageFilter() }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/di/NetworkModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/NetworkModule.kt
similarity index 92%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/di/NetworkModule.kt
rename to app/src/main/java/dev/snipme/snipmeapp/di/NetworkModule.kt
index 858ab54..a306688 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/di/NetworkModule.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/NetworkModule.kt
@@ -1,12 +1,12 @@
-package pl.tkadziolka.snipmeandroid.di
+package dev.snipme.snipmeapp.di
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level.BASIC
import okhttp3.logging.HttpLoggingInterceptor.Level.BODY
import org.koin.dsl.module
-import pl.tkadziolka.snipmeandroid.BuildConfig
-import pl.tkadziolka.snipmeandroid.util.AuthInterceptor
+import dev.snipme.snipmeapp.BuildConfig
+import dev.snipme.snipmeapp.util.AuthInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.moshi.MoshiConverterFactory
@@ -63,7 +63,7 @@ internal val networkModule = module {
single {
Retrofit.Builder()
- .client(get())
+ .client(get())
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/di/PreferenceModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/PreferenceModule.kt
similarity index 54%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/di/PreferenceModule.kt
rename to app/src/main/java/dev/snipme/snipmeapp/di/PreferenceModule.kt
index 8a9d591..5a63f08 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/di/PreferenceModule.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/PreferenceModule.kt
@@ -1,9 +1,9 @@
-package pl.tkadziolka.snipmeandroid.di
+package dev.snipme.snipmeapp.di
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
-import pl.tkadziolka.snipmeandroid.infrastructure.local.AuthPreferences
-import pl.tkadziolka.snipmeandroid.util.PreferencesUtil
+import dev.snipme.snipmeapp.infrastructure.local.AuthPreferences
+import dev.snipme.snipmeapp.util.PreferencesUtil
val preferenceModule = module {
single { PreferencesUtil(androidContext()) }
diff --git a/app/src/main/java/dev/snipme/snipmeapp/di/RepositoryModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/RepositoryModule.kt
new file mode 100644
index 0000000..5a8e567
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/RepositoryModule.kt
@@ -0,0 +1,21 @@
+package dev.snipme.snipmeapp.di
+
+import org.koin.dsl.module
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepositoryReal
+import dev.snipme.snipmeapp.domain.repository.language.LanguageRepository
+import dev.snipme.snipmeapp.domain.repository.language.LanguageRepositoryReal
+import dev.snipme.snipmeapp.domain.repository.networkstate.NetworkStateRepository
+import dev.snipme.snipmeapp.domain.repository.networkstate.NetworkStateRepositoryReal
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepositoryReal
+import dev.snipme.snipmeapp.domain.repository.user.UserRepository
+import dev.snipme.snipmeapp.domain.repository.user.UserRepositoryReal
+
+internal val repositoryModule = module {
+ single { NetworkStateRepositoryReal() }
+ single { AuthRepositoryReal(get(), get(), get()) }
+ single { UserRepositoryReal(get(), get()) }
+ single { SnippetRepositoryReal(get(), get(), get()) }
+ single { LanguageRepositoryReal(get(), get(), get()) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/di/ServiceModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/ServiceModule.kt
new file mode 100644
index 0000000..b7c9db7
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/ServiceModule.kt
@@ -0,0 +1,28 @@
+package dev.snipme.snipmeapp.di
+
+import androidx.room.Room
+import dev.snipme.snipmeapp.infrastructure.local.AppDatabase
+import dev.snipme.snipmeapp.infrastructure.local.SnippetDao
+import dev.snipme.snipmeapp.infrastructure.local.UserDao
+import org.koin.dsl.module
+import dev.snipme.snipmeapp.infrastructure.remote.*
+import retrofit2.Retrofit
+
+internal val serviceModule = module {
+ single { get().create(AuthService::class.java) }
+ single { get().create(UserService::class.java) }
+ single { get().create(SnippetService::class.java) }
+ single { get().create(LanguageService::class.java) }
+ single { get().create(ShareService::class.java) }
+
+
+ single {
+ Room.databaseBuilder(
+ get(), AppDatabase::class.java, "app_database"
+ ).createFromAsset("app_database.db").build()
+ }
+
+ single { get().userDao() }
+ single { get().snippetDao() }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/di/UseCaseModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/UseCaseModule.kt
new file mode 100644
index 0000000..bec68fc
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/UseCaseModule.kt
@@ -0,0 +1,63 @@
+package dev.snipme.snipmeapp.di
+
+import org.koin.dsl.module
+import dev.snipme.snipmeapp.domain.auth.*
+import dev.snipme.snipmeapp.domain.clipboard.AddToClipboardUseCase
+import dev.snipme.snipmeapp.domain.clipboard.GetFromClipboardUseCase
+import dev.snipme.snipmeapp.domain.language.GetLanguagesUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.reaction.GetTargetUserReactionUseCase
+import dev.snipme.snipmeapp.domain.reaction.SetUserReactionUseCase
+import dev.snipme.snipmeapp.domain.share.ShareSnippetUseCase
+import dev.snipme.snipmeapp.domain.snippet.*
+import dev.snipme.snipmeapp.domain.filter.FilterSnippetsByLanguageUseCase
+import dev.snipme.snipmeapp.domain.filter.FilterSnippetsByScopeUseCase
+import dev.snipme.snipmeapp.domain.filter.GetLanguageFiltersUseCase
+import dev.snipme.snipmeapp.domain.filter.UpdateSnippetFiltersLanguageUseCase
+import dev.snipme.snipmeapp.domain.snippets.GetSnippetsUseCase
+import dev.snipme.snipmeapp.domain.snippets.HasMoreSnippetPagesUseCase
+import dev.snipme.snipmeapp.domain.user.GetSingleUserUseCase
+
+internal val useCaseModule = module {
+ // Base
+ factory { CheckNetworkAvailableUseCase(get()) }
+ // Auth
+ factory { IdentifyUserUseCase(get()) }
+ factory { InitialLoginUseCase(get()) }
+ factory { LoginUseCase(get()) }
+ factory { RegisterUseCase(get(), get()) }
+ factory { LogoutUserUseCase(get()) }
+ factory { AuthorizationUseCase(get()) }
+ // User
+ factory { GetSingleUserUseCase(get(), get(), get(), get()) }
+ // Snippet
+ factory { GetSnippetsUseCase(get(), get(), get()) }
+ factory { GetSingleSnippetUseCase(get(), get(), get()) }
+ factory { HasMoreSnippetPagesUseCase(get(), get(), get()) }
+ factory { CreateSnippetUseCase(get(), get(), get()) }
+ factory { UpdateSnippetUseCase(get(), get(), get()) }
+ factory { ObserveUpdatedSnippetPageUseCase(get()) }
+ factory { ObserveSnippetUpdatesUseCase(get()) }
+ factory { GetTargetUserReactionUseCase() }
+ factory { SetUserReactionUseCase(get(), get(), get(), get()) }
+ factory { DeleteSnippetUseCase(get()) }
+ // Language
+ factory { GetLanguagesUseCase(get(), get(), get()) }
+ // Share
+ factory { ShareSnippetUseCase(get()) }
+ // Clipboard
+ single { AddToClipboardUseCase(get()) }
+ factory { GetFromClipboardUseCase(get()) }
+ // Save
+ factory { SaveSnippetUseCase(get()) }
+ // Filter
+ factory { GetLanguageFiltersUseCase() }
+ factory { FilterSnippetsByLanguageUseCase() }
+ factory { FilterSnippetsByScopeUseCase() }
+ factory { UpdateSnippetFiltersLanguageUseCase() }
+}
+
+internal val interactorModule = module {
+ factory { LoginInteractor(get(), get(), get()) }
+ factory { EditInteractor(get(), get(), get(), get(), get()) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/di/UtilModule.kt b/app/src/main/java/dev/snipme/snipmeapp/di/UtilModule.kt
new file mode 100644
index 0000000..89d5bd9
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/di/UtilModule.kt
@@ -0,0 +1,21 @@
+package dev.snipme.snipmeapp.di
+
+import android.content.ClipboardManager
+import android.content.Context.CLIPBOARD_SERVICE
+import dev.snipme.snipmeapp.AppService
+import dev.snipme.snipmeapp.BuildConfig
+import dev.snipme.snipmeapp.domain.error.DebugErrorHandler
+import dev.snipme.snipmeapp.domain.error.SafeErrorHandler
+import dev.snipme.snipmeapp.domain.message.ErrorMessages
+import dev.snipme.snipmeapp.domain.message.RealValidationMessages
+import dev.snipme.snipmeapp.domain.message.ValidationMessages
+import org.koin.android.ext.koin.androidApplication
+import org.koin.dsl.module
+
+internal val utilModule = module {
+ factory { if (BuildConfig.DEBUG) DebugErrorHandler() else SafeErrorHandler() }
+ factory { ErrorMessages(get()) }
+ factory { RealValidationMessages(get()) }
+ single { androidApplication().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager }
+ single { AppService(androidApplication()) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/AuthorizationUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/AuthorizationUseCase.kt
similarity index 70%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/AuthorizationUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/auth/AuthorizationUseCase.kt
index a67605f..32ad5ff 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/AuthorizationUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/AuthorizationUseCase.kt
@@ -1,8 +1,8 @@
-package pl.tkadziolka.snipmeandroid.domain.auth
+package dev.snipme.snipmeapp.domain.auth
import io.reactivex.Completable
-import pl.tkadziolka.snipmeandroid.domain.error.exception.SessionExpiredException
-import pl.tkadziolka.snipmeandroid.domain.repository.auth.AuthRepository
+import dev.snipme.snipmeapp.domain.error.exception.SessionExpiredException
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
// In future this should check if token is correct and up to date (refresh)
class AuthorizationUseCase(
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/auth/IdentifyUserUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/IdentifyUserUseCase.kt
new file mode 100644
index 0000000..86e01d7
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/IdentifyUserUseCase.kt
@@ -0,0 +1,11 @@
+package dev.snipme.snipmeapp.domain.auth
+
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
+
+class IdentifyUserUseCase(
+ private val auth: AuthRepository,
+) {
+ operator fun invoke(login: String) =
+ auth.identify(login)
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/InitialLoginUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/InitialLoginUseCase.kt
similarity index 64%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/InitialLoginUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/auth/InitialLoginUseCase.kt
index ff2e915..0129e04 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/InitialLoginUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/InitialLoginUseCase.kt
@@ -1,8 +1,8 @@
-package pl.tkadziolka.snipmeandroid.domain.auth
+package dev.snipme.snipmeapp.domain.auth
import io.reactivex.Completable
-import pl.tkadziolka.snipmeandroid.domain.error.exception.NotAuthorizedException
-import pl.tkadziolka.snipmeandroid.domain.repository.auth.AuthRepository
+import dev.snipme.snipmeapp.domain.error.exception.NotAuthorizedException
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
class InitialLoginUseCase(private val auth: AuthRepository) {
operator fun invoke() = auth.getToken()
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/LoginInteractor.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/LoginInteractor.kt
similarity index 89%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/LoginInteractor.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/auth/LoginInteractor.kt
index 4735c8b..f8e5ba1 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/LoginInteractor.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/LoginInteractor.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.auth
+package dev.snipme.snipmeapp.domain.auth
class LoginInteractor(
private val identifyUserUseCase: IdentifyUserUseCase,
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/auth/LoginUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/LoginUseCase.kt
new file mode 100644
index 0000000..6153f63
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/LoginUseCase.kt
@@ -0,0 +1,15 @@
+package dev.snipme.snipmeapp.domain.auth
+
+import io.reactivex.Completable
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
+
+class LoginUseCase(
+ private val auth: AuthRepository,
+) {
+
+ operator fun invoke(login: String, password: String): Completable =
+ auth.login(login, password)
+ .flatMapCompletable { token -> auth.saveToken(token.toString()) }
+}
+
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/LogoutUserUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/LogoutUserUseCase.kt
similarity index 50%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/LogoutUserUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/auth/LogoutUserUseCase.kt
index 5eaded8..4ad59bc 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/auth/LogoutUserUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/LogoutUserUseCase.kt
@@ -1,6 +1,6 @@
-package pl.tkadziolka.snipmeandroid.domain.auth
+package dev.snipme.snipmeapp.domain.auth
-import pl.tkadziolka.snipmeandroid.domain.repository.auth.AuthRepository
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
class LogoutUserUseCase(private val repository: AuthRepository) {
operator fun invoke() = repository.clearToken()
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/auth/RegisterUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/RegisterUseCase.kt
new file mode 100644
index 0000000..7925204
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/auth/RegisterUseCase.kt
@@ -0,0 +1,19 @@
+package dev.snipme.snipmeapp.domain.auth
+
+import io.reactivex.Completable
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
+
+class RegisterUseCase(
+ private val auth: AuthRepository,
+ private val loginUseCase: LoginUseCase,
+) {
+ operator fun invoke(login: String, password: String, email: String): Completable =
+ register(login, password, email)
+
+ private fun register(login: String, password: String, email: String) =
+ auth.register(login, password, email).andThen(
+ loginUseCase(login, password)
+ )
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/clipboard/AddToClipboardUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/clipboard/AddToClipboardUseCase.kt
similarity index 84%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/clipboard/AddToClipboardUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/clipboard/AddToClipboardUseCase.kt
index dfe7942..b8bd405 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/clipboard/AddToClipboardUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/clipboard/AddToClipboardUseCase.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.clipboard
+package dev.snipme.snipmeapp.domain.clipboard
import android.content.ClipData
import android.content.ClipboardManager
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/clipboard/GetFromClipboardUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/clipboard/GetFromClipboardUseCase.kt
similarity index 88%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/clipboard/GetFromClipboardUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/clipboard/GetFromClipboardUseCase.kt
index 9595a79..82a5b37 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/clipboard/GetFromClipboardUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/clipboard/GetFromClipboardUseCase.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.clipboard
+package dev.snipme.snipmeapp.domain.clipboard
import android.content.ClipboardManager
import timber.log.Timber
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/DebugErrorHandler.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/DebugErrorHandler.kt
similarity index 92%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/DebugErrorHandler.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/DebugErrorHandler.kt
index f7b7eee..05b1076 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/DebugErrorHandler.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/DebugErrorHandler.kt
@@ -1,6 +1,6 @@
-package pl.tkadziolka.snipmeandroid.domain.error
+package dev.snipme.snipmeapp.domain.error
-import pl.tkadziolka.snipmeandroid.domain.error.exception.*
+import dev.snipme.snipmeapp.domain.error.exception.*
import retrofit2.HttpException
import timber.log.Timber
import java.io.IOException
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/error/ErrorHandler.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/ErrorHandler.kt
new file mode 100644
index 0000000..37ef1bd
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/ErrorHandler.kt
@@ -0,0 +1,7 @@
+package dev.snipme.snipmeapp.domain.error
+
+import dev.snipme.snipmeapp.domain.error.exception.SnipException
+
+interface ErrorHandler {
+ fun handle(throwable: Throwable): SnipException
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/SafeErrorHandler.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/SafeErrorHandler.kt
similarity index 90%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/SafeErrorHandler.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/SafeErrorHandler.kt
index 751e26d..d7ba903 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/SafeErrorHandler.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/SafeErrorHandler.kt
@@ -1,6 +1,6 @@
-package pl.tkadziolka.snipmeandroid.domain.error
+package dev.snipme.snipmeapp.domain.error
-import pl.tkadziolka.snipmeandroid.domain.error.exception.*
+import dev.snipme.snipmeapp.domain.error.exception.*
import retrofit2.HttpException
import java.io.IOException
import java.net.HttpURLConnection.*
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ConnectionException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ConnectionException.kt
similarity index 58%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ConnectionException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ConnectionException.kt
index c9021d4..269ac2a 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ConnectionException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ConnectionException.kt
@@ -1,3 +1,3 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
class ConnectionException(override val cause: Throwable? = null): SnipException()
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ContentNotFoundException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ContentNotFoundException.kt
similarity index 59%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ContentNotFoundException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ContentNotFoundException.kt
index bb43bad..8050ad1 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ContentNotFoundException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ContentNotFoundException.kt
@@ -1,3 +1,3 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
class ContentNotFoundException(override val cause: Throwable? = null): SnipException()
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ForbiddenActionException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ForbiddenActionException.kt
similarity index 59%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ForbiddenActionException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ForbiddenActionException.kt
index e098ec5..a081fdc 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/ForbiddenActionException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/ForbiddenActionException.kt
@@ -1,3 +1,3 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
class ForbiddenActionException(override val cause: Throwable? = null): SnipException()
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/NetworkNotAvailableException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/NetworkNotAvailableException.kt
similarity index 60%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/NetworkNotAvailableException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/NetworkNotAvailableException.kt
index add6c2e..01f50b0 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/NetworkNotAvailableException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/NetworkNotAvailableException.kt
@@ -1,3 +1,3 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
class NetworkNotAvailableException(override val cause: Throwable? = null): SnipException()
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/NotAuthorizedException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/NotAuthorizedException.kt
similarity index 59%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/NotAuthorizedException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/NotAuthorizedException.kt
index 61def1c..a916c7d 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/NotAuthorizedException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/NotAuthorizedException.kt
@@ -1,3 +1,3 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
class NotAuthorizedException(override val cause: Throwable? = null): SnipException()
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/RemoteException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/RemoteException.kt
similarity index 56%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/RemoteException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/RemoteException.kt
index a3a413d..172b4ca 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/RemoteException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/RemoteException.kt
@@ -1,3 +1,3 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
class RemoteException(override val cause: Throwable? = null): SnipException()
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/SessionExpiredException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/SessionExpiredException.kt
similarity index 59%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/SessionExpiredException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/SessionExpiredException.kt
index 9851a47..e7316a5 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/SessionExpiredException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/SessionExpiredException.kt
@@ -1,3 +1,3 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
class SessionExpiredException(override val cause: Throwable? = null): SnipException()
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/SnipException.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/SnipException.kt
similarity index 64%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/SnipException.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/SnipException.kt
index ec2b88b..0619fad 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/error/exception/SnipException.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/error/exception/SnipException.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.error.exception
+package dev.snipme.snipmeapp.domain.error.exception
import java.lang.Exception
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/filter/FilterSnippetsByLanguageUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/FilterSnippetsByLanguageUseCase.kt
new file mode 100644
index 0000000..a77ee72
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/FilterSnippetsByLanguageUseCase.kt
@@ -0,0 +1,10 @@
+package dev.snipme.snipmeapp.domain.filter
+
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+
+class FilterSnippetsByLanguageUseCase {
+ operator fun invoke(snippets: List, languages: List): List {
+ if (languages.contains(SNIPPET_FILTER_ALL)) return snippets
+ return snippets.filter { languages.contains(it.language.raw) }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/filter/FilterSnippetsByScopeUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/FilterSnippetsByScopeUseCase.kt
new file mode 100644
index 0000000..762110b
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/FilterSnippetsByScopeUseCase.kt
@@ -0,0 +1,11 @@
+package dev.snipme.snipmeapp.domain.filter
+
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+
+class FilterSnippetsByScopeUseCase {
+ operator fun invoke(snippets: List, scope: String): List {
+ if (scope == SNIPPET_FILTER_ALL) return snippets
+
+ return snippets.filter { it.isOwner && it.visibility.name.equals(scope, ignoreCase = true) }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/filter/GetLanguageFiltersUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/GetLanguageFiltersUseCase.kt
new file mode 100644
index 0000000..388444d
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/GetLanguageFiltersUseCase.kt
@@ -0,0 +1,18 @@
+package dev.snipme.snipmeapp.domain.filter
+
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+
+const val SNIPPET_FILTER_ALL = "All"
+
+class GetLanguageFiltersUseCase {
+
+ operator fun invoke(snippets: List): List {
+ return listOf(SNIPPET_FILTER_ALL) +
+ snippets.groupBy { it.language.raw }
+ .map { it.key to it.value.count() }
+ .sortedBy { it.second }.reversed()
+ .map { it.first }
+ .filter { it.isNotBlank() }
+ .distinct()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/filter/UpdateSnippetFiltersLanguageUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/UpdateSnippetFiltersLanguageUseCase.kt
new file mode 100644
index 0000000..3a72c99
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/filter/UpdateSnippetFiltersLanguageUseCase.kt
@@ -0,0 +1,24 @@
+package dev.snipme.snipmeapp.domain.filter
+
+import dev.snipme.snipmeapp.domain.snippets.SnippetFilters
+
+class UpdateSnippetFiltersLanguageUseCase {
+
+ operator fun invoke(
+ filter: SnippetFilters,
+ language: String,
+ isSelected: Boolean
+ ): SnippetFilters = when {
+ language == SNIPPET_FILTER_ALL ->
+ filter.copy(selectedLanguages = listOf(SNIPPET_FILTER_ALL))
+ isSelected.not() -> filter.copy(selectedLanguages = filter.selectedLanguages - language)
+ else ->
+ filter.copy(
+ selectedLanguages = (
+ filter.selectedLanguages
+ - SNIPPET_FILTER_ALL
+ + language
+ ).distinct()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/language/AvailableLanguageFilter.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/language/AvailableLanguageFilter.kt
similarity index 51%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/language/AvailableLanguageFilter.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/language/AvailableLanguageFilter.kt
index c80a760..24992ae 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/language/AvailableLanguageFilter.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/language/AvailableLanguageFilter.kt
@@ -1,7 +1,7 @@
-package pl.tkadziolka.snipmeandroid.domain.language
+package dev.snipme.snipmeapp.domain.language
-import pl.tkadziolka.snipmeandroid.domain.snippets.SnippetLanguageType
-import pl.tkadziolka.snipmeandroid.domain.snippets.SnippetLanguageMapper
+import dev.snipme.snipmeapp.domain.snippets.SnippetLanguageType
+import dev.snipme.snipmeapp.domain.snippets.SnippetLanguageMapper
class AvailableLanguageFilter {
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/language/GetLanguagesUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/language/GetLanguagesUseCase.kt
new file mode 100644
index 0000000..673c3a0
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/language/GetLanguagesUseCase.kt
@@ -0,0 +1,17 @@
+package dev.snipme.snipmeapp.domain.language
+
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.language.LanguageRepository
+import dev.snipme.snipmeapp.util.extension.mapItems
+
+class GetLanguagesUseCase(
+ private val auth: AuthorizationUseCase,
+ private val networkState: CheckNetworkAvailableUseCase,
+ private val language: LanguageRepository
+) {
+ operator fun invoke() =
+ auth()
+ .andThen(networkState())
+ .andThen(language.languages().mapItems { it.name })
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/language/SnippetLanguage.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/language/SnippetLanguage.kt
new file mode 100644
index 0000000..8668927
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/language/SnippetLanguage.kt
@@ -0,0 +1,7 @@
+package dev.snipme.snipmeapp.domain.language
+
+import dev.snipme.snipmeapp.infrastructure.model.response.LanguageResponse
+
+data class SnippetLanguage(val name: String)
+
+fun LanguageResponse.toLanguage(): SnippetLanguage = SnippetLanguage(name)
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/ErrorMessages.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/message/ErrorMessages.kt
similarity index 88%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/ErrorMessages.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/message/ErrorMessages.kt
index 565d47f..82acd29 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/ErrorMessages.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/message/ErrorMessages.kt
@@ -1,8 +1,8 @@
-package pl.tkadziolka.snipmeandroid.domain.message
+package dev.snipme.snipmeapp.domain.message
import android.content.Context
-import pl.tkadziolka.snipmeandroid.R
-import pl.tkadziolka.snipmeandroid.domain.error.exception.*
+import dev.snipme.snipmeapp.R
+import dev.snipme.snipmeapp.domain.error.exception.*
class ErrorMessages(context: Context) {
private val res = context.resources
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/RealValidationMessages.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/message/RealValidationMessages.kt
similarity index 94%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/RealValidationMessages.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/message/RealValidationMessages.kt
index 8711fff..5e67c01 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/RealValidationMessages.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/message/RealValidationMessages.kt
@@ -1,7 +1,7 @@
-package pl.tkadziolka.snipmeandroid.domain.message
+package dev.snipme.snipmeapp.domain.message
import android.content.Context
-import pl.tkadziolka.snipmeandroid.R
+import dev.snipme.snipmeapp.R
class RealValidationMessages(context: Context): ValidationMessages {
private val res = context.resources
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/ValidationMessages.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/message/ValidationMessages.kt
similarity index 90%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/ValidationMessages.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/message/ValidationMessages.kt
index d72162a..0c2dbce 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/message/ValidationMessages.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/message/ValidationMessages.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.message
+package dev.snipme.snipmeapp.domain.message
interface ValidationMessages {
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/network/CheckNetworkAvailableUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/network/CheckNetworkAvailableUseCase.kt
similarity index 67%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/network/CheckNetworkAvailableUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/network/CheckNetworkAvailableUseCase.kt
index 0fdf9d4..208a91f 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/network/CheckNetworkAvailableUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/network/CheckNetworkAvailableUseCase.kt
@@ -1,8 +1,8 @@
-package pl.tkadziolka.snipmeandroid.domain.network
+package dev.snipme.snipmeapp.domain.network
import io.reactivex.Completable
-import pl.tkadziolka.snipmeandroid.domain.error.exception.NetworkNotAvailableException
-import pl.tkadziolka.snipmeandroid.domain.repository.networkstate.NetworkStateRepository
+import dev.snipme.snipmeapp.domain.error.exception.NetworkNotAvailableException
+import dev.snipme.snipmeapp.domain.repository.networkstate.NetworkStateRepository
class CheckNetworkAvailableUseCase(private val networkStateRepository: NetworkStateRepository) {
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/reaction/GetTargetUserReactionUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/GetTargetUserReactionUseCase.kt
similarity index 67%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/reaction/GetTargetUserReactionUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/reaction/GetTargetUserReactionUseCase.kt
index 8333e1e..9547c39 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/reaction/GetTargetUserReactionUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/GetTargetUserReactionUseCase.kt
@@ -1,6 +1,6 @@
-package pl.tkadziolka.snipmeandroid.domain.reaction
+package dev.snipme.snipmeapp.domain.reaction
-import pl.tkadziolka.snipmeandroid.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.snippets.Snippet
class GetTargetUserReactionUseCase {
operator fun invoke(snippet: Snippet, reaction: UserReaction) =
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/SetUserReactionUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/SetUserReactionUseCase.kt
new file mode 100644
index 0000000..855251e
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/SetUserReactionUseCase.kt
@@ -0,0 +1,25 @@
+package dev.snipme.snipmeapp.domain.reaction
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.user.GetSingleUserUseCase
+
+class SetUserReactionUseCase(
+ private val auth: AuthorizationUseCase,
+ private val repository: SnippetRepository,
+ private val getTargetReaction: GetTargetUserReactionUseCase,
+ private val getSingleUser: GetSingleUserUseCase
+) {
+ operator fun invoke(snippet: Snippet, reaction: UserReaction): Single {
+ val targetReaction = getTargetReaction(snippet, reaction)
+ return auth()
+ .andThen(getSingleUser())
+ .flatMap { user ->
+ repository.reaction(snippet.uuid, user.id, targetReaction)
+ .andThen(repository.snippet(snippet.uuid, user.id))
+ .doOnSuccess { repository.updateListener.onNext(it) }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/UserReaction.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/UserReaction.kt
new file mode 100644
index 0000000..dc53fac
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/reaction/UserReaction.kt
@@ -0,0 +1,7 @@
+package dev.snipme.snipmeapp.domain.reaction
+
+enum class UserReaction {
+ DISLIKE,
+ NONE,
+ LIKE
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/auth/AuthRepository.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/auth/AuthRepository.kt
similarity index 59%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/auth/AuthRepository.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/repository/auth/AuthRepository.kt
index 2dfa1e6..ccc413d 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/auth/AuthRepository.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/auth/AuthRepository.kt
@@ -1,17 +1,17 @@
-package pl.tkadziolka.snipmeandroid.domain.repository.auth
+package dev.snipme.snipmeapp.domain.repository.auth
import io.reactivex.Completable
import io.reactivex.Maybe
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.RegisterUserResponse
+import dev.snipme.snipmeapp.infrastructure.model.response.RegisterUserResponse
interface AuthRepository {
fun identify(login: String): Single
- fun login(login: String, password: String): Single
+ fun login(login: String, password: String): Single
- fun register(login: String, password: String, email: String): Single
+ fun register(login: String, password: String, email: String): Completable
fun saveToken(token: String): Completable
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/auth/AuthRepositoryReal.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/auth/AuthRepositoryReal.kt
similarity index 52%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/auth/AuthRepositoryReal.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/repository/auth/AuthRepositoryReal.kt
index d99239a..d17d49e 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/auth/AuthRepositoryReal.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/auth/AuthRepositoryReal.kt
@@ -1,32 +1,39 @@
-package pl.tkadziolka.snipmeandroid.domain.repository.auth
+package dev.snipme.snipmeapp.domain.repository.auth
+import android.util.Log
import io.reactivex.Completable
import io.reactivex.Maybe
-import pl.tkadziolka.snipmeandroid.domain.error.ErrorHandler
-import pl.tkadziolka.snipmeandroid.infrastructure.local.AuthPreferences
-import pl.tkadziolka.snipmeandroid.infrastructure.model.request.IdentifyUserRequest
-import pl.tkadziolka.snipmeandroid.infrastructure.model.request.LoginUserRequest
-import pl.tkadziolka.snipmeandroid.infrastructure.model.request.RegisterUserRequest
-import pl.tkadziolka.snipmeandroid.infrastructure.remote.AuthService
-import pl.tkadziolka.snipmeandroid.util.extension.mapError
+import dev.snipme.snipmeapp.domain.error.ErrorHandler
+import dev.snipme.snipmeapp.infrastructure.local.AuthPreferences
+import dev.snipme.snipmeapp.infrastructure.local.UserEntry
+import dev.snipme.snipmeapp.infrastructure.local.UserDao
+import dev.snipme.snipmeapp.util.extension.mapError
+import io.reactivex.Single
class AuthRepositoryReal(
private val errorHandler: ErrorHandler,
- private val service: AuthService,
+ private val service: UserDao,
private val prefs: AuthPreferences
) : AuthRepository {
override fun identify(login: String) =
- service.identify(IdentifyUserRequest(login))
+ service.identify(login)
.mapError { errorHandler.handle(it) }
+ .map { it -> it > 0 }
+
override fun login(login: String, password: String) =
- service.login(LoginUserRequest(login, password))
+ service.login(login, password)
.mapError { errorHandler.handle(it) }
- .map { it.token }
+ .map { it }
override fun register(login: String, password: String, email: String) =
- service.register(RegisterUserRequest(login, password, email))
+ service.register(UserEntry(
+ email = email,
+ password = password,
+ login = email.substring(0, email.indexOf('@')),
+ photo = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRrRHyzylz9-x3vO04G9qyWdOwOjtfsmtaubQ&s"
+ ))
.mapError { errorHandler.handle(it) }
override fun saveToken(token: String) = Completable.fromCallable {
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/repository/language/LanguageRepository.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/language/LanguageRepository.kt
new file mode 100644
index 0000000..d236f8f
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/language/LanguageRepository.kt
@@ -0,0 +1,9 @@
+package dev.snipme.snipmeapp.domain.repository.language
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.language.SnippetLanguage
+
+interface LanguageRepository {
+
+ fun languages(): Single>
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/repository/language/LanguageRepositoryReal.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/language/LanguageRepositoryReal.kt
new file mode 100644
index 0000000..bffde26
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/language/LanguageRepositoryReal.kt
@@ -0,0 +1,24 @@
+package dev.snipme.snipmeapp.domain.repository.language
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.error.ErrorHandler
+import dev.snipme.snipmeapp.domain.language.AvailableLanguageFilter
+import dev.snipme.snipmeapp.domain.language.SnippetLanguage
+import dev.snipme.snipmeapp.domain.language.toLanguage
+import dev.snipme.snipmeapp.infrastructure.remote.LanguageService
+import dev.snipme.snipmeapp.util.extension.filterItems
+import dev.snipme.snipmeapp.util.extension.mapError
+import dev.snipme.snipmeapp.util.extension.mapItems
+
+class LanguageRepositoryReal(
+ private val errorHandler: ErrorHandler,
+ private val service: LanguageService,
+ private val filterAvailable: AvailableLanguageFilter
+): LanguageRepository {
+
+ override fun languages(): Single> =
+ service.languages()
+ .mapError { errorHandler.handle(it) }
+ .filterItems { filterAvailable(it.name) }
+ .mapItems { it.toLanguage() }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/networkstate/NetworkStateRepository.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/networkstate/NetworkStateRepository.kt
similarity index 72%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/networkstate/NetworkStateRepository.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/repository/networkstate/NetworkStateRepository.kt
index 69142c3..5aac54a 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/networkstate/NetworkStateRepository.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/networkstate/NetworkStateRepository.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.repository.networkstate
+package dev.snipme.snipmeapp.domain.repository.networkstate
import io.reactivex.Observable
import io.reactivex.Single
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/networkstate/NetworkStateRepositoryReal.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/networkstate/NetworkStateRepositoryReal.kt
similarity index 85%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/networkstate/NetworkStateRepositoryReal.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/repository/networkstate/NetworkStateRepositoryReal.kt
index 35e2f69..19600c6 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/repository/networkstate/NetworkStateRepositoryReal.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/networkstate/NetworkStateRepositoryReal.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.repository.networkstate
+package dev.snipme.snipmeapp.domain.repository.networkstate
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import io.reactivex.Observable
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepository.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepository.kt
new file mode 100644
index 0000000..7790765
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepository.kt
@@ -0,0 +1,41 @@
+package dev.snipme.snipmeapp.domain.repository.snippet
+
+import io.reactivex.Completable
+import io.reactivex.Single
+import io.reactivex.subjects.BehaviorSubject
+import dev.snipme.snipmeapp.domain.reaction.UserReaction
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.snippets.SnippetScope
+import dev.snipme.snipmeapp.domain.snippets.SnippetVisibility
+
+interface SnippetRepository {
+
+ val updateListener: BehaviorSubject
+
+ fun snippets(userId: Int): Single>
+
+ fun snippet(uuid: String, userId: Int): Single
+
+ fun create(
+ title: String,
+ code: String,
+ language: String,
+ visibility: SnippetVisibility,
+ userId: Int
+ ): Single
+
+ fun update(
+ uuid: String,
+ title: String,
+ code: String,
+ language: String,
+ visibility: SnippetVisibility,
+ userId: Int
+ ): Single
+
+ fun count(): Single
+
+ fun reaction(uuid: String, userId: Int, reaction: UserReaction): Completable
+
+ fun delete(uuid: String): Completable
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepositoryReal.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepositoryReal.kt
new file mode 100644
index 0000000..9d8e86c
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepositoryReal.kt
@@ -0,0 +1,91 @@
+package dev.snipme.snipmeapp.domain.repository.snippet
+
+import dev.snipme.snipmeapp.domain.error.ErrorHandler
+import dev.snipme.snipmeapp.domain.reaction.UserReaction
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.snippets.SnippetResponseMapper
+import dev.snipme.snipmeapp.domain.snippets.SnippetVisibility
+import dev.snipme.snipmeapp.infrastructure.local.ReactionEntry
+import dev.snipme.snipmeapp.infrastructure.local.SnippetDao
+import dev.snipme.snipmeapp.infrastructure.local.SnippetEntry
+import dev.snipme.snipmeapp.util.extension.mapError
+import dev.snipme.snipmeapp.util.extension.mapItems
+import io.reactivex.Completable
+import io.reactivex.Single
+import io.reactivex.subjects.BehaviorSubject
+import java.util.Date
+
+const val PAGE_START = 0
+const val SNIPPET_PAGE_SIZE = 10
+const val ONE_SNIPPET = 1
+
+class SnippetRepositoryReal(
+ private val errorHandler: ErrorHandler,
+ private val service: SnippetDao,
+ private val mapper: SnippetResponseMapper
+) : SnippetRepository {
+ override val updateListener = BehaviorSubject.create()
+
+ override fun snippets(userId: Int): Single> =
+ service.snippets(userId)
+ .mapError { errorHandler.handle(it) }
+ .mapItems { mapper(it) }
+
+ override fun snippet(uuid: String, userId: Int): Single =
+ service.snippet(uuid.toInt(), userId).map { mapper(it) }
+ .mapError { errorHandler.handle(it) }
+
+ override fun create(
+ title: String,
+ code: String,
+ language: String,
+ visibility: SnippetVisibility,
+ userId: Int
+ ): Single {
+ return service.create(
+ SnippetEntry(
+ title = title,
+ code = code,
+ createdAt = Date().toString(),
+ modifiedAt = Date().toString(),
+ visibility = visibility.name,
+ ownerId = userId,
+ language = language,
+ )
+ )
+ .mapError { errorHandler.handle(it) }
+ .flatMap { newId ->
+ service.snippet(newId.toInt(), userId)
+ .mapError { errorHandler.handle(it) }
+ .map { mapper(it) }
+ }
+ }
+
+ override fun update(
+ uuid: String,
+ title: String,
+ code: String,
+ language: String,
+ visibility: SnippetVisibility,
+ userId: Int
+ ): Single =
+ service.update(uuid.toInt(), title, code, language, visibility.name)
+ .mapError { errorHandler.handle(it) }
+ .andThen(
+ service.snippet(uuid.toInt(), userId)
+ .mapError { errorHandler.handle(it) }
+ .map { mapper(it) }
+ )
+
+ override fun delete(uuid: String): Completable =
+ service.delete(uuid.toInt()).mapError { errorHandler.handle(it) }
+
+ override fun count() =
+ service.count()
+ .mapError { errorHandler.handle(it) }
+ .map { it }
+
+ override fun reaction(uuid: String, userId: Int, reaction: UserReaction): Completable =
+ service.reaction(ReactionEntry(snippetId = uuid.toInt(), userId = userId, reaction = reaction.ordinal.toShort()))
+ .mapError { errorHandler.handle(it) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepositoryTest.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepositoryTest.kt
new file mode 100644
index 0000000..8f6d7cd
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/snippet/SnippetRepositoryTest.kt
@@ -0,0 +1,167 @@
+//package dev.snipme.snipmeapp.domain.repository.snippet
+//
+//import android.text.SpannableString
+//import io.reactivex.Completable
+//import io.reactivex.Single
+//import io.reactivex.subjects.BehaviorSubject
+//import dev.snipme.snipmeapp.domain.error.ErrorHandler
+//import dev.snipme.snipmeapp.domain.reaction.UserReaction
+//import dev.snipme.snipmeapp.domain.snippets.*
+//import dev.snipme.snipmeapp.util.SyntaxHighlighter.getHighlighted
+//import dev.snipme.snipmeapp.util.extension.lines
+//import dev.snipme.snipmeapp.util.extension.newLineChar
+//import org.koin.core.definition.indexKey
+//import java.util.*
+//
+//private const val PREVIEW_COUNT = 5
+//
+//class SnippetRepositoryTest(private val errorHandler: ErrorHandler) : SnippetRepository {
+//
+// private val uuid
+// get() = UUID.randomUUID().toString()
+//
+// private val list by lazy {
+// List(25) {
+// Snippet(
+// id = it.toLong(),
+// title = "Snippet $it",
+// code = getMockCode(code),
+// language = getMockLanguage(),
+// visibility = SnippetVisibility.PUBLIC,
+// isOwner = true,
+// owner = Owner(it, "User $it"),
+// modifiedAt = Date(),
+// numberOfLikes = 5,
+// numberOfDislikes = 3,
+// userReaction = UserReaction.LIKE
+// )
+// }
+// }
+// override val updateListener: BehaviorSubject = BehaviorSubject.create()
+//
+//// override fun snippets(scope: SnippetScope, page: Int): Single> {
+//// return Single.just(list)
+//// .map { it.take(SNIPPET_PAGE_SIZE * page) }
+//// .onErrorResumeNext { throwable -> Single.error(errorHandler.handle(throwable)) }
+//// }
+////
+//// override fun snippet(id: String): Single = Single.just(list.find { it.id == id })
+////
+//// override fun create(
+//// title: String,
+//// code: String,
+//// language: String,
+//// visibility: SnippetVisibility
+//// ): Single = Single.just(
+//// Snippet(
+//// id = uuid,
+//// title = title,
+//// code = getMockCode(code),
+//// language = getMockLanguage(),
+//// visibility = SnippetVisibility.PUBLIC,
+//// isOwner = true,
+//// owner = Owner(0, "login"),
+//// modifiedAt = Date(),
+//// numberOfLikes = 0,
+//// numberOfDislikes = 0,
+//// userReaction = UserReaction.NONE
+//// )
+//// )
+////
+//// override fun update(
+//// uuid: String,
+//// title: String,
+//// code: String,
+//// language: String,
+//// visibility: SnippetVisibility
+//// ): Single = Single.just(
+//// Snippet(
+//// id = uuid,
+//// title = title,
+//// code = getMockCode(code),
+//// language = getMockLanguage(),
+//// visibility = SnippetVisibility.PUBLIC,
+//// isOwner = true,
+//// owner = Owner(0, "login"),
+//// modifiedAt = Date(),
+//// numberOfLikes = 5,
+//// numberOfDislikes = 3,
+//// userReaction = UserReaction.LIKE
+//// )
+//// )
+////
+//// override fun count(scope: SnippetScope): Single = Single.just(list.size)
+////
+//// override fun reaction(uuid: String, reaction: UserReaction): Completable =
+//// Completable.complete()
+////
+//// override fun delete(uuid: String): Completable = Completable.complete()
+////
+//// private fun getPreview(code: String): SpannableString {
+//// val preview = code.lines(PREVIEW_COUNT).joinToString(separator = newLineChar)
+//// return getHighlighted(preview)
+//// }
+//
+// private fun getMockCode(code: String) = SnippetCode(raw = code, highlighted = getPreview(code))
+//
+// private fun getMockLanguage() = SnippetLanguage(raw = "Java", type = SnippetLanguageType.JAVA)
+//
+// private val code =
+// """
+// /* Block comment */
+// import java.util.Date;
+// import static AnInterface.CONSTANT;
+// import static java.util.Date.parse;
+// import static SomeClass.staticField;
+// /**
+// * Doc comment here for SomeClass
+// * @param T type parameter
+// * @see Math#sin(double)
+// */
+// @Annotation (name=value)
+// public class SomeClass { // some comment
+// private T field = null;
+// private double unusedField = 12345.67890;
+// private UnknownType anotherString = "Another\nStrin\g";
+// public static int staticField = 0;
+// public final int instanceFinalField = 0;
+//
+// /**
+// * Semantic highlighting:
+// * Generated spectrum to pick colors for local variables and parameters:
+// * Color#1 SC1.1 SC1.2 SC1.3 SC1.4 Color#2 SC2.1 SC2.2 SC2.3 SC2.4 Color#3
+// * Color#3 SC3.1 SC3.2 SC3.3 SC3.4 Color#4 SC4.1 SC4.2 SC4.3 SC4.4 Color#5
+// * @param param1
+// * @param reassignedParam
+// * @param param2
+// * @param param3
+// */
+// public SomeClass(AnInterface param1, int[] reassignedParam,
+// int param2
+// int param3) {
+// int reassignedValue = this.staticField + param2 + param3;
+// long localVar1, localVar2, localVar3, localVar4;
+// int localVar = "IntelliJ"; // Error, incompatible types
+// System.out.println(anotherString + toString() + localVar);
+// long time = parse("1.2.3"); // Method is deprecated
+// new Thread().countStackFrames(); // Method is deprecated and marked for removal
+// reassignedValue ++;
+// field.run();
+// new SomeClass() {
+// {
+// int a = localVar;
+// }
+// };
+// reassignedParam = new ArrayList().toArray(new int[CONSTANT]);
+// }
+// }
+// enum AnEnum { CONST1, CONST2 }
+// interface AnInterface {
+// int CONSTANT = 2;
+// void method();
+// }
+// abstract class SomeAbstractClass {
+// protected int instanceField = staticField;
+// }
+// """.trimIndent()
+//}
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/repository/user/UserRepository.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/user/UserRepository.kt
new file mode 100644
index 0000000..f6d8032
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/user/UserRepository.kt
@@ -0,0 +1,8 @@
+package dev.snipme.snipmeapp.domain.repository.user
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.user.User
+
+interface UserRepository {
+ fun user(id: Int): Single
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/repository/user/UserRepositoryReal.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/user/UserRepositoryReal.kt
new file mode 100644
index 0000000..2e70c3c
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/repository/user/UserRepositoryReal.kt
@@ -0,0 +1,18 @@
+package dev.snipme.snipmeapp.domain.repository.user
+
+import dev.snipme.snipmeapp.domain.error.ErrorHandler
+import dev.snipme.snipmeapp.domain.user.User
+import dev.snipme.snipmeapp.domain.user.toUser
+import dev.snipme.snipmeapp.infrastructure.local.UserDao
+import dev.snipme.snipmeapp.util.extension.mapError
+import io.reactivex.Single
+
+class UserRepositoryReal(
+ private val errorHandler: ErrorHandler,
+ private val service: UserDao
+) : UserRepository {
+
+ override fun user(id: Int): Single = service.user(id)
+ .mapError { errorHandler.handle(it) }
+ .map { it.toUser() }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/share/ShareSnippetUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/share/ShareSnippetUseCase.kt
new file mode 100644
index 0000000..71dde64
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/share/ShareSnippetUseCase.kt
@@ -0,0 +1,15 @@
+package dev.snipme.snipmeapp.domain.share
+
+import dev.snipme.snipmeapp.AppService
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+
+class ShareSnippetUseCase(
+ private val appService: AppService
+) {
+
+ operator fun invoke(image: ByteArray, snippet: Snippet) {
+ val name = "${appService.getCurrentDateFormatted()}.png"
+ appService.storeFile(image, name, temp = true)
+ appService.launchShareIntent(snippet)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/share/ShareUser.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/share/ShareUser.kt
similarity index 70%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/share/ShareUser.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/share/ShareUser.kt
index a3625ba..7931943 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/share/ShareUser.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/share/ShareUser.kt
@@ -1,7 +1,7 @@
-package pl.tkadziolka.snipmeandroid.domain.share
+package dev.snipme.snipmeapp.domain.share
-import pl.tkadziolka.snipmeandroid.domain.user.User
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.SharePersonResponse
+import dev.snipme.snipmeapp.domain.user.User
+import dev.snipme.snipmeapp.infrastructure.model.response.SharePersonResponse
data class ShareUser(val user: User, val isShared: Boolean)
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/CreateSnippetUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/CreateSnippetUseCase.kt
new file mode 100644
index 0000000..ffc51d2
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/CreateSnippetUseCase.kt
@@ -0,0 +1,35 @@
+package dev.snipme.snipmeapp.domain.snippet
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.snippets.SnippetVisibility
+import dev.snipme.snipmeapp.domain.user.GetSingleUserUseCase
+
+class CreateSnippetUseCase(
+ private val auth: AuthorizationUseCase,
+ private val snippetRepository: SnippetRepository,
+ private val getSingleUser: GetSingleUserUseCase
+) {
+ operator fun invoke(
+ title: String,
+ code: String,
+ language: String,
+ visibility: SnippetVisibility = SnippetVisibility.PUBLIC
+ ): Single = auth()
+ .andThen(getSingleUser())
+ .flatMap { user ->
+ snippetRepository.create(
+ title = title,
+ code = code,
+ language = language,
+ visibility = visibility,
+ userId = user.id
+ )
+ }
+ .doOnSuccess { snippet ->
+ snippetRepository.updateListener.onNext(snippet)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/DeleteSnippetUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/DeleteSnippetUseCase.kt
new file mode 100644
index 0000000..4814d9f
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/DeleteSnippetUseCase.kt
@@ -0,0 +1,13 @@
+package dev.snipme.snipmeapp.domain.snippet
+
+import io.reactivex.Completable
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+
+class DeleteSnippetUseCase(private val repository: SnippetRepository) {
+
+ operator fun invoke(uuid: String): Completable =
+ repository
+ .delete(uuid)
+ .doOnComplete { repository.updateListener.onNext(Snippet.EMPTY.copy(uuid)) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippet/EditInteractor.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/EditInteractor.kt
similarity index 53%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippet/EditInteractor.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippet/EditInteractor.kt
index f23d20d..844994d 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippet/EditInteractor.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/EditInteractor.kt
@@ -1,9 +1,10 @@
-package pl.tkadziolka.snipmeandroid.domain.snippet
+package dev.snipme.snipmeapp.domain.snippet
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.domain.clipboard.GetFromClipboardUseCase
-import pl.tkadziolka.snipmeandroid.domain.language.GetLanguagesUseCase
-import pl.tkadziolka.snipmeandroid.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.clipboard.GetFromClipboardUseCase
+import dev.snipme.snipmeapp.domain.language.GetLanguagesUseCase
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.snippets.SnippetVisibility
class EditInteractor(
private val getLanguages: GetLanguagesUseCase,
@@ -19,8 +20,13 @@ class EditInteractor(
fun create(title: String, code: String, language: String): Single =
createSnippet(title, code, language)
- fun update(uuid: String, title: String, code: String, language: String): Single =
- updateSnippet(uuid, title, code, language)
+ fun update(
+ uuid: String,
+ title: String,
+ code: String,
+ language: String,
+ visibility: SnippetVisibility,
+ ): Single = updateSnippet(uuid, title, code, language, visibility)
fun getFromClipboard(): String? = fromClipboard()
}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/GetSingleSnippetUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/GetSingleSnippetUseCase.kt
new file mode 100644
index 0000000..1a6d0e7
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/GetSingleSnippetUseCase.kt
@@ -0,0 +1,20 @@
+package dev.snipme.snipmeapp.domain.snippet
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.user.GetSingleUserUseCase
+
+class GetSingleSnippetUseCase(
+ private val auth: AuthorizationUseCase,
+ private val getSingleUser: GetSingleUserUseCase,
+ private val repository: SnippetRepository
+) {
+
+ operator fun invoke(uuid: String): Single =
+ auth()
+ .andThen(getSingleUser())
+ .flatMap { repository.snippet(uuid, it.id) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/ObserveSnippetUpdatesUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/ObserveSnippetUpdatesUseCase.kt
new file mode 100644
index 0000000..ac7ea4b
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/ObserveSnippetUpdatesUseCase.kt
@@ -0,0 +1,9 @@
+package dev.snipme.snipmeapp.domain.snippet
+
+import io.reactivex.Observable
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+
+class ObserveSnippetUpdatesUseCase(private val repository: SnippetRepository) {
+ operator fun invoke(): Observable = repository.updateListener.share()
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippet/ObserveUpdatedSnippetPageUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/ObserveUpdatedSnippetPageUseCase.kt
similarity index 58%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippet/ObserveUpdatedSnippetPageUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippet/ObserveUpdatedSnippetPageUseCase.kt
index 64c983d..4f4c0b9 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippet/ObserveUpdatedSnippetPageUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/ObserveUpdatedSnippetPageUseCase.kt
@@ -1,34 +1,35 @@
-package pl.tkadziolka.snipmeandroid.domain.snippet
+package dev.snipme.snipmeapp.domain.snippet
import io.reactivex.Observable
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.domain.repository.snippet.SnippetRepository
-import pl.tkadziolka.snipmeandroid.domain.snippets.Snippet
-import pl.tkadziolka.snipmeandroid.domain.snippets.SnippetScope
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+import dev.snipme.snipmeapp.domain.snippets.SnippetScope
private const val START_PAGE = 1
class ObserveUpdatedSnippetPageUseCase(private val repository: SnippetRepository) {
- operator fun invoke(scope: SnippetScope): Observable =
+ operator fun invoke(scope: SnippetScope, userId: Int): Observable =
repository.updateListener
.skipWhile { it == Snippet.EMPTY }
.flatMapSingle { updated ->
- getPageWithUpdated(scope, updated, START_PAGE)
+ getPageWithUpdated(scope, updated, START_PAGE, userId)
}
private fun getPageWithUpdated(
scope: SnippetScope,
updated: Snippet,
- page: Int
- ): Single = repository.snippets(scope, page)
+ page: Int,
+ userId: Int
+ ): Single = repository.snippets(userId)
.map { snippets -> snippets.contains(updated.uuid) }
.flatMap { contains ->
if (contains) {
Single.just(page)
} else {
// Be aware of recursion here
- getPageWithUpdated(scope, updated, page + 1)
+ getPageWithUpdated(scope, updated, page + 1, userId)
}
}
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/SaveSnippetUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/SaveSnippetUseCase.kt
new file mode 100644
index 0000000..b1ed75a
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/SaveSnippetUseCase.kt
@@ -0,0 +1,15 @@
+package dev.snipme.snipmeapp.domain.snippet
+
+import dev.snipme.snipmeapp.AppService
+import dev.snipme.snipmeapp.domain.snippets.Snippet
+
+class SaveSnippetUseCase(
+ private val appService: AppService
+) {
+ operator fun invoke(image: ByteArray, snippet: Snippet): String {
+ val name = "${snippet.title.replace(" ", "_")}.png"
+ appService.storeFile(image, name, temp = false)
+ appService.storeMediaFile(image, name)
+ return name
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/UpdateSnippetUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/UpdateSnippetUseCase.kt
new file mode 100644
index 0000000..ed9c6af
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippet/UpdateSnippetUseCase.kt
@@ -0,0 +1,28 @@
+package dev.snipme.snipmeapp.domain.snippet
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.snippets.SnippetVisibility
+import dev.snipme.snipmeapp.domain.user.GetSingleUserUseCase
+
+class UpdateSnippetUseCase(
+ private val auth: AuthorizationUseCase,
+ private val getSingleUser: GetSingleUserUseCase,
+ private val repository: SnippetRepository
+) {
+ operator fun invoke(
+ uuid: String,
+ title: String,
+ code: String,
+ language: String,
+ visibility: SnippetVisibility,
+ ) = auth()
+ .andThen(getSingleUser())
+ .flatMap{repository.update(uuid, title, code, language, visibility, it.id)}
+ .doOnSuccess() {
+ repository.updateListener.onNext(it)
+ Single.just(it)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/GetSnippetsUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/GetSnippetsUseCase.kt
new file mode 100644
index 0000000..20e0106
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/GetSnippetsUseCase.kt
@@ -0,0 +1,22 @@
+package dev.snipme.snipmeapp.domain.snippets
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.user.GetSingleUserUseCase
+
+class GetSnippetsUseCase(
+ private val auth: AuthorizationUseCase,
+ private val repository: SnippetRepository,
+ private val getSingleUser: GetSingleUserUseCase
+) {
+ operator fun invoke(scope: SnippetScope, page: Int): Single> =
+ auth()
+ .andThen(getSingleUser())
+ .flatMap {
+ user ->
+ repository.snippets(user.id)
+ .map { list -> list.sortedByDescending { it.modifiedAt.time } }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/HasMoreSnippetPagesUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/HasMoreSnippetPagesUseCase.kt
similarity index 59%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/HasMoreSnippetPagesUseCase.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippets/HasMoreSnippetPagesUseCase.kt
index c742f5b..8bd123c 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/HasMoreSnippetPagesUseCase.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/HasMoreSnippetPagesUseCase.kt
@@ -1,10 +1,10 @@
-package pl.tkadziolka.snipmeandroid.domain.snippets
+package dev.snipme.snipmeapp.domain.snippets
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.domain.auth.AuthorizationUseCase
-import pl.tkadziolka.snipmeandroid.domain.network.CheckNetworkAvailableUseCase
-import pl.tkadziolka.snipmeandroid.domain.repository.snippet.SNIPPET_PAGE_SIZE
-import pl.tkadziolka.snipmeandroid.domain.repository.snippet.SnippetRepository
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.snippet.SNIPPET_PAGE_SIZE
+import dev.snipme.snipmeapp.domain.repository.snippet.SnippetRepository
private const val NEXT_PAGE = 1
@@ -17,7 +17,7 @@ class HasMoreSnippetPagesUseCase(
operator fun invoke(scope: SnippetScope, page: Int): Single =
auth()
.andThen(networkAvailable())
- .andThen(repository.count(scope).map { count -> page < pageCountFromOverall(count) })
+ .andThen(repository.count().map { count -> page < pageCountFromOverall(count) })
private fun pageCountFromOverall(count: Int): Int {
val nextPageOffset = count % SNIPPET_PAGE_SIZE
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/Snippet.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/Snippet.kt
similarity index 90%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/Snippet.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippets/Snippet.kt
index 2bf2dff..c5ade79 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/Snippet.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/Snippet.kt
@@ -1,7 +1,7 @@
-package pl.tkadziolka.snipmeandroid.domain.snippets
+package dev.snipme.snipmeapp.domain.snippets
import android.text.SpannableString
-import pl.tkadziolka.snipmeandroid.domain.reaction.UserReaction
+import dev.snipme.snipmeapp.domain.reaction.UserReaction
import java.util.*
data class Snippet(
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetFilters.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetFilters.kt
new file mode 100644
index 0000000..bc7847c
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetFilters.kt
@@ -0,0 +1,8 @@
+package dev.snipme.snipmeapp.domain.snippets
+
+data class SnippetFilters(
+ val languages: List,
+ val selectedLanguages: List,
+ val scopes: List,
+ val selectedScope: String
+)
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetLanguageMapper.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetLanguageMapper.kt
similarity index 92%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetLanguageMapper.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetLanguageMapper.kt
index 51b8c81..1dd812b 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetLanguageMapper.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetLanguageMapper.kt
@@ -1,6 +1,6 @@
-package pl.tkadziolka.snipmeandroid.domain.snippets
+package dev.snipme.snipmeapp.domain.snippets
-import pl.tkadziolka.snipmeandroid.domain.snippets.SnippetLanguageType.*
+import dev.snipme.snipmeapp.domain.snippets.SnippetLanguageType.*
object SnippetLanguageMapper {
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetLanguageType.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetLanguageType.kt
similarity index 94%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetLanguageType.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetLanguageType.kt
index 42ff4cd..77dd5ab 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetLanguageType.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetLanguageType.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.snippets
+package dev.snipme.snipmeapp.domain.snippets
enum class SnippetLanguageType(val fileExtension: String) {
C("c"),
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetResponseMapper.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetResponseMapper.kt
new file mode 100644
index 0000000..f999162
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetResponseMapper.kt
@@ -0,0 +1,59 @@
+package dev.snipme.snipmeapp.domain.snippets
+
+import android.text.SpannableString
+import dev.snipme.snipmeapp.domain.reaction.UserReaction
+import dev.snipme.snipmeapp.infrastructure.local.SnippetExtended
+import dev.snipme.snipmeapp.util.SyntaxHighlighter.getHighlighted
+import dev.snipme.snipmeapp.util.extension.lines
+import dev.snipme.snipmeapp.util.extension.newLineChar
+import dev.snipme.snipmeapp.util.extension.toDate
+import dev.snipme.snipmeapp.util.extension.toSnippetLanguage
+import java.util.*
+
+const val PREVIEW_COUNT = 5
+
+class SnippetResponseMapper {
+
+ operator fun invoke(response: SnippetExtended) = with(response.snippet) {
+ return@with Snippet(
+ uuid = id.toString(),
+ title = title,
+ code = getCode(code),
+ language = getLanguage(language),
+ visibility = getVisibility(visibility),
+ isOwner = response.isOwner,
+ owner = Owner(ownerId , response.ownerName),
+ modifiedAt = modifiedAt.toDate(),
+ numberOfLikes = response.numberOfLikes,
+ numberOfDislikes = response.numberOfDislikes,
+ userReaction = getUserReaction(response.userReaction)
+ )
+ }
+
+ private fun getUserReaction(value: String?) =
+ when {
+ value.equals("like", ignoreCase = true) -> UserReaction.LIKE
+ value.equals("dislike", ignoreCase = true) -> UserReaction.DISLIKE
+ else -> UserReaction.NONE
+ }
+
+ private fun getCode(code: String) = SnippetCode(
+ raw = code.orEmpty(),
+ highlighted = getPreview(code)
+ )
+
+ private fun getLanguage(language: String?) = SnippetLanguage(
+ raw = language.orEmpty(),
+ type = language.toSnippetLanguage()
+ )
+
+ private fun getPreview(code: String): SpannableString {
+ val preview = code.lines(PREVIEW_COUNT).joinToString(separator = newLineChar)
+ return getHighlighted(preview)
+ }
+
+ private fun getVisibility(visibility: String?): SnippetVisibility {
+ if (visibility == null) return SnippetVisibility.PRIVATE
+ return SnippetVisibility.valueOf(visibility)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetScope.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetScope.kt
similarity index 69%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetScope.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetScope.kt
index 14641c7..be5c944 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetScope.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetScope.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.snippets
+package dev.snipme.snipmeapp.domain.snippets
enum class SnippetScope {
ALL, PUBLIC, OWNED, SHARED_FOR;
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetVisibility.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetVisibility.kt
similarity index 50%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetVisibility.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetVisibility.kt
index 02865d1..ff41c28 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/snippets/SnippetVisibility.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/snippets/SnippetVisibility.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.domain.snippets
+package dev.snipme.snipmeapp.domain.snippets
enum class SnippetVisibility {
PUBLIC, PRIVATE
diff --git a/app/src/main/java/dev/snipme/snipmeapp/domain/user/GetSingleUserUseCase.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/user/GetSingleUserUseCase.kt
new file mode 100644
index 0000000..dc22e81
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/user/GetSingleUserUseCase.kt
@@ -0,0 +1,24 @@
+package dev.snipme.snipmeapp.domain.user
+
+import android.annotation.SuppressLint
+import dev.snipme.snipmeapp.domain.auth.AuthorizationUseCase
+import dev.snipme.snipmeapp.domain.network.CheckNetworkAvailableUseCase
+import dev.snipme.snipmeapp.domain.repository.auth.AuthRepository
+import dev.snipme.snipmeapp.domain.repository.user.UserRepository
+import io.reactivex.Single
+
+class GetSingleUserUseCase(
+ private val auth: AuthorizationUseCase,
+ private val networkAvailable: CheckNetworkAvailableUseCase,
+ private val repository: UserRepository,
+ private val authRepository: AuthRepository,
+) {
+ @SuppressLint("CheckResult")
+ operator fun invoke(): Single {
+ var token: Int = 0
+ authRepository.getToken().subscribe { value -> token = value.toInt() }
+ return auth()
+// .andThen(networkAvailable())
+ .andThen(repository.user(token))
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/user/User.kt b/app/src/main/java/dev/snipme/snipmeapp/domain/user/User.kt
similarity index 64%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/domain/user/User.kt
rename to app/src/main/java/dev/snipme/snipmeapp/domain/user/User.kt
index 082f4df..88804ca 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/domain/user/User.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/domain/user/User.kt
@@ -1,7 +1,8 @@
-package pl.tkadziolka.snipmeandroid.domain.user
+package dev.snipme.snipmeapp.domain.user
import androidx.annotation.VisibleForTesting
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.PersonResponse
+import dev.snipme.snipmeapp.infrastructure.local.UserEntry
+import dev.snipme.snipmeapp.infrastructure.model.response.PersonResponse
data class User(val id: Int, val login: String, val email: String, val photo: String) {
companion object {
@@ -15,4 +16,11 @@ fun PersonResponse.toUser() = User(
login = username ?: throw IllegalArgumentException("User must have a login!"),
email = email ?: "",
photo = photo ?: ""
+)
+
+fun UserEntry.toUser() = User(
+ id = id,
+ login = login,
+ email = email,
+ photo = photo
)
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/AppDatabase.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/AppDatabase.kt
new file mode 100644
index 0000000..e77bf49
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/AppDatabase.kt
@@ -0,0 +1,28 @@
+package dev.snipme.snipmeapp.infrastructure.local
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import android.content.Context
+
+@Database(entities = [UserEntry::class, SnippetEntry::class, ReactionEntry::class], version = 1)
+abstract class AppDatabase : RoomDatabase() {
+ abstract fun userDao(): UserDao
+ abstract fun snippetDao(): SnippetDao
+
+ companion object {
+ @Volatile
+ private var INSTANCE: AppDatabase? = null
+
+ fun getDatabase(context: Context): AppDatabase {
+ return INSTANCE ?: synchronized(this) {
+ val instance = Room.databaseBuilder(
+ context.applicationContext,
+ AppDatabase::class.java,
+ "app_database"
+ ).build()
+ INSTANCE = instance
+ instance
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/local/AuthPreferences.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/AuthPreferences.kt
similarity index 74%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/local/AuthPreferences.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/AuthPreferences.kt
index 5621c85..fae5b0c 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/local/AuthPreferences.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/AuthPreferences.kt
@@ -1,11 +1,10 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.local
+package dev.snipme.snipmeapp.infrastructure.local
-import pl.tkadziolka.snipmeandroid.util.PreferencesUtil
+import dev.snipme.snipmeapp.util.PreferencesUtil
private const val TOKEN_KEY = "7e3a40ea-32d2-4248-bcfb-297f2f41246e"
class AuthPreferences(private val prefs: PreferencesUtil) {
-
fun saveToken(token: String) {
prefs.save(TOKEN_KEY, token)
}
diff --git a/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/ReactionEntry.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/ReactionEntry.kt
new file mode 100644
index 0000000..c832293
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/ReactionEntry.kt
@@ -0,0 +1,33 @@
+package dev.snipme.snipmeapp.infrastructure.local
+
+import androidx.room.Entity
+import androidx.room.ForeignKey
+import androidx.room.Index
+import androidx.room.PrimaryKey
+
+@Entity(
+ tableName = "reactions",
+ foreignKeys = [
+ ForeignKey(
+ entity = UserEntry::class,
+ parentColumns = arrayOf("id"),
+ childColumns = arrayOf("userId"),
+ onUpdate = ForeignKey.CASCADE,
+ onDelete = ForeignKey.CASCADE
+ ),
+ ForeignKey(
+ entity = SnippetEntry::class,
+ parentColumns = arrayOf("id"),
+ childColumns = arrayOf("snippetId"),
+ onUpdate = ForeignKey.CASCADE,
+ onDelete = ForeignKey.CASCADE
+ ),
+ ],
+ indices = [Index(value = ["userId", "snippetId"], unique = true)]
+)
+data class ReactionEntry(
+ @PrimaryKey(true) val id: Int = 0,
+ val userId: Int,
+ val snippetId: Int,
+ val reaction: Short // 0 dislike, 1 none, 2 like
+)
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/SnippetDao.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/SnippetDao.kt
new file mode 100644
index 0000000..8f070fe
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/SnippetDao.kt
@@ -0,0 +1,72 @@
+package dev.snipme.snipmeapp.infrastructure.local
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import io.reactivex.Completable
+import io.reactivex.Single
+
+@Dao
+interface SnippetDao {
+ @Query(
+ """
+ SELECT s.*, u.login as ownerName,
+ CASE WHEN s.ownerId = :userId THEN 1 ELSE 0 END as isOwner,
+ CASE WHEN r.reaction = 0 THEN 'DISLIKE' ELSE CASE WHEN r.reaction = 2 THEN 'LIKE' ELSE 'NONE' END END as userReaction,
+ (Select Count(*) FROM reactions as r where r.snippetId = :uuid and reaction = 2) as numberOfLikes,
+ (Select Count(*) FROM reactions as r where r.snippetId = :uuid and reaction = 0) as numberOfDislikes
+ FROM snippets as s
+ INNER JOIN users as u ON s.ownerId = u.id
+ LEFT JOIN reactions as r ON r.userId = :userId and r.snippetId = :uuid
+ WHERE s.id = :uuid
+ """
+ )
+ fun snippet(uuid: Int, userId: Int): Single
+
+ @Query(
+ """
+ SELECT s.*, u.login as ownerName,
+ CASE WHEN s.ownerId = :userId THEN 1 ELSE 0 END as isOwner,
+ CASE WHEN r.reaction = 0 THEN "DISLIKE" ELSE CASE WHEN r.reaction = 2 THEN "LIKE" ELSE "NONE" END END as userReaction,
+ (Select Count(*) FROM reactions as r where r.snippetId = s.id and reaction = 2) as numberOfLikes,
+ (Select Count(*) FROM reactions as r where r.snippetId = s.id and reaction = 0) as numberOfDislikes
+ FROM snippets as s
+ INNER JOIN users as u ON s.ownerId = u.id
+ LEFT JOIN reactions as r ON r.userId = :userId and r.snippetId = s.id
+ """
+ )
+ fun snippets(userId: Int): Single>
+
+ @Query("SELECT COUNT(*) FROM snippets")
+ fun count(): Single
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun create(snippet: SnippetEntry): Single
+
+ @Query(
+ """
+ UPDATE snippets
+ SET title = :title,
+ code = :code,
+ modifiedAt = current_timestamp,
+ visibility = :visibility,
+ language = :language
+ WHERE id = :uuid
+ """
+ )
+ fun update(
+ uuid: Int,
+ title: String,
+ code: String,
+ visibility: String,
+ language: String,
+ ): Completable
+
+ @Query("DELETE FROM snippets WHERE id = :uuid")
+ fun delete(uuid: Int): Completable
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun reaction(reaction: ReactionEntry): Completable
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/SnippetEntity.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/SnippetEntity.kt
new file mode 100644
index 0000000..425f7c2
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/SnippetEntity.kt
@@ -0,0 +1,28 @@
+package dev.snipme.snipmeapp.infrastructure.local
+
+import androidx.room.Embedded
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+
+@Entity(tableName = "snippets")
+data class SnippetEntry(
+ @PrimaryKey(true) val id: Long = 0,
+ val title: String,
+ val code: String,
+ val createdAt: String,
+ val modifiedAt: String,
+ val visibility: String,
+ val ownerId: Int,
+ val language: String,
+)
+
+
+data class SnippetExtended(
+ @Embedded val snippet: SnippetEntry,
+ val ownerName: String,
+ val isOwner: Boolean,
+ val userReaction: String,
+ val numberOfLikes: Int,
+ val numberOfDislikes: Int,
+)
diff --git a/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/UserDao.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/UserDao.kt
new file mode 100644
index 0000000..ad72231
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/UserDao.kt
@@ -0,0 +1,24 @@
+package dev.snipme.snipmeapp.infrastructure.local
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import io.reactivex.Completable
+import io.reactivex.Single
+
+@Dao
+interface UserDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun register(user: UserEntry): Completable
+
+ @Query("SELECT id FROM users WHERE email = :email AND password = :password")
+ fun login(email: String, password: String): Single
+
+ @Query("SELECT COUNT(*) FROM users WHERE email = :email")
+ fun identify(email: String): Single
+
+ @Query("SELECT * FROM users WHERE id = :id")
+ fun user(id: Int) : Single
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/UserEntry.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/UserEntry.kt
new file mode 100644
index 0000000..7fee638
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/local/UserEntry.kt
@@ -0,0 +1,13 @@
+package dev.snipme.snipmeapp.infrastructure.local
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "users")
+data class UserEntry(
+ @PrimaryKey(true) val id: Int = 0,
+ val email: String,
+ val password: String,
+ val login: String,
+ val photo: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/SnippetPageResponse.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/SnippetPageResponse.kt
similarity index 60%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/SnippetPageResponse.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/SnippetPageResponse.kt
index 9064120..8a669c4 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/SnippetPageResponse.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/SnippetPageResponse.kt
@@ -1,7 +1,7 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model
+package dev.snipme.snipmeapp.infrastructure.model
import com.squareup.moshi.JsonClass
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.SnippetResponse
+import dev.snipme.snipmeapp.infrastructure.model.response.SnippetResponse
@JsonClass(generateAdapter = true)
data class SnippetPageResponse(
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/CreateSnippetRequest.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/CreateSnippetRequest.kt
similarity index 57%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/CreateSnippetRequest.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/CreateSnippetRequest.kt
index 6d57f20..a3412ab 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/CreateSnippetRequest.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/CreateSnippetRequest.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.request
+package dev.snipme.snipmeapp.infrastructure.model.request
import com.squareup.moshi.JsonClass
@@ -6,5 +6,6 @@ import com.squareup.moshi.JsonClass
data class CreateSnippetRequest(
val title: String,
val code: String,
- val language: String
+ val language: String,
+ val visibility: String
)
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/IdentifyUserRequest.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/IdentifyUserRequest.kt
similarity index 65%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/IdentifyUserRequest.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/IdentifyUserRequest.kt
index 341f5c0..b7246ec 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/IdentifyUserRequest.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/IdentifyUserRequest.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.request
+package dev.snipme.snipmeapp.infrastructure.model.request
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/LoginUserRequest.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/LoginUserRequest.kt
similarity index 68%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/LoginUserRequest.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/LoginUserRequest.kt
index 2a425dd..4dc20da 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/LoginUserRequest.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/LoginUserRequest.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.request
+package dev.snipme.snipmeapp.infrastructure.model.request
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/RateSnippetRequest.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/RateSnippetRequest.kt
similarity index 68%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/RateSnippetRequest.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/RateSnippetRequest.kt
index 733bfa8..dacbcab 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/RateSnippetRequest.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/RateSnippetRequest.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.request
+package dev.snipme.snipmeapp.infrastructure.model.request
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/RegisterUserRequest.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/RegisterUserRequest.kt
similarity index 71%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/RegisterUserRequest.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/RegisterUserRequest.kt
index 5aeea9b..cda564d 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/RegisterUserRequest.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/RegisterUserRequest.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.request
+package dev.snipme.snipmeapp.infrastructure.model.request
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/ShareSnippetRequest.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/ShareSnippetRequest.kt
similarity index 77%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/ShareSnippetRequest.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/ShareSnippetRequest.kt
index e9248af..5d011f6 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/request/ShareSnippetRequest.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/request/ShareSnippetRequest.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.request
+package dev.snipme.snipmeapp.infrastructure.model.request
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/LanguageResponse.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/LanguageResponse.kt
similarity index 64%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/LanguageResponse.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/LanguageResponse.kt
index ae992b0..b302c7c 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/LanguageResponse.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/LanguageResponse.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.response
+package dev.snipme.snipmeapp.infrastructure.model.response
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/PersonResponse.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/PersonResponse.kt
similarity index 85%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/PersonResponse.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/PersonResponse.kt
index 6cbfbaf..4d4aad1 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/PersonResponse.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/PersonResponse.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.response
+package dev.snipme.snipmeapp.infrastructure.model.response
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/RegisterUserResponse.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/RegisterUserResponse.kt
similarity index 87%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/RegisterUserResponse.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/RegisterUserResponse.kt
index 9bbaf54..3e2f976 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/RegisterUserResponse.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/RegisterUserResponse.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.response
+package dev.snipme.snipmeapp.infrastructure.model.response
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/SnippetResponse.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/SnippetResponse.kt
similarity index 89%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/SnippetResponse.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/SnippetResponse.kt
index 1821cf5..6864079 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/SnippetResponse.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/SnippetResponse.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.response
+package dev.snipme.snipmeapp.infrastructure.model.response
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/TokenResponse.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/TokenResponse.kt
similarity index 63%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/TokenResponse.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/TokenResponse.kt
index 15a6f1b..098ab33 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/model/response/TokenResponse.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/model/response/TokenResponse.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.model.response
+package dev.snipme.snipmeapp.infrastructure.model.response
import com.squareup.moshi.JsonClass
diff --git a/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/AuthService.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/AuthService.kt
new file mode 100644
index 0000000..a99525c
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/AuthService.kt
@@ -0,0 +1,21 @@
+package dev.snipme.snipmeapp.infrastructure.remote
+
+import io.reactivex.Single
+import dev.snipme.snipmeapp.infrastructure.model.request.IdentifyUserRequest
+import dev.snipme.snipmeapp.infrastructure.model.request.LoginUserRequest
+import dev.snipme.snipmeapp.infrastructure.model.request.RegisterUserRequest
+import dev.snipme.snipmeapp.infrastructure.model.response.RegisterUserResponse
+import dev.snipme.snipmeapp.infrastructure.model.response.TokenResponse
+import retrofit2.http.*
+
+interface AuthService {
+
+ @POST("check-if-user-exist/")
+ fun identify(@Body request: IdentifyUserRequest): Single
+
+ @POST("auth-token/")
+ fun login(@Body request: LoginUserRequest): Single
+
+ @POST("register/")
+ fun register(@Body request: RegisterUserRequest): Single
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/LanguageService.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/LanguageService.kt
similarity index 53%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/LanguageService.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/LanguageService.kt
index d9830a0..d7426c4 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/LanguageService.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/LanguageService.kt
@@ -1,7 +1,7 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.remote
+package dev.snipme.snipmeapp.infrastructure.remote
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.LanguageResponse
+import dev.snipme.snipmeapp.infrastructure.model.response.LanguageResponse
import retrofit2.http.GET
interface LanguageService {
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/ShareService.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/ShareService.kt
similarity index 64%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/ShareService.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/ShareService.kt
index f745b54..ea6ae7a 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/ShareService.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/ShareService.kt
@@ -1,9 +1,9 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.remote
+package dev.snipme.snipmeapp.infrastructure.remote
import io.reactivex.Completable
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.infrastructure.model.request.ShareSnippetRequest
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.SharePersonResponse
+import dev.snipme.snipmeapp.infrastructure.model.request.ShareSnippetRequest
+import dev.snipme.snipmeapp.infrastructure.model.response.SharePersonResponse
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/SnippetService.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/SnippetService.kt
similarity index 53%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/SnippetService.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/SnippetService.kt
index 87c5f80..8ce8dfa 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/SnippetService.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/SnippetService.kt
@@ -1,11 +1,11 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.remote
+package dev.snipme.snipmeapp.infrastructure.remote
import io.reactivex.Completable
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.infrastructure.model.SnippetPageResponse
-import pl.tkadziolka.snipmeandroid.infrastructure.model.request.CreateSnippetRequest
-import pl.tkadziolka.snipmeandroid.infrastructure.model.request.RateSnippetRequest
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.SnippetResponse
+import dev.snipme.snipmeapp.infrastructure.model.SnippetPageResponse
+import dev.snipme.snipmeapp.infrastructure.model.request.CreateSnippetRequest
+import dev.snipme.snipmeapp.infrastructure.model.request.RateSnippetRequest
+import dev.snipme.snipmeapp.infrastructure.model.response.SnippetResponse
import retrofit2.http.*
private const val PATH_ID = "id"
@@ -26,8 +26,14 @@ interface SnippetService {
fun create(@Body request: CreateSnippetRequest): Single
@PUT("snippet/{$PATH_ID}/")
- fun update(@Path(PATH_ID) id: String, @Body request: CreateSnippetRequest): Single
+ fun update(
+ @Path(PATH_ID) id: String,
+ @Body request: CreateSnippetRequest
+ ): Single
@POST("snippet-rate/")
fun rate(@Body request: RateSnippetRequest): Completable
+
+ @DELETE("snippet/{$PATH_ID}/")
+ fun delete(@Path(PATH_ID) id: String): Completable
}
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/UserService.kt b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/UserService.kt
similarity index 50%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/UserService.kt
rename to app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/UserService.kt
index 7e8dbc6..b856e69 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/infrastructure/remote/UserService.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/infrastructure/remote/UserService.kt
@@ -1,7 +1,7 @@
-package pl.tkadziolka.snipmeandroid.infrastructure.remote
+package dev.snipme.snipmeapp.infrastructure.remote
import io.reactivex.Single
-import pl.tkadziolka.snipmeandroid.infrastructure.model.response.PersonResponse
+import dev.snipme.snipmeapp.infrastructure.model.response.PersonResponse
import retrofit2.http.GET
interface UserService {
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/AuthInterceptor.kt b/app/src/main/java/dev/snipme/snipmeapp/util/AuthInterceptor.kt
similarity index 79%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/AuthInterceptor.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/AuthInterceptor.kt
index 02ebbed..f0154b0 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/AuthInterceptor.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/AuthInterceptor.kt
@@ -1,9 +1,9 @@
-package pl.tkadziolka.snipmeandroid.util
+package dev.snipme.snipmeapp.util
import okhttp3.Interceptor
import okhttp3.Response
-import pl.tkadziolka.snipmeandroid.BuildConfig
-import pl.tkadziolka.snipmeandroid.infrastructure.local.AuthPreferences
+import dev.snipme.snipmeapp.BuildConfig
+import dev.snipme.snipmeapp.infrastructure.local.AuthPreferences
import timber.log.Timber
private const val KEY_HEADER_AUTHORIZATION = "Authorization"
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/CrashReportingTree.kt b/app/src/main/java/dev/snipme/snipmeapp/util/CrashReportingTree.kt
similarity index 82%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/CrashReportingTree.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/CrashReportingTree.kt
index 6b38461..21e2b06 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/CrashReportingTree.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/CrashReportingTree.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.util
+package dev.snipme.snipmeapp.util
import timber.log.Timber
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/PreferencesUtil.kt b/app/src/main/java/dev/snipme/snipmeapp/util/PreferencesUtil.kt
similarity index 95%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/PreferencesUtil.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/PreferencesUtil.kt
index 87e7e46..6fabaa4 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/PreferencesUtil.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/PreferencesUtil.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.util
+package dev.snipme.snipmeapp.util
import android.content.Context
import android.content.Context.MODE_PRIVATE
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/SyntaxHighlighter.kt b/app/src/main/java/dev/snipme/snipmeapp/util/SyntaxHighlighter.kt
similarity index 92%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/SyntaxHighlighter.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/SyntaxHighlighter.kt
index 7ce203a..79046af 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/SyntaxHighlighter.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/SyntaxHighlighter.kt
@@ -1,20 +1,20 @@
-package pl.tkadziolka.snipmeandroid.util
+package dev.snipme.snipmeapp.util
import android.graphics.Color
import android.text.Spannable
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
import androidx.core.text.set
-import pl.tkadziolka.snipmeandroid.BuildConfig
-import pl.tkadziolka.snipmeandroid.util.SyntaxPhrases.commentTerminators
-import pl.tkadziolka.snipmeandroid.util.SyntaxPhrases.keywords
-import pl.tkadziolka.snipmeandroid.util.SyntaxPhrases.multilineCommentTerminators
-import pl.tkadziolka.snipmeandroid.util.SyntaxPhrases.textTerminators
-import pl.tkadziolka.snipmeandroid.util.SyntaxPhrases.wordTerminators
-import pl.tkadziolka.snipmeandroid.util.extension.containsDefault
-import pl.tkadziolka.snipmeandroid.util.extension.indicesOf
-import pl.tkadziolka.snipmeandroid.util.extension.lengthToEOF
-import pl.tkadziolka.snipmeandroid.util.extension.opaque
+import dev.snipme.snipmeapp.BuildConfig
+import dev.snipme.snipmeapp.util.SyntaxPhrases.commentTerminators
+import dev.snipme.snipmeapp.util.SyntaxPhrases.keywords
+import dev.snipme.snipmeapp.util.SyntaxPhrases.multilineCommentTerminators
+import dev.snipme.snipmeapp.util.SyntaxPhrases.textTerminators
+import dev.snipme.snipmeapp.util.SyntaxPhrases.wordTerminators
+import dev.snipme.snipmeapp.util.extension.containsDefault
+import dev.snipme.snipmeapp.util.extension.indicesOf
+import dev.snipme.snipmeapp.util.extension.lengthToEOF
+import dev.snipme.snipmeapp.util.extension.opaque
import timber.log.Timber
import java.util.*
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/SyntaxPhrases.kt b/app/src/main/java/dev/snipme/snipmeapp/util/SyntaxPhrases.kt
similarity index 98%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/SyntaxPhrases.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/SyntaxPhrases.kt
index e88fafe..35e5bd2 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/SyntaxPhrases.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/SyntaxPhrases.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.util
+package dev.snipme.snipmeapp.util
object SyntaxPhrases {
val wordTerminators = arrayOf(" ", ",", ".", ":", "(", ")", "=", "{", "}", "<", ">", "\r", "\n")
diff --git a/app/src/main/java/dev/snipme/snipmeapp/util/extension/CollectionExtensions.kt b/app/src/main/java/dev/snipme/snipmeapp/util/extension/CollectionExtensions.kt
new file mode 100644
index 0000000..9165e40
--- /dev/null
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/extension/CollectionExtensions.kt
@@ -0,0 +1,8 @@
+package dev.snipme.snipmeapp.util.extension
+
+import dev.snipme.snipmeapp.domain.snippets.SnippetLanguageType
+import dev.snipme.snipmeapp.domain.snippets.SnippetLanguageMapper
+
+fun CharSequence.lines(count: Int) = lines().take(count)
+
+fun String?.toSnippetLanguage(): SnippetLanguageType = SnippetLanguageMapper.fromString(this)
\ No newline at end of file
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/NetworkExtensions.kt b/app/src/main/java/dev/snipme/snipmeapp/util/extension/NetworkExtensions.kt
similarity index 78%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/NetworkExtensions.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/extension/NetworkExtensions.kt
index 1cf19d0..6e96ce0 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/NetworkExtensions.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/extension/NetworkExtensions.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.util.extension
+package dev.snipme.snipmeapp.util.extension
import retrofit2.HttpException
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/NumberExtensions.kt b/app/src/main/java/dev/snipme/snipmeapp/util/extension/NumberExtensions.kt
similarity index 88%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/NumberExtensions.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/extension/NumberExtensions.kt
index 0f37d58..0db4018 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/NumberExtensions.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/extension/NumberExtensions.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.util.extension
+package dev.snipme.snipmeapp.util.extension
import android.graphics.Color
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/RxExtensions.kt b/app/src/main/java/dev/snipme/snipmeapp/util/extension/RxExtensions.kt
similarity index 92%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/RxExtensions.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/extension/RxExtensions.kt
index af711b0..85e64bf 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/RxExtensions.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/extension/RxExtensions.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.util.extension
+package dev.snipme.snipmeapp.util.extension
import io.reactivex.Completable
import io.reactivex.Single
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/TextExtensions.kt b/app/src/main/java/dev/snipme/snipmeapp/util/extension/TextExtensions.kt
similarity index 95%
rename from app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/TextExtensions.kt
rename to app/src/main/java/dev/snipme/snipmeapp/util/extension/TextExtensions.kt
index 53baee9..1737799 100644
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/util/extension/TextExtensions.kt
+++ b/app/src/main/java/dev/snipme/snipmeapp/util/extension/TextExtensions.kt
@@ -1,4 +1,4 @@
-package pl.tkadziolka.snipmeandroid.util.extension
+package dev.snipme.snipmeapp.util.extension
import java.text.SimpleDateFormat
import java.util.*
diff --git a/app/src/main/java/pl/tkadziolka/snipmeandroid/bridge/Bridge.java b/app/src/main/java/pl/tkadziolka/snipmeandroid/bridge/Bridge.java
deleted file mode 100644
index 0914b54..0000000
--- a/app/src/main/java/pl/tkadziolka/snipmeandroid/bridge/Bridge.java
+++ /dev/null
@@ -1,944 +0,0 @@
-// Autogenerated from Pigeon (v4.2.3), do not edit directly.
-// See also: https://pub.dev/packages/pigeon
-
-package pl.tkadziolka.snipmeandroid.bridge;
-
-import android.util.Log;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import io.flutter.plugin.common.BasicMessageChannel;
-import io.flutter.plugin.common.BinaryMessenger;
-import io.flutter.plugin.common.MessageCodec;
-import io.flutter.plugin.common.StandardMessageCodec;
-import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-
-/**Generated class from Pigeon. */
-@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})
-public class Bridge {
-
- public enum SnippetLanguageType {
- C(0),
- CPP(1),
- OBJECTIVE_C(2),
- C_SHARP(3),
- JAVA(4),
- BASH(5),
- PYTHON(6),
- PERL(7),
- RUBY(8),
- SWIFT(9),
- JAVASCRIPT(10),
- KOTLIN(11),
- COFFEESCRIPT(12),
- RUST(13),
- BASIC(14),
- CLOJURE(15),
- CSS(16),
- DART(17),
- ERLANG(18),
- GO(19),
- HASKELL(20),
- LISP(21),
- LLVM(22),
- LUA(23),
- MATLAB(24),
- ML(25),
- MUMPS(26),
- NEMERLE(27),
- PASCAL(28),
- R(29),
- RD(30),
- SCALA(31),
- SQL(32),
- TEX(33),
- VB(34),
- VHDL(35),
- TCL(36),
- XQUERY(37),
- YAML(38),
- MARKDOWN(39),
- JSON(40),
- XML(41),
- PROTO(42),
- REGEX(43),
- UNKNOWN(44);
-
- private int index;
- private SnippetLanguageType(final int index) {
- this.index = index;
- }
- }
-
- public enum SnippetFilterType {
- ALL(0),
- MINE(1),
- SHARED(2);
-
- private int index;
- private SnippetFilterType(final int index) {
- this.index = index;
- }
- }
-
- public enum UserReaction {
- NONE(0),
- LIKE(1),
- DISLIKE(2);
-
- private int index;
- private UserReaction(final int index) {
- this.index = index;
- }
- }
-
- public enum ModelState {
- LOADING(0),
- LOADED(1),
- ERROR(2);
-
- private int index;
- private ModelState(final int index) {
- this.index = index;
- }
- }
-
- public enum MainModelEvent {
- NONE(0),
- ALERT(1),
- LOGOUT(2);
-
- private int index;
- private MainModelEvent(final int index) {
- this.index = index;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class Snippet {
- private @Nullable String uuid;
- public @Nullable String getUuid() { return uuid; }
- public void setUuid(@Nullable String setterArg) {
- this.uuid = setterArg;
- }
-
- private @Nullable String title;
- public @Nullable String getTitle() { return title; }
- public void setTitle(@Nullable String setterArg) {
- this.title = setterArg;
- }
-
- private @Nullable SnippetCode code;
- public @Nullable SnippetCode getCode() { return code; }
- public void setCode(@Nullable SnippetCode setterArg) {
- this.code = setterArg;
- }
-
- private @Nullable SnippetLanguage language;
- public @Nullable SnippetLanguage getLanguage() { return language; }
- public void setLanguage(@Nullable SnippetLanguage setterArg) {
- this.language = setterArg;
- }
-
- private @Nullable Owner owner;
- public @Nullable Owner getOwner() { return owner; }
- public void setOwner(@Nullable Owner setterArg) {
- this.owner = setterArg;
- }
-
- private @Nullable Boolean isOwner;
- public @Nullable Boolean getIsOwner() { return isOwner; }
- public void setIsOwner(@Nullable Boolean setterArg) {
- this.isOwner = setterArg;
- }
-
- private @Nullable String timeAgo;
- public @Nullable String getTimeAgo() { return timeAgo; }
- public void setTimeAgo(@Nullable String setterArg) {
- this.timeAgo = setterArg;
- }
-
- private @Nullable Long voteResult;
- public @Nullable Long getVoteResult() { return voteResult; }
- public void setVoteResult(@Nullable Long setterArg) {
- this.voteResult = setterArg;
- }
-
- private @Nullable UserReaction userReaction;
- public @Nullable UserReaction getUserReaction() { return userReaction; }
- public void setUserReaction(@Nullable UserReaction setterArg) {
- this.userReaction = setterArg;
- }
-
- private @Nullable Boolean isPrivate;
- public @Nullable Boolean getIsPrivate() { return isPrivate; }
- public void setIsPrivate(@Nullable Boolean setterArg) {
- this.isPrivate = setterArg;
- }
-
- private @Nullable Boolean isLiked;
- public @Nullable Boolean getIsLiked() { return isLiked; }
- public void setIsLiked(@Nullable Boolean setterArg) {
- this.isLiked = setterArg;
- }
-
- private @Nullable Boolean isDisliked;
- public @Nullable Boolean getIsDisliked() { return isDisliked; }
- public void setIsDisliked(@Nullable Boolean setterArg) {
- this.isDisliked = setterArg;
- }
-
- private @Nullable Boolean isSaved;
- public @Nullable Boolean getIsSaved() { return isSaved; }
- public void setIsSaved(@Nullable Boolean setterArg) {
- this.isSaved = setterArg;
- }
-
- public static final class Builder {
- private @Nullable String uuid;
- public @NonNull Builder setUuid(@Nullable String setterArg) {
- this.uuid = setterArg;
- return this;
- }
- private @Nullable String title;
- public @NonNull Builder setTitle(@Nullable String setterArg) {
- this.title = setterArg;
- return this;
- }
- private @Nullable SnippetCode code;
- public @NonNull Builder setCode(@Nullable SnippetCode setterArg) {
- this.code = setterArg;
- return this;
- }
- private @Nullable SnippetLanguage language;
- public @NonNull Builder setLanguage(@Nullable SnippetLanguage setterArg) {
- this.language = setterArg;
- return this;
- }
- private @Nullable Owner owner;
- public @NonNull Builder setOwner(@Nullable Owner setterArg) {
- this.owner = setterArg;
- return this;
- }
- private @Nullable Boolean isOwner;
- public @NonNull Builder setIsOwner(@Nullable Boolean setterArg) {
- this.isOwner = setterArg;
- return this;
- }
- private @Nullable String timeAgo;
- public @NonNull Builder setTimeAgo(@Nullable String setterArg) {
- this.timeAgo = setterArg;
- return this;
- }
- private @Nullable Long voteResult;
- public @NonNull Builder setVoteResult(@Nullable Long setterArg) {
- this.voteResult = setterArg;
- return this;
- }
- private @Nullable UserReaction userReaction;
- public @NonNull Builder setUserReaction(@Nullable UserReaction setterArg) {
- this.userReaction = setterArg;
- return this;
- }
- private @Nullable Boolean isPrivate;
- public @NonNull Builder setIsPrivate(@Nullable Boolean setterArg) {
- this.isPrivate = setterArg;
- return this;
- }
- private @Nullable Boolean isLiked;
- public @NonNull Builder setIsLiked(@Nullable Boolean setterArg) {
- this.isLiked = setterArg;
- return this;
- }
- private @Nullable Boolean isDisliked;
- public @NonNull Builder setIsDisliked(@Nullable Boolean setterArg) {
- this.isDisliked = setterArg;
- return this;
- }
- private @Nullable Boolean isSaved;
- public @NonNull Builder setIsSaved(@Nullable Boolean setterArg) {
- this.isSaved = setterArg;
- return this;
- }
- public @NonNull Snippet build() {
- Snippet pigeonReturn = new Snippet();
- pigeonReturn.setUuid(uuid);
- pigeonReturn.setTitle(title);
- pigeonReturn.setCode(code);
- pigeonReturn.setLanguage(language);
- pigeonReturn.setOwner(owner);
- pigeonReturn.setIsOwner(isOwner);
- pigeonReturn.setTimeAgo(timeAgo);
- pigeonReturn.setVoteResult(voteResult);
- pigeonReturn.setUserReaction(userReaction);
- pigeonReturn.setIsPrivate(isPrivate);
- pigeonReturn.setIsLiked(isLiked);
- pigeonReturn.setIsDisliked(isDisliked);
- pigeonReturn.setIsSaved(isSaved);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("uuid", uuid);
- toMapResult.put("title", title);
- toMapResult.put("code", (code == null) ? null : code.toMap());
- toMapResult.put("language", (language == null) ? null : language.toMap());
- toMapResult.put("owner", (owner == null) ? null : owner.toMap());
- toMapResult.put("isOwner", isOwner);
- toMapResult.put("timeAgo", timeAgo);
- toMapResult.put("voteResult", voteResult);
- toMapResult.put("userReaction", userReaction == null ? null : userReaction.index);
- toMapResult.put("isPrivate", isPrivate);
- toMapResult.put("isLiked", isLiked);
- toMapResult.put("isDisliked", isDisliked);
- toMapResult.put("isSaved", isSaved);
- return toMapResult;
- }
- static @NonNull Snippet fromMap(@NonNull Map map) {
- Snippet pigeonResult = new Snippet();
- Object uuid = map.get("uuid");
- pigeonResult.setUuid((String)uuid);
- Object title = map.get("title");
- pigeonResult.setTitle((String)title);
- Object code = map.get("code");
- pigeonResult.setCode((code == null) ? null : SnippetCode.fromMap((Map)code));
- Object language = map.get("language");
- pigeonResult.setLanguage((language == null) ? null : SnippetLanguage.fromMap((Map)language));
- Object owner = map.get("owner");
- pigeonResult.setOwner((owner == null) ? null : Owner.fromMap((Map)owner));
- Object isOwner = map.get("isOwner");
- pigeonResult.setIsOwner((Boolean)isOwner);
- Object timeAgo = map.get("timeAgo");
- pigeonResult.setTimeAgo((String)timeAgo);
- Object voteResult = map.get("voteResult");
- pigeonResult.setVoteResult((voteResult == null) ? null : ((voteResult instanceof Integer) ? (Integer)voteResult : (Long)voteResult));
- Object userReaction = map.get("userReaction");
- pigeonResult.setUserReaction(userReaction == null ? null : UserReaction.values()[(int)userReaction]);
- Object isPrivate = map.get("isPrivate");
- pigeonResult.setIsPrivate((Boolean)isPrivate);
- Object isLiked = map.get("isLiked");
- pigeonResult.setIsLiked((Boolean)isLiked);
- Object isDisliked = map.get("isDisliked");
- pigeonResult.setIsDisliked((Boolean)isDisliked);
- Object isSaved = map.get("isSaved");
- pigeonResult.setIsSaved((Boolean)isSaved);
- return pigeonResult;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class SnippetCode {
- private @Nullable String raw;
- public @Nullable String getRaw() { return raw; }
- public void setRaw(@Nullable String setterArg) {
- this.raw = setterArg;
- }
-
- private @Nullable List tokens;
- public @Nullable List getTokens() { return tokens; }
- public void setTokens(@Nullable List setterArg) {
- this.tokens = setterArg;
- }
-
- public static final class Builder {
- private @Nullable String raw;
- public @NonNull Builder setRaw(@Nullable String setterArg) {
- this.raw = setterArg;
- return this;
- }
- private @Nullable List tokens;
- public @NonNull Builder setTokens(@Nullable List setterArg) {
- this.tokens = setterArg;
- return this;
- }
- public @NonNull SnippetCode build() {
- SnippetCode pigeonReturn = new SnippetCode();
- pigeonReturn.setRaw(raw);
- pigeonReturn.setTokens(tokens);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("raw", raw);
- toMapResult.put("tokens", tokens);
- return toMapResult;
- }
- static @NonNull SnippetCode fromMap(@NonNull Map map) {
- SnippetCode pigeonResult = new SnippetCode();
- Object raw = map.get("raw");
- pigeonResult.setRaw((String)raw);
- Object tokens = map.get("tokens");
- pigeonResult.setTokens((List)tokens);
- return pigeonResult;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class SyntaxToken {
- private @Nullable Long start;
- public @Nullable Long getStart() { return start; }
- public void setStart(@Nullable Long setterArg) {
- this.start = setterArg;
- }
-
- private @Nullable Long end;
- public @Nullable Long getEnd() { return end; }
- public void setEnd(@Nullable Long setterArg) {
- this.end = setterArg;
- }
-
- private @Nullable Long color;
- public @Nullable Long getColor() { return color; }
- public void setColor(@Nullable Long setterArg) {
- this.color = setterArg;
- }
-
- public static final class Builder {
- private @Nullable Long start;
- public @NonNull Builder setStart(@Nullable Long setterArg) {
- this.start = setterArg;
- return this;
- }
- private @Nullable Long end;
- public @NonNull Builder setEnd(@Nullable Long setterArg) {
- this.end = setterArg;
- return this;
- }
- private @Nullable Long color;
- public @NonNull Builder setColor(@Nullable Long setterArg) {
- this.color = setterArg;
- return this;
- }
- public @NonNull SyntaxToken build() {
- SyntaxToken pigeonReturn = new SyntaxToken();
- pigeonReturn.setStart(start);
- pigeonReturn.setEnd(end);
- pigeonReturn.setColor(color);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("start", start);
- toMapResult.put("end", end);
- toMapResult.put("color", color);
- return toMapResult;
- }
- static @NonNull SyntaxToken fromMap(@NonNull Map map) {
- SyntaxToken pigeonResult = new SyntaxToken();
- Object start = map.get("start");
- pigeonResult.setStart((start == null) ? null : ((start instanceof Integer) ? (Integer)start : (Long)start));
- Object end = map.get("end");
- pigeonResult.setEnd((end == null) ? null : ((end instanceof Integer) ? (Integer)end : (Long)end));
- Object color = map.get("color");
- pigeonResult.setColor((color == null) ? null : ((color instanceof Integer) ? (Integer)color : (Long)color));
- return pigeonResult;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class SnippetLanguage {
- private @Nullable String raw;
- public @Nullable String getRaw() { return raw; }
- public void setRaw(@Nullable String setterArg) {
- this.raw = setterArg;
- }
-
- private @Nullable SnippetLanguageType type;
- public @Nullable SnippetLanguageType getType() { return type; }
- public void setType(@Nullable SnippetLanguageType setterArg) {
- this.type = setterArg;
- }
-
- public static final class Builder {
- private @Nullable String raw;
- public @NonNull Builder setRaw(@Nullable String setterArg) {
- this.raw = setterArg;
- return this;
- }
- private @Nullable SnippetLanguageType type;
- public @NonNull Builder setType(@Nullable SnippetLanguageType setterArg) {
- this.type = setterArg;
- return this;
- }
- public @NonNull SnippetLanguage build() {
- SnippetLanguage pigeonReturn = new SnippetLanguage();
- pigeonReturn.setRaw(raw);
- pigeonReturn.setType(type);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("raw", raw);
- toMapResult.put("type", type == null ? null : type.index);
- return toMapResult;
- }
- static @NonNull SnippetLanguage fromMap(@NonNull Map map) {
- SnippetLanguage pigeonResult = new SnippetLanguage();
- Object raw = map.get("raw");
- pigeonResult.setRaw((String)raw);
- Object type = map.get("type");
- pigeonResult.setType(type == null ? null : SnippetLanguageType.values()[(int)type]);
- return pigeonResult;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class Owner {
- private @Nullable Long id;
- public @Nullable Long getId() { return id; }
- public void setId(@Nullable Long setterArg) {
- this.id = setterArg;
- }
-
- private @Nullable String login;
- public @Nullable String getLogin() { return login; }
- public void setLogin(@Nullable String setterArg) {
- this.login = setterArg;
- }
-
- public static final class Builder {
- private @Nullable Long id;
- public @NonNull Builder setId(@Nullable Long setterArg) {
- this.id = setterArg;
- return this;
- }
- private @Nullable String login;
- public @NonNull Builder setLogin(@Nullable String setterArg) {
- this.login = setterArg;
- return this;
- }
- public @NonNull Owner build() {
- Owner pigeonReturn = new Owner();
- pigeonReturn.setId(id);
- pigeonReturn.setLogin(login);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("id", id);
- toMapResult.put("login", login);
- return toMapResult;
- }
- static @NonNull Owner fromMap(@NonNull Map map) {
- Owner pigeonResult = new Owner();
- Object id = map.get("id");
- pigeonResult.setId((id == null) ? null : ((id instanceof Integer) ? (Integer)id : (Long)id));
- Object login = map.get("login");
- pigeonResult.setLogin((String)login);
- return pigeonResult;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class SnippetFilter {
- private @Nullable SnippetFilterType type;
- public @Nullable SnippetFilterType getType() { return type; }
- public void setType(@Nullable SnippetFilterType setterArg) {
- this.type = setterArg;
- }
-
- public static final class Builder {
- private @Nullable SnippetFilterType type;
- public @NonNull Builder setType(@Nullable SnippetFilterType setterArg) {
- this.type = setterArg;
- return this;
- }
- public @NonNull SnippetFilter build() {
- SnippetFilter pigeonReturn = new SnippetFilter();
- pigeonReturn.setType(type);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("type", type == null ? null : type.index);
- return toMapResult;
- }
- static @NonNull SnippetFilter fromMap(@NonNull Map map) {
- SnippetFilter pigeonResult = new SnippetFilter();
- Object type = map.get("type");
- pigeonResult.setType(type == null ? null : SnippetFilterType.values()[(int)type]);
- return pigeonResult;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class MainModelStateData {
- private @Nullable ModelState state;
- public @Nullable ModelState getState() { return state; }
- public void setState(@Nullable ModelState setterArg) {
- this.state = setterArg;
- }
-
- private @Nullable Boolean is_loading;
- public @Nullable Boolean getIs_loading() { return is_loading; }
- public void setIs_loading(@Nullable Boolean setterArg) {
- this.is_loading = setterArg;
- }
-
- private @Nullable List data;
- public @Nullable List getData() { return data; }
- public void setData(@Nullable List setterArg) {
- this.data = setterArg;
- }
-
- private @Nullable String error;
- public @Nullable String getError() { return error; }
- public void setError(@Nullable String setterArg) {
- this.error = setterArg;
- }
-
- public static final class Builder {
- private @Nullable ModelState state;
- public @NonNull Builder setState(@Nullable ModelState setterArg) {
- this.state = setterArg;
- return this;
- }
- private @Nullable Boolean is_loading;
- public @NonNull Builder setIs_loading(@Nullable Boolean setterArg) {
- this.is_loading = setterArg;
- return this;
- }
- private @Nullable List data;
- public @NonNull Builder setData(@Nullable List setterArg) {
- this.data = setterArg;
- return this;
- }
- private @Nullable String error;
- public @NonNull Builder setError(@Nullable String setterArg) {
- this.error = setterArg;
- return this;
- }
- public @NonNull MainModelStateData build() {
- MainModelStateData pigeonReturn = new MainModelStateData();
- pigeonReturn.setState(state);
- pigeonReturn.setIs_loading(is_loading);
- pigeonReturn.setData(data);
- pigeonReturn.setError(error);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("state", state == null ? null : state.index);
- toMapResult.put("is_loading", is_loading);
- toMapResult.put("data", data);
- toMapResult.put("error", error);
- return toMapResult;
- }
- static @NonNull MainModelStateData fromMap(@NonNull Map map) {
- MainModelStateData pigeonResult = new MainModelStateData();
- Object state = map.get("state");
- pigeonResult.setState(state == null ? null : ModelState.values()[(int)state]);
- Object is_loading = map.get("is_loading");
- pigeonResult.setIs_loading((Boolean)is_loading);
- Object data = map.get("data");
- pigeonResult.setData((List)data);
- Object error = map.get("error");
- pigeonResult.setError((String)error);
- return pigeonResult;
- }
- }
-
- /** Generated class from Pigeon that represents data sent in messages. */
- public static class MainModelEventData {
- private @Nullable MainModelEvent event;
- public @Nullable MainModelEvent getEvent() { return event; }
- public void setEvent(@Nullable MainModelEvent setterArg) {
- this.event = setterArg;
- }
-
- private @Nullable String message;
- public @Nullable String getMessage() { return message; }
- public void setMessage(@Nullable String setterArg) {
- this.message = setterArg;
- }
-
- public static final class Builder {
- private @Nullable MainModelEvent event;
- public @NonNull Builder setEvent(@Nullable MainModelEvent setterArg) {
- this.event = setterArg;
- return this;
- }
- private @Nullable String message;
- public @NonNull Builder setMessage(@Nullable String setterArg) {
- this.message = setterArg;
- return this;
- }
- public @NonNull MainModelEventData build() {
- MainModelEventData pigeonReturn = new MainModelEventData();
- pigeonReturn.setEvent(event);
- pigeonReturn.setMessage(message);
- return pigeonReturn;
- }
- }
- @NonNull Map toMap() {
- Map toMapResult = new HashMap<>();
- toMapResult.put("event", event == null ? null : event.index);
- toMapResult.put("message", message);
- return toMapResult;
- }
- static @NonNull MainModelEventData fromMap(@NonNull Map map) {
- MainModelEventData pigeonResult = new MainModelEventData();
- Object event = map.get("event");
- pigeonResult.setEvent(event == null ? null : MainModelEvent.values()[(int)event]);
- Object message = map.get("message");
- pigeonResult.setMessage((String)message);
- return pigeonResult;
- }
- }
- private static class MainModelBridgeCodec extends StandardMessageCodec {
- public static final MainModelBridgeCodec INSTANCE = new MainModelBridgeCodec();
- private MainModelBridgeCodec() {}
- @Override
- protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
- switch (type) {
- case (byte)128:
- return MainModelEventData.fromMap((Map) readValue(buffer));
-
- case (byte)129:
- return MainModelStateData.fromMap((Map) readValue(buffer));
-
- case (byte)130:
- return Owner.fromMap((Map) readValue(buffer));
-
- case (byte)131:
- return Snippet.fromMap((Map