diff --git a/android/Omnivore/app/build.gradle b/android/Omnivore/app/build.gradle index 0b4746285..c23dcee14 100644 --- a/android/Omnivore/app/build.gradle +++ b/android/Omnivore/app/build.gradle @@ -49,13 +49,14 @@ android { } dependencies { - implementation 'androidx.core:core-ktx:1.7.0' implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.material:material:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' implementation 'androidx.activity:activity-compose:1.3.1' + implementation 'androidx.appcompat:appcompat:1.4.1' + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/android/Omnivore/app/src/main/AndroidManifest.xml b/android/Omnivore/app/src/main/AndroidManifest.xml index b067f10f0..ed213ee7f 100644 --- a/android/Omnivore/app/src/main/AndroidManifest.xml +++ b/android/Omnivore/app/src/main/AndroidManifest.xml @@ -28,6 +28,17 @@ + + + + + + + + diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/CloseButton.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/CloseButton.kt new file mode 100644 index 000000000..aabee8b6b --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/CloseButton.kt @@ -0,0 +1,47 @@ +package app.omnivore.omnivore + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Button +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import app.omnivore.omnivore.R + +typealias OnClickedClose = () -> Unit + +@Composable +fun CloseButton( + modifier: Modifier = Modifier, + onClickedClose: OnClickedClose +) { + Box( + modifier.then( + Modifier.padding(end = 13.dp, top = 13.dp) + ) + ) { + Button( + onClick = { onClickedClose() }, + modifier = Modifier.size(26.dp), + shape = CircleShape, + elevation = ButtonDefaults.elevation(defaultElevation = 0.dp, pressedElevation = 0.dp), + contentPadding = PaddingValues(0.dp), + colors = ButtonDefaults.outlinedButtonColors(backgroundColor = colorResource(id = R.color.cloud)) + ) { + Icon( + modifier = Modifier.align(Alignment.CenterVertically), + painter = painterResource(id = R.drawable.ic_x_2), + contentDescription = "CLOSE_BUTTON_DESCRIPTION", + tint = colorResource(id = R.color.gray_B7B7B7) + ) + } + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/NewFlowActivity.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/NewFlowActivity.kt new file mode 100644 index 000000000..0748fda0f --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/NewFlowActivity.kt @@ -0,0 +1,11 @@ +package app.omnivore.omnivore + +import androidx.compose.material.ExperimentalMaterialApi + +// Not sure why we need this class, but directly opening SaveSheetActivity +// causes the app to crash. + +@OptIn(ExperimentalMaterialApi::class) +class NewFlowActivity : SaveSheetActivity() { + +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/SaveContent.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/SaveContent.kt new file mode 100644 index 000000000..c1dce23f0 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/SaveContent.kt @@ -0,0 +1,41 @@ +package app.omnivore.omnivore + +import android.view.Surface +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Alignment.Companion.CenterHorizontally +import androidx.compose.ui.Modifier +import androidx.compose.material.* +import androidx.compose.ui.unit.dp + +@Composable +fun SaveContent(extractedText: String?, modifier: Modifier, button: (@Composable () -> Unit)? = null) { + Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { + Column( + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .background(MaterialTheme.colors.background) + .fillMaxSize() + ) { + val authToken = "authToken" + + Text(text = extractedText ?: "no text extracted") + Spacer(modifier = Modifier.height(16.dp)) + Text(text = authToken ?: "no auth token") + + } + } + Column { + button?.let { + Box(modifier = Modifier.align(CenterHorizontally)) { + button() + } + } + } +} + diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/SaveSheetActivity.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/SaveSheetActivity.kt new file mode 100644 index 000000000..ba2b1422e --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/SaveSheetActivity.kt @@ -0,0 +1,190 @@ +package app.omnivore.omnivore + +import android.content.ContentValues +import android.content.Intent +import android.os.Bundle +import android.util.Log +import androidx.activity.compose.BackHandler +import androidx.activity.compose.setContent +import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment.Companion.TopCenter +import androidx.compose.ui.Alignment.Companion.TopEnd +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.core.view.WindowCompat +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + + +@AndroidEntryPoint +@OptIn(ExperimentalMaterialApi::class) +abstract class SaveSheetActivity: AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val viewModel: SaveViewModel by viewModels() + var extractedText: String? = null + val authToken = viewModel.getAuthToken() + + when (intent?.action) { + Intent.ACTION_SEND -> { + if (intent.type?.startsWith("text/plain") == true) { + intent.getStringExtra(Intent.EXTRA_TEXT)?.let { + Log.d(ContentValues.TAG, "Extracted text: $extractedText") + extractedText = it + viewModel.saveURL(it) + } + } + + if (intent.type?.startsWith("text/html") == true) { + intent.getStringExtra(Intent.EXTRA_HTML_TEXT)?.let { + extractedText = it + } + } + } + else -> { + // Handle other intents, such as being started from the home screen + } + } + + setContent { + val coroutineScope = rememberCoroutineScope() + val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) + val isSheetOpened = remember { mutableStateOf(false) } + + ModalBottomSheetLayout( + sheetBackgroundColor = Color.Transparent, + sheetState = modalBottomSheetState, + sheetContent = { + BottomSheetUI(coroutineScope, modalBottomSheetState) { + ScreenContent(extractedText, coroutineScope, modalBottomSheetState) { + onFinish(coroutineScope, modalBottomSheetState) + } + } + } + ) {} + + BackHandler { + onFinish(coroutineScope, modalBottomSheetState) + } + + // Take action based on hidden state + LaunchedEffect(modalBottomSheetState.currentValue) { + when (modalBottomSheetState.currentValue) { + ModalBottomSheetValue.Hidden -> { + handleBottomSheetAtHiddenState( + isSheetOpened, + modalBottomSheetState + ) + } + else -> { + Log.i(TAG, "Bottom sheet ${modalBottomSheetState.currentValue} state") + } + } + } + } + } + + @Composable + private fun BottomSheetUI( + coroutineScope: CoroutineScope, + modalBottomSheetState: ModalBottomSheetState, + content: @Composable () -> Unit + ) { + Box( + modifier = Modifier + .wrapContentHeight() + .fillMaxWidth() + .clip(RoundedCornerShape(topEnd = 20.dp, topStart = 20.dp)) + .background(Color.White) + .statusBarsPadding() + ) { + content() + + Divider( + color = Color.Gray, + thickness = 5.dp, + modifier = Modifier + .padding(top = 15.dp) + .align(TopCenter) + .width(80.dp) + .clip(RoundedCornerShape(50.dp)) + ) + + CloseButton( + modifier = Modifier + .align(TopEnd) + .padding(10.dp) + ) { + coroutineScope.launch { + modalBottomSheetState.hide() + } + } + } + } + + // Helper methods + private suspend fun handleBottomSheetAtHiddenState( + isSheetOpened: MutableState, + modalBottomSheetState: ModalBottomSheetState + ) { + when { + !isSheetOpened.value -> initializeModalLayout(isSheetOpened, modalBottomSheetState) + else -> exit() + } + } + + private suspend fun initializeModalLayout( + isSheetOpened: MutableState, + modalBottomSheetState: ModalBottomSheetState + ) { + isSheetOpened.value = true + modalBottomSheetState.show() + } + + open fun exit() = finish() + + private fun onFinish( + coroutineScope: CoroutineScope, + modalBottomSheetState: ModalBottomSheetState, + withResults: Boolean = false, + result: Intent? = null + ) { + coroutineScope.launch { + if (withResults) setResult(RESULT_OK) + result?.let { intent = it} + modalBottomSheetState.hide() // will trigger the LaunchedEffect + } + } + + @Composable + fun ScreenContent( + extractedText: String?, + coroutineScope: CoroutineScope, + modalBottomSheetState: ModalBottomSheetState, + onExit: () -> Unit? + ) { + Box(modifier = Modifier.height(300.dp).background(Color.White)) { + SaveContent(extractedText, modifier = Modifier.fillMaxSize()) + } + } + + override fun onPause() { + super.onPause() + overridePendingTransition(0, 0) + } + + companion object { + private val TAG = SaveSheetActivity::class.java.simpleName + } +} diff --git a/android/Omnivore/app/src/main/res/drawable/ic_x_2.xml b/android/Omnivore/app/src/main/res/drawable/ic_x_2.xml new file mode 100644 index 000000000..0899ee9ed --- /dev/null +++ b/android/Omnivore/app/src/main/res/drawable/ic_x_2.xml @@ -0,0 +1,16 @@ + + + + diff --git a/android/Omnivore/app/src/main/res/values/colors.xml b/android/Omnivore/app/src/main/res/values/colors.xml index ca1931bca..234f693f1 100644 --- a/android/Omnivore/app/src/main/res/values/colors.xml +++ b/android/Omnivore/app/src/main/res/values/colors.xml @@ -7,4 +7,6 @@ #FF018786 #FF000000 #FFFFFFFF + #F7F7F7 + #B7B7B7 diff --git a/android/Omnivore/app/src/main/res/values/themes.xml b/android/Omnivore/app/src/main/res/values/themes.xml index fb34267cb..0b211c476 100644 --- a/android/Omnivore/app/src/main/res/values/themes.xml +++ b/android/Omnivore/app/src/main/res/values/themes.xml @@ -4,4 +4,22 @@ + + diff --git a/android/SaveToOmnivore/.gitignore b/android/SaveToOmnivore/.gitignore deleted file mode 100644 index aa724b770..000000000 --- a/android/SaveToOmnivore/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx -local.properties diff --git a/android/SaveToOmnivore/app/.gitignore b/android/SaveToOmnivore/app/.gitignore deleted file mode 100644 index 42afabfd2..000000000 --- a/android/SaveToOmnivore/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/android/SaveToOmnivore/app/build.gradle b/android/SaveToOmnivore/app/build.gradle deleted file mode 100644 index 9c89431b1..000000000 --- a/android/SaveToOmnivore/app/build.gradle +++ /dev/null @@ -1,73 +0,0 @@ - -plugins { - id 'com.android.application' - id 'org.jetbrains.kotlin.android' - id("com.apollographql.apollo3").version("3.4.0") -} - -android { - compileSdk 32 - - defaultConfig { - applicationId "app.omnivore.savetoomnivore" - minSdk 23 - targetSdk 32 - versionCode 3 - versionName "0.3" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { - useSupportLibrary true - } - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion "1.2.0-alpha08" - } - packagingOptions { - resources { - excludes += '/META-INF/{AL2.0,LGPL2.1}' - } - } -} - -dependencies { - - implementation 'androidx.core:core-ktx:1.7.0' - implementation "androidx.compose.ui:ui:$compose_version" - implementation 'androidx.compose.material3:material3:1.0.0-alpha14' - implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' - implementation 'androidx.activity:activity-compose:1.3.1' - implementation 'com.apollographql.apollo3:apollo-runtime:3.4.0' - implementation 'androidx.security:security-crypto-ktx:1.1.0-alpha03' - implementation 'androidx.datastore:datastore-core:1.0.0-rc01' - implementation "androidx.datastore:datastore-preferences:1.0.0" - - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' - androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" - debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" - debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" -} - -apollo { - packageName.set("app.omnivore.generated") -} \ No newline at end of file diff --git a/android/SaveToOmnivore/app/proguard-rules.pro b/android/SaveToOmnivore/app/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/android/SaveToOmnivore/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/androidTest/java/app/omnivore/savetoomnivore/ExampleInstrumentedTest.kt b/android/SaveToOmnivore/app/src/androidTest/java/app/omnivore/savetoomnivore/ExampleInstrumentedTest.kt deleted file mode 100644 index 7bda9bc5a..000000000 --- a/android/SaveToOmnivore/app/src/androidTest/java/app/omnivore/savetoomnivore/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.omnivore.savetoomnivore - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("app.omnivore.savetoomnivore", appContext.packageName) - } -} \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/AndroidManifest.xml b/android/SaveToOmnivore/app/src/main/AndroidManifest.xml deleted file mode 100644 index bcab33f06..000000000 --- a/android/SaveToOmnivore/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/graphql/SaveUrl.graphql b/android/SaveToOmnivore/app/src/main/graphql/SaveUrl.graphql deleted file mode 100644 index c2a2d2428..000000000 --- a/android/SaveToOmnivore/app/src/main/graphql/SaveUrl.graphql +++ /dev/null @@ -1,10 +0,0 @@ -mutation SaveUrl ($input: SaveUrlInput!) { - saveUrl(input:$input){ - ... on SaveSuccess { - url - } - ... on SaveError { - errorCodes - } - } -} \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/graphql/schema.graphqls b/android/SaveToOmnivore/app/src/main/graphql/schema.graphqls deleted file mode 100644 index 187b8d072..000000000 --- a/android/SaveToOmnivore/app/src/main/graphql/schema.graphqls +++ /dev/null @@ -1,1829 +0,0 @@ -directive @sanitize(allowedTags: [String], maxLength: Int, pattern: String) on INPUT_FIELD_DEFINITION - -type AddPopularReadError { - errorCodes: [AddPopularReadErrorCode!]! -} - -enum AddPopularReadErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union AddPopularReadResult = AddPopularReadError | AddPopularReadSuccess - -type AddPopularReadSuccess { - pageId: String! -} - -type ApiKey { - createdAt: Date! - expiresAt: Date! - id: ID! - key: String - name: String! - scopes: [String!] - usedAt: Date -} - -type ApiKeysError { - errorCodes: [ApiKeysErrorCode!]! -} - -enum ApiKeysErrorCode { - BAD_REQUEST - UNAUTHORIZED -} - -union ApiKeysResult = ApiKeysError | ApiKeysSuccess - -type ApiKeysSuccess { - apiKeys: [ApiKey!]! -} - -type ArchiveLinkError { - errorCodes: [ArchiveLinkErrorCode!]! - message: String! -} - -enum ArchiveLinkErrorCode { - BAD_REQUEST - UNAUTHORIZED -} - -input ArchiveLinkInput { - archived: Boolean! - linkId: ID! -} - -union ArchiveLinkResult = ArchiveLinkError | ArchiveLinkSuccess - -type ArchiveLinkSuccess { - linkId: String! - message: String! -} - -type Article { - author: String - content: String! - contentReader: ContentReader! - createdAt: Date! - description: String - hasContent: Boolean - hash: String! - highlights(input: ArticleHighlightsInput): [Highlight!]! - id: ID! - image: String - isArchived: Boolean! - labels: [Label!] - language: String - linkId: ID - originalArticleUrl: String - originalHtml: String - pageType: PageType - postedByViewer: Boolean - publishedAt: Date - readAt: Date - readingProgressAnchorIndex: Int! - readingProgressPercent: Float! - savedAt: Date! - savedByViewer: Boolean - shareInfo: LinkShareInfo - sharedComment: String - siteIcon: String - siteName: String - slug: String! - state: ArticleSavingRequestStatus - subscription: String - title: String! - unsubHttpUrl: String - unsubMailTo: String - updatedAt: Date! - uploadFileId: ID - url: String! -} - -type ArticleEdge { - cursor: String! - node: Article! -} - -type ArticleError { - errorCodes: [ArticleErrorCode!]! -} - -enum ArticleErrorCode { - BAD_DATA - NOT_FOUND - UNAUTHORIZED -} - -input ArticleHighlightsInput { - includeFriends: Boolean -} - -union ArticleResult = ArticleError | ArticleSuccess - -type ArticleSavingRequest { - article: Article @deprecated(reason: "article has been replaced with slug") - createdAt: Date! - errorCode: CreateArticleErrorCode - id: ID! - slug: String! - status: ArticleSavingRequestStatus! - updatedAt: Date! - user: User! - userId: ID! @deprecated(reason: "userId has been replaced with user") -} - -type ArticleSavingRequestError { - errorCodes: [ArticleSavingRequestErrorCode!]! -} - -enum ArticleSavingRequestErrorCode { - NOT_FOUND - UNAUTHORIZED -} - -union ArticleSavingRequestResult = ArticleSavingRequestError | ArticleSavingRequestSuccess - -enum ArticleSavingRequestStatus { - FAILED - PROCESSING - SUCCEEDED -} - -type ArticleSavingRequestSuccess { - articleSavingRequest: ArticleSavingRequest! -} - -type ArticleSuccess { - article: Article! -} - -type ArticlesError { - errorCodes: [ArticlesErrorCode!]! -} - -enum ArticlesErrorCode { - UNAUTHORIZED -} - -union ArticlesResult = ArticlesError | ArticlesSuccess - -type ArticlesSuccess { - edges: [ArticleEdge!]! - pageInfo: PageInfo! -} - -enum ContentReader { - PDF - WEB -} - -type CreateArticleError { - errorCodes: [CreateArticleErrorCode!]! -} - -enum CreateArticleErrorCode { - ELASTIC_ERROR - NOT_ALLOWED_TO_PARSE - PAYLOAD_TOO_LARGE - UNABLE_TO_FETCH - UNABLE_TO_PARSE - UNAUTHORIZED - UPLOAD_FILE_MISSING -} - -input CreateArticleInput { - articleSavingRequestId: ID - preparedDocument: PreparedDocumentInput - skipParsing: Boolean - source: String - uploadFileId: ID - url: String! -} - -union CreateArticleResult = CreateArticleError | CreateArticleSuccess - -type CreateArticleSavingRequestError { - errorCodes: [CreateArticleSavingRequestErrorCode!]! -} - -enum CreateArticleSavingRequestErrorCode { - BAD_DATA - UNAUTHORIZED -} - -input CreateArticleSavingRequestInput { - url: String! -} - -union CreateArticleSavingRequestResult = CreateArticleSavingRequestError | CreateArticleSavingRequestSuccess - -type CreateArticleSavingRequestSuccess { - articleSavingRequest: ArticleSavingRequest! -} - -type CreateArticleSuccess { - created: Boolean! - createdArticle: Article! - user: User! -} - -type CreateHighlightError { - errorCodes: [CreateHighlightErrorCode!]! -} - -enum CreateHighlightErrorCode { - ALREADY_EXISTS - BAD_DATA - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input CreateHighlightInput { - annotation: String - articleId: ID! - id: ID! - patch: String! - prefix: String - quote: String! - sharedAt: Date - shortId: String! - suffix: String -} - -type CreateHighlightReplyError { - errorCodes: [CreateHighlightReplyErrorCode!]! -} - -enum CreateHighlightReplyErrorCode { - EMPTY_ANNOTATION - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input CreateHighlightReplyInput { - highlightId: ID! - text: String! -} - -union CreateHighlightReplyResult = CreateHighlightReplyError | CreateHighlightReplySuccess - -type CreateHighlightReplySuccess { - highlightReply: HighlightReply! -} - -union CreateHighlightResult = CreateHighlightError | CreateHighlightSuccess - -type CreateHighlightSuccess { - highlight: Highlight! -} - -type CreateLabelError { - errorCodes: [CreateLabelErrorCode!]! -} - -enum CreateLabelErrorCode { - BAD_REQUEST - LABEL_ALREADY_EXISTS - NOT_FOUND - UNAUTHORIZED -} - -input CreateLabelInput { - color: String! - description: String - name: String! -} - -union CreateLabelResult = CreateLabelError | CreateLabelSuccess - -type CreateLabelSuccess { - label: Label! -} - -type CreateNewsletterEmailError { - errorCodes: [CreateNewsletterEmailErrorCode!]! -} - -enum CreateNewsletterEmailErrorCode { - BAD_REQUEST - UNAUTHORIZED -} - -union CreateNewsletterEmailResult = CreateNewsletterEmailError | CreateNewsletterEmailSuccess - -type CreateNewsletterEmailSuccess { - newsletterEmail: NewsletterEmail! -} - -type CreateReactionError { - errorCodes: [CreateReactionErrorCode!]! -} - -enum CreateReactionErrorCode { - BAD_CODE - BAD_TARGET - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input CreateReactionInput { - code: ReactionType! - highlightId: ID - userArticleId: ID -} - -union CreateReactionResult = CreateReactionError | CreateReactionSuccess - -type CreateReactionSuccess { - reaction: Reaction! -} - -type CreateReminderError { - errorCodes: [CreateReminderErrorCode!]! -} - -enum CreateReminderErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -input CreateReminderInput { - archiveUntil: Boolean! - clientRequestId: ID - linkId: ID - remindAt: Date! - sendNotification: Boolean! -} - -union CreateReminderResult = CreateReminderError | CreateReminderSuccess - -type CreateReminderSuccess { - reminder: Reminder! -} - -scalar Date - -type DeleteAccountError { - errorCodes: [DeleteAccountErrorCode!]! -} - -enum DeleteAccountErrorCode { - FORBIDDEN - UNAUTHORIZED - USER_NOT_FOUND -} - -union DeleteAccountResult = DeleteAccountError | DeleteAccountSuccess - -type DeleteAccountSuccess { - userID: ID! -} - -type DeleteHighlightError { - errorCodes: [DeleteHighlightErrorCode!]! -} - -enum DeleteHighlightErrorCode { - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -type DeleteHighlightReplyError { - errorCodes: [DeleteHighlightReplyErrorCode!]! -} - -enum DeleteHighlightReplyErrorCode { - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -union DeleteHighlightReplyResult = DeleteHighlightReplyError | DeleteHighlightReplySuccess - -type DeleteHighlightReplySuccess { - highlightReply: HighlightReply! -} - -union DeleteHighlightResult = DeleteHighlightError | DeleteHighlightSuccess - -type DeleteHighlightSuccess { - highlight: Highlight! -} - -type DeleteLabelError { - errorCodes: [DeleteLabelErrorCode!]! -} - -enum DeleteLabelErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union DeleteLabelResult = DeleteLabelError | DeleteLabelSuccess - -type DeleteLabelSuccess { - label: Label! -} - -type DeleteNewsletterEmailError { - errorCodes: [DeleteNewsletterEmailErrorCode!]! -} - -enum DeleteNewsletterEmailErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union DeleteNewsletterEmailResult = DeleteNewsletterEmailError | DeleteNewsletterEmailSuccess - -type DeleteNewsletterEmailSuccess { - newsletterEmail: NewsletterEmail! -} - -type DeleteReactionError { - errorCodes: [DeleteReactionErrorCode!]! -} - -enum DeleteReactionErrorCode { - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -union DeleteReactionResult = DeleteReactionError | DeleteReactionSuccess - -type DeleteReactionSuccess { - reaction: Reaction! -} - -type DeleteReminderError { - errorCodes: [DeleteReminderErrorCode!]! -} - -enum DeleteReminderErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union DeleteReminderResult = DeleteReminderError | DeleteReminderSuccess - -type DeleteReminderSuccess { - reminder: Reminder! -} - -type DeleteWebhookError { - errorCodes: [DeleteWebhookErrorCode!]! -} - -enum DeleteWebhookErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union DeleteWebhookResult = DeleteWebhookError | DeleteWebhookSuccess - -type DeleteWebhookSuccess { - webhook: Webhook! -} - -type DeviceToken { - createdAt: Date! - id: ID! - token: String! -} - -type FeedArticle { - annotationsCount: Int - article: Article! - highlight: Highlight - highlightsCount: Int - id: ID! - reactions: [Reaction!]! - sharedAt: Date! - sharedBy: User! - sharedComment: String - sharedWithHighlights: Boolean -} - -type FeedArticleEdge { - cursor: String! - node: FeedArticle! -} - -type FeedArticlesError { - errorCodes: [FeedArticlesErrorCode!]! -} - -enum FeedArticlesErrorCode { - UNAUTHORIZED -} - -union FeedArticlesResult = FeedArticlesError | FeedArticlesSuccess - -type FeedArticlesSuccess { - edges: [FeedArticleEdge!]! - pageInfo: PageInfo! -} - -type GenerateApiKeyError { - errorCodes: [GenerateApiKeyErrorCode!]! -} - -enum GenerateApiKeyErrorCode { - ALREADY_EXISTS - BAD_REQUEST - UNAUTHORIZED -} - -input GenerateApiKeyInput { - expiresAt: Date! - name: String! - scopes: [String!] -} - -union GenerateApiKeyResult = GenerateApiKeyError | GenerateApiKeySuccess - -type GenerateApiKeySuccess { - apiKey: ApiKey! -} - -type GetFollowersError { - errorCodes: [GetFollowersErrorCode!]! -} - -enum GetFollowersErrorCode { - UNAUTHORIZED -} - -union GetFollowersResult = GetFollowersError | GetFollowersSuccess - -type GetFollowersSuccess { - followers: [User!]! -} - -type GetFollowingError { - errorCodes: [GetFollowingErrorCode!]! -} - -enum GetFollowingErrorCode { - UNAUTHORIZED -} - -union GetFollowingResult = GetFollowingError | GetFollowingSuccess - -type GetFollowingSuccess { - following: [User!]! -} - -type GetUserPersonalizationError { - errorCodes: [GetUserPersonalizationErrorCode!]! -} - -enum GetUserPersonalizationErrorCode { - UNAUTHORIZED -} - -union GetUserPersonalizationResult = GetUserPersonalizationError | GetUserPersonalizationSuccess - -type GetUserPersonalizationSuccess { - userPersonalization: UserPersonalization -} - -input GoogleLoginInput { - email: String! - secret: String! -} - -type GoogleSignupError { - errorCodes: [SignupErrorCode]! -} - -input GoogleSignupInput { - bio: String - email: String! - name: String! - pictureUrl: String! - secret: String! - sourceUserId: String! - username: String! -} - -union GoogleSignupResult = GoogleSignupError | GoogleSignupSuccess - -type GoogleSignupSuccess { - me: User! -} - -type Highlight { - annotation: String - createdAt: Date! - createdByMe: Boolean! - id: ID! - patch: String! - prefix: String - quote: String! - reactions: [Reaction!]! - replies: [HighlightReply!]! - sharedAt: Date - shortId: String! - suffix: String - updatedAt: Date! - user: User! -} - -type HighlightReply { - createdAt: Date! - highlight: Highlight! - id: ID! - text: String! - updatedAt: Date! - user: User! -} - -type HighlightStats { - highlightCount: Int! -} - -type Label { - color: String! - createdAt: Date - description: String - id: ID! - name: String! -} - -type LabelsError { - errorCodes: [LabelsErrorCode!]! -} - -enum LabelsErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union LabelsResult = LabelsError | LabelsSuccess - -type LabelsSuccess { - labels: [Label!]! -} - -type Link { - highlightStats: HighlightStats! - id: ID! - page: Page! - postedByViewer: Boolean! - readState: ReadState! - savedAt: Date! - savedBy: User! - savedByViewer: Boolean! - shareInfo: LinkShareInfo! - shareStats: ShareStats! - slug: String! - updatedAt: Date! - url: String! -} - -type LinkShareInfo { - description: String! - imageUrl: String! - title: String! -} - -type LogOutError { - errorCodes: [LogOutErrorCode!]! -} - -enum LogOutErrorCode { - LOG_OUT_FAILED -} - -union LogOutResult = LogOutError | LogOutSuccess - -type LogOutSuccess { - message: String -} - -type LoginError { - errorCodes: [LoginErrorCode!]! -} - -enum LoginErrorCode { - ACCESS_DENIED - AUTH_FAILED - INVALID_CREDENTIALS - USER_ALREADY_EXISTS - USER_NOT_FOUND - WRONG_SOURCE -} - -input LoginInput { - email: String! - password: String! -} - -union LoginResult = LoginError | LoginSuccess - -type LoginSuccess { - me: User! -} - -type MergeHighlightError { - errorCodes: [MergeHighlightErrorCode!]! -} - -enum MergeHighlightErrorCode { - ALREADY_EXISTS - BAD_DATA - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input MergeHighlightInput { - annotation: String - articleId: ID! - id: ID! - overlapHighlightIdList: [String!]! - patch: String! - prefix: String - quote: String! - shortId: ID! - suffix: String -} - -union MergeHighlightResult = MergeHighlightError | MergeHighlightSuccess - -type MergeHighlightSuccess { - highlight: Highlight! - overlapHighlightIdList: [String!]! -} - -type Mutation { - addPopularRead(name: String!): AddPopularReadResult! - createArticle(input: CreateArticleInput!): CreateArticleResult! - createArticleSavingRequest(input: CreateArticleSavingRequestInput!): CreateArticleSavingRequestResult! - createHighlight(input: CreateHighlightInput!): CreateHighlightResult! - createHighlightReply(input: CreateHighlightReplyInput!): CreateHighlightReplyResult! - createLabel(input: CreateLabelInput!): CreateLabelResult! - createNewsletterEmail: CreateNewsletterEmailResult! - createReaction(input: CreateReactionInput!): CreateReactionResult! - createReminder(input: CreateReminderInput!): CreateReminderResult! - deleteAccount(userID: ID!): DeleteAccountResult! - deleteHighlight(highlightId: ID!): DeleteHighlightResult! - deleteHighlightReply(highlightReplyId: ID!): DeleteHighlightReplyResult! - deleteLabel(id: ID!): DeleteLabelResult! - deleteNewsletterEmail(newsletterEmailId: ID!): DeleteNewsletterEmailResult! - deleteReaction(id: ID!): DeleteReactionResult! - deleteReminder(id: ID!): DeleteReminderResult! - deleteWebhook(id: ID!): DeleteWebhookResult! - generateApiKey(input: GenerateApiKeyInput!): GenerateApiKeyResult! - googleLogin(input: GoogleLoginInput!): LoginResult! - googleSignup(input: GoogleSignupInput!): GoogleSignupResult! - logOut: LogOutResult! - login(input: LoginInput!): LoginResult! - mergeHighlight(input: MergeHighlightInput!): MergeHighlightResult! - reportItem(input: ReportItemInput!): ReportItemResult! - revokeApiKey(id: ID!): RevokeApiKeyResult! - saveArticleReadingProgress(input: SaveArticleReadingProgressInput!): SaveArticleReadingProgressResult! - saveFile(input: SaveFileInput!): SaveResult! - savePage(input: SavePageInput!): SaveResult! - saveUrl(input: SaveUrlInput!): SaveResult! - setBookmarkArticle(input: SetBookmarkArticleInput!): SetBookmarkArticleResult! - setDeviceToken(input: SetDeviceTokenInput!): SetDeviceTokenResult! - setFollow(input: SetFollowInput!): SetFollowResult! - setLabels(input: SetLabelsInput!): SetLabelsResult! - setLabelsForHighlight(input: SetLabelsForHighlightInput!): SetLabelsResult! - setLinkArchived(input: ArchiveLinkInput!): ArchiveLinkResult! - setShareArticle(input: SetShareArticleInput!): SetShareArticleResult! - setShareHighlight(input: SetShareHighlightInput!): SetShareHighlightResult! - setUserPersonalization(input: SetUserPersonalizationInput!): SetUserPersonalizationResult! - setWebhook(input: SetWebhookInput!): SetWebhookResult! - signup(input: SignupInput!): SignupResult! - subscribe(name: String!): SubscribeResult! - unsubscribe(name: String!): UnsubscribeResult! - updateHighlight(input: UpdateHighlightInput!): UpdateHighlightResult! - updateHighlightReply(input: UpdateHighlightReplyInput!): UpdateHighlightReplyResult! - updateLabel(input: UpdateLabelInput!): UpdateLabelResult! - updateLinkShareInfo(input: UpdateLinkShareInfoInput!): UpdateLinkShareInfoResult! - updatePage(input: UpdatePageInput!): UpdatePageResult! - updateReminder(input: UpdateReminderInput!): UpdateReminderResult! - updateSharedComment(input: UpdateSharedCommentInput!): UpdateSharedCommentResult! - updateUser(input: UpdateUserInput!): UpdateUserResult! - updateUserProfile(input: UpdateUserProfileInput!): UpdateUserProfileResult! - uploadFileRequest(input: UploadFileRequestInput!): UploadFileRequestResult! -} - -type NewsletterEmail { - address: String! - confirmationCode: String - id: ID! -} - -type NewsletterEmailsError { - errorCodes: [NewsletterEmailsErrorCode!]! -} - -enum NewsletterEmailsErrorCode { - BAD_REQUEST - UNAUTHORIZED -} - -union NewsletterEmailsResult = NewsletterEmailsError | NewsletterEmailsSuccess - -type NewsletterEmailsSuccess { - newsletterEmails: [NewsletterEmail!]! -} - -type Page { - author: String - createdAt: Date! - description: String - hash: String! - id: ID! - image: String! - originalHtml: String! - originalUrl: String! - publishedAt: Date - readableHtml: String! - title: String! - type: PageType! - updatedAt: Date! - url: String! -} - -type PageInfo { - endCursor: String - hasNextPage: Boolean! - hasPreviousPage: Boolean! - startCursor: String - totalCount: Int -} - -input PageInfoInput { - author: String - canonicalUrl: String - contentType: String - description: String - previewImage: String - publishedAt: Date - title: String -} - -enum PageType { - ARTICLE - BOOK - FILE - HIGHLIGHTS - PROFILE - UNKNOWN - WEBSITE -} - -input PreparedDocumentInput { - document: String! - pageInfo: PageInfoInput! -} - -type Profile { - bio: String - id: ID! - pictureUrl: String - private: Boolean! - username: String! -} - -type Query { - apiKeys: ApiKeysResult! - article(slug: String!, username: String!): ArticleResult! - articleSavingRequest(id: ID!): ArticleSavingRequestResult! - articles(after: String, first: Int, includePending: Boolean, query: String, sharedOnly: Boolean, sort: SortParams): ArticlesResult! - feedArticles(after: String, first: Int, sharedByUser: ID, sort: SortParams): FeedArticlesResult! - getFollowers(userId: ID): GetFollowersResult! - getFollowing(userId: ID): GetFollowingResult! - getUserPersonalization: GetUserPersonalizationResult! - hello: String - labels: LabelsResult! - me: User - newsletterEmails: NewsletterEmailsResult! - reminder(linkId: ID!): ReminderResult! - search(after: String, first: Int, query: String): SearchResult! - sendInstallInstructions: SendInstallInstructionsResult! - sharedArticle(selectedHighlightId: String, slug: String!, username: String!): SharedArticleResult! - subscriptions(sort: SortParams): SubscriptionsResult! - typeaheadSearch(first: Int, query: String!): TypeaheadSearchResult! - user(userId: ID, username: String): UserResult! - users: UsersResult! - validateUsername(username: String!): Boolean! - webhook(id: ID!): WebhookResult! - webhooks: WebhooksResult! -} - -type Reaction { - code: ReactionType! - createdAt: Date! - id: ID! - updatedAt: Date - user: User! -} - -enum ReactionType { - CRYING - HEART - HUSHED - LIKE - POUT - SMILE -} - -type ReadState { - progressAnchorIndex: Int! - progressPercent: Float! - reading: Boolean - readingTime: Int -} - -type Reminder { - archiveUntil: Boolean! - id: ID! - remindAt: Date! - sendNotification: Boolean! -} - -type ReminderError { - errorCodes: [ReminderErrorCode!]! -} - -enum ReminderErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union ReminderResult = ReminderError | ReminderSuccess - -type ReminderSuccess { - reminder: Reminder! -} - -input ReportItemInput { - itemUrl: String! - pageId: ID! - reportComment: String! - reportTypes: [ReportType!]! - sharedBy: ID -} - -type ReportItemResult { - message: String! -} - -enum ReportType { - ABUSIVE - CONTENT_DISPLAY - CONTENT_VIOLATION - SPAM -} - -type RevokeApiKeyError { - errorCodes: [RevokeApiKeyErrorCode!]! -} - -enum RevokeApiKeyErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union RevokeApiKeyResult = RevokeApiKeyError | RevokeApiKeySuccess - -type RevokeApiKeySuccess { - apiKey: ApiKey! -} - -type SaveArticleReadingProgressError { - errorCodes: [SaveArticleReadingProgressErrorCode!]! -} - -enum SaveArticleReadingProgressErrorCode { - BAD_DATA - NOT_FOUND - UNAUTHORIZED -} - -input SaveArticleReadingProgressInput { - id: ID! - readingProgressAnchorIndex: Int! - readingProgressPercent: Float! -} - -union SaveArticleReadingProgressResult = SaveArticleReadingProgressError | SaveArticleReadingProgressSuccess - -type SaveArticleReadingProgressSuccess { - updatedArticle: Article! -} - -type SaveError { - errorCodes: [SaveErrorCode!]! - message: String -} - -enum SaveErrorCode { - UNAUTHORIZED - UNKNOWN -} - -input SaveFileInput { - clientRequestId: ID! - source: String! - uploadFileId: ID! - url: String! -} - -input SavePageInput { - clientRequestId: ID! - originalContent: String! - source: String! - title: String - url: String! -} - -union SaveResult = SaveError | SaveSuccess - -type SaveSuccess { - clientRequestId: ID! - url: String! -} - -input SaveUrlInput { - clientRequestId: ID! - source: String! - url: String! -} - -type SearchError { - errorCodes: [SearchErrorCode!]! -} - -enum SearchErrorCode { - UNAUTHORIZED -} - -type SearchItem { - annotation: String - author: String - contentReader: ContentReader! - createdAt: Date! - description: String - highlights: [Highlight!] - id: ID! - image: String - isArchived: Boolean! - labels: [Label!] - language: String - originalArticleUrl: String - ownedByViewer: Boolean - pageId: ID - pageType: PageType! - publishedAt: Date - quote: String - readAt: Date - readingProgressAnchorIndex: Int! - readingProgressPercent: Float! - savedAt: Date! - shortId: String - siteName: String - slug: String! - state: ArticleSavingRequestStatus - subscription: String - title: String! - unsubHttpUrl: String - unsubMailTo: String - updatedAt: Date - uploadFileId: ID - url: String! -} - -type SearchItemEdge { - cursor: String! - node: SearchItem! -} - -union SearchResult = SearchError | SearchSuccess - -type SearchSuccess { - edges: [SearchItemEdge!]! - pageInfo: PageInfo! -} - -type SendInstallInstructionsError { - errorCodes: [SendInstallInstructionsErrorCode!]! -} - -enum SendInstallInstructionsErrorCode { - BAD_REQUEST - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -union SendInstallInstructionsResult = SendInstallInstructionsError | SendInstallInstructionsSuccess - -type SendInstallInstructionsSuccess { - sent: Boolean! -} - -type SetBookmarkArticleError { - errorCodes: [SetBookmarkArticleErrorCode!]! -} - -enum SetBookmarkArticleErrorCode { - BOOKMARK_EXISTS - NOT_FOUND -} - -input SetBookmarkArticleInput { - articleID: ID! - bookmark: Boolean! -} - -union SetBookmarkArticleResult = SetBookmarkArticleError | SetBookmarkArticleSuccess - -type SetBookmarkArticleSuccess { - bookmarkedArticle: Article! -} - -type SetDeviceTokenError { - errorCodes: [SetDeviceTokenErrorCode!]! -} - -enum SetDeviceTokenErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -input SetDeviceTokenInput { - id: ID - token: String -} - -union SetDeviceTokenResult = SetDeviceTokenError | SetDeviceTokenSuccess - -type SetDeviceTokenSuccess { - deviceToken: DeviceToken! -} - -type SetFollowError { - errorCodes: [SetFollowErrorCode!]! -} - -enum SetFollowErrorCode { - NOT_FOUND - UNAUTHORIZED -} - -input SetFollowInput { - follow: Boolean! - userId: ID! -} - -union SetFollowResult = SetFollowError | SetFollowSuccess - -type SetFollowSuccess { - updatedUser: User! -} - -type SetLabelsError { - errorCodes: [SetLabelsErrorCode!]! -} - -enum SetLabelsErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -input SetLabelsForHighlightInput { - highlightId: ID! - labelIds: [ID!]! -} - -input SetLabelsInput { - labelIds: [ID!]! - pageId: ID! -} - -union SetLabelsResult = SetLabelsError | SetLabelsSuccess - -type SetLabelsSuccess { - labels: [Label!]! -} - -type SetShareArticleError { - errorCodes: [SetShareArticleErrorCode!]! -} - -enum SetShareArticleErrorCode { - NOT_FOUND - UNAUTHORIZED -} - -input SetShareArticleInput { - articleID: ID! - share: Boolean! - sharedComment: String - sharedWithHighlights: Boolean -} - -union SetShareArticleResult = SetShareArticleError | SetShareArticleSuccess - -type SetShareArticleSuccess { - updatedArticle: Article! - updatedFeedArticle: FeedArticle - updatedFeedArticleId: String -} - -type SetShareHighlightError { - errorCodes: [SetShareHighlightErrorCode!]! -} - -enum SetShareHighlightErrorCode { - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input SetShareHighlightInput { - id: ID! - share: Boolean! -} - -union SetShareHighlightResult = SetShareHighlightError | SetShareHighlightSuccess - -type SetShareHighlightSuccess { - highlight: Highlight! -} - -type SetUserPersonalizationError { - errorCodes: [SetUserPersonalizationErrorCode!]! -} - -enum SetUserPersonalizationErrorCode { - UNAUTHORIZED -} - -input SetUserPersonalizationInput { - fontFamily: String - fontSize: Int - libraryLayoutType: String - librarySortOrder: SortOrder - margin: Int - theme: String -} - -union SetUserPersonalizationResult = SetUserPersonalizationError | SetUserPersonalizationSuccess - -type SetUserPersonalizationSuccess { - updatedUserPersonalization: UserPersonalization! -} - -type SetWebhookError { - errorCodes: [SetWebhookErrorCode!]! -} - -enum SetWebhookErrorCode { - ALREADY_EXISTS - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -input SetWebhookInput { - contentType: String - enabled: Boolean - eventTypes: [WebhookEvent!]! - id: ID - method: String - url: String! -} - -union SetWebhookResult = SetWebhookError | SetWebhookSuccess - -type SetWebhookSuccess { - webhook: Webhook! -} - -type ShareStats { - readDuration: Int! - saveCount: Int! - viewCount: Int! -} - -type SharedArticleError { - errorCodes: [SharedArticleErrorCode!]! -} - -enum SharedArticleErrorCode { - NOT_FOUND -} - -union SharedArticleResult = SharedArticleError | SharedArticleSuccess - -type SharedArticleSuccess { - article: Article! -} - -type SignupError { - errorCodes: [SignupErrorCode]! -} - -enum SignupErrorCode { - ACCESS_DENIED - EXPIRED_TOKEN - GOOGLE_AUTH_ERROR - INVALID_PASSWORD - INVALID_USERNAME - UNKNOWN - USER_EXISTS -} - -input SignupInput { - bio: String - email: String! - name: String! - password: String! - pictureUrl: String - username: String! -} - -union SignupResult = SignupError | SignupSuccess - -type SignupSuccess { - me: User! -} - -enum SortBy { - PUBLISHED_AT - SAVED_AT - SCORE - UPDATED_TIME -} - -enum SortOrder { - ASCENDING - DESCENDING -} - -input SortParams { - by: SortBy! - order: SortOrder -} - -type SubscribeError { - errorCodes: [SubscribeErrorCode!]! -} - -enum SubscribeErrorCode { - ALREADY_SUBSCRIBED - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -union SubscribeResult = SubscribeError | SubscribeSuccess - -type SubscribeSuccess { - subscriptions: [Subscription!]! -} - -type Subscription { - createdAt: Date! - description: String - id: ID! - name: String! - newsletterEmail: String! - status: SubscriptionStatus! - unsubscribeHttpUrl: String - unsubscribeMailTo: String - updatedAt: Date! - url: String -} - -enum SubscriptionStatus { - ACTIVE - DELETED - UNSUBSCRIBED -} - -type SubscriptionsError { - errorCodes: [SubscriptionsErrorCode!]! -} - -enum SubscriptionsErrorCode { - BAD_REQUEST - UNAUTHORIZED -} - -union SubscriptionsResult = SubscriptionsError | SubscriptionsSuccess - -type SubscriptionsSuccess { - subscriptions: [Subscription!]! -} - -type TypeaheadSearchError { - errorCodes: [TypeaheadSearchErrorCode!]! -} - -enum TypeaheadSearchErrorCode { - UNAUTHORIZED -} - -type TypeaheadSearchItem { - id: ID! - siteName: String - slug: String! - title: String! -} - -union TypeaheadSearchResult = TypeaheadSearchError | TypeaheadSearchSuccess - -type TypeaheadSearchSuccess { - items: [TypeaheadSearchItem!]! -} - -type UnsubscribeError { - errorCodes: [UnsubscribeErrorCode!]! -} - -enum UnsubscribeErrorCode { - ALREADY_UNSUBSCRIBED - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED - UNSUBSCRIBE_METHOD_NOT_FOUND -} - -union UnsubscribeResult = UnsubscribeError | UnsubscribeSuccess - -type UnsubscribeSuccess { - subscription: Subscription! -} - -type UpdateHighlightError { - errorCodes: [UpdateHighlightErrorCode!]! -} - -enum UpdateHighlightErrorCode { - BAD_DATA - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input UpdateHighlightInput { - annotation: String - highlightId: ID! - sharedAt: Date -} - -type UpdateHighlightReplyError { - errorCodes: [UpdateHighlightReplyErrorCode!]! -} - -enum UpdateHighlightReplyErrorCode { - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input UpdateHighlightReplyInput { - highlightReplyId: ID! - text: String! -} - -union UpdateHighlightReplyResult = UpdateHighlightReplyError | UpdateHighlightReplySuccess - -type UpdateHighlightReplySuccess { - highlightReply: HighlightReply! -} - -union UpdateHighlightResult = UpdateHighlightError | UpdateHighlightSuccess - -type UpdateHighlightSuccess { - highlight: Highlight! -} - -type UpdateLabelError { - errorCodes: [UpdateLabelErrorCode!]! -} - -enum UpdateLabelErrorCode { - BAD_REQUEST - FORBIDDEN - NOT_FOUND - UNAUTHORIZED -} - -input UpdateLabelInput { - color: String! - description: String - labelId: ID! - name: String! -} - -union UpdateLabelResult = UpdateLabelError | UpdateLabelSuccess - -type UpdateLabelSuccess { - label: Label! -} - -type UpdateLinkShareInfoError { - errorCodes: [UpdateLinkShareInfoErrorCode!]! -} - -enum UpdateLinkShareInfoErrorCode { - BAD_REQUEST - UNAUTHORIZED -} - -input UpdateLinkShareInfoInput { - description: String! - linkId: ID! - title: String! -} - -union UpdateLinkShareInfoResult = UpdateLinkShareInfoError | UpdateLinkShareInfoSuccess - -type UpdateLinkShareInfoSuccess { - message: String! -} - -type UpdatePageError { - errorCodes: [UpdatePageErrorCode!]! -} - -enum UpdatePageErrorCode { - BAD_REQUEST - FORBIDDEN - NOT_FOUND - UNAUTHORIZED - UPDATE_FAILED -} - -input UpdatePageInput { - description: String - pageId: ID! - title: String -} - -union UpdatePageResult = UpdatePageError | UpdatePageSuccess - -type UpdatePageSuccess { - updatedPage: Article! -} - -type UpdateReminderError { - errorCodes: [UpdateReminderErrorCode!]! -} - -enum UpdateReminderErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -input UpdateReminderInput { - archiveUntil: Boolean! - id: ID! - remindAt: Date! - sendNotification: Boolean! -} - -union UpdateReminderResult = UpdateReminderError | UpdateReminderSuccess - -type UpdateReminderSuccess { - reminder: Reminder! -} - -type UpdateSharedCommentError { - errorCodes: [UpdateSharedCommentErrorCode!]! -} - -enum UpdateSharedCommentErrorCode { - NOT_FOUND - UNAUTHORIZED -} - -input UpdateSharedCommentInput { - articleID: ID! - sharedComment: String! -} - -union UpdateSharedCommentResult = UpdateSharedCommentError | UpdateSharedCommentSuccess - -type UpdateSharedCommentSuccess { - articleID: ID! - sharedComment: String! -} - -type UpdateUserError { - errorCodes: [UpdateUserErrorCode!]! -} - -enum UpdateUserErrorCode { - BIO_TOO_LONG - EMPTY_NAME - UNAUTHORIZED - USER_NOT_FOUND -} - -input UpdateUserInput { - bio: String - name: String! -} - -type UpdateUserProfileError { - errorCodes: [UpdateUserProfileErrorCode!]! -} - -enum UpdateUserProfileErrorCode { - BAD_DATA - BAD_USERNAME - FORBIDDEN - UNAUTHORIZED - USERNAME_EXISTS -} - -input UpdateUserProfileInput { - bio: String - pictureUrl: String - userId: ID! - username: String -} - -union UpdateUserProfileResult = UpdateUserProfileError | UpdateUserProfileSuccess - -type UpdateUserProfileSuccess { - user: User! -} - -union UpdateUserResult = UpdateUserError | UpdateUserSuccess - -type UpdateUserSuccess { - user: User! -} - -type UploadFileRequestError { - errorCodes: [UploadFileRequestErrorCode!]! -} - -enum UploadFileRequestErrorCode { - BAD_INPUT - FAILED_CREATE - UNAUTHORIZED -} - -input UploadFileRequestInput { - clientRequestId: String - contentType: String! - createPageEntry: Boolean - url: String! -} - -union UploadFileRequestResult = UploadFileRequestError | UploadFileRequestSuccess - -type UploadFileRequestSuccess { - createdPageId: String - id: ID! - uploadFileId: ID - uploadSignedUrl: String -} - -enum UploadFileStatus { - COMPLETED - INITIALIZED -} - -type User { - followersCount: Int - friendsCount: Int - id: ID! - isFriend: Boolean @deprecated(reason: "isFriend has been replaced with viewerIsFollowing") - isFullUser: Boolean - name: String! - picture: String - profile: Profile! - sharedArticles: [FeedArticle!]! - sharedArticlesCount: Int - sharedHighlightsCount: Int - sharedNotesCount: Int - viewerIsFollowing: Boolean -} - -type UserError { - errorCodes: [UserErrorCode!]! -} - -enum UserErrorCode { - BAD_REQUEST - UNAUTHORIZED - USER_NOT_FOUND -} - -type UserPersonalization { - fontFamily: String - fontSize: Int - id: ID - libraryLayoutType: String - librarySortOrder: SortOrder - margin: Int - theme: String -} - -union UserResult = UserError | UserSuccess - -type UserSuccess { - user: User! -} - -type UsersError { - errorCodes: [UsersErrorCode!]! -} - -enum UsersErrorCode { - UNAUTHORIZED -} - -union UsersResult = UsersError | UsersSuccess - -type UsersSuccess { - users: [User!]! -} - -type Webhook { - contentType: String! - createdAt: Date! - enabled: Boolean! - eventTypes: [WebhookEvent!]! - id: ID! - method: String! - updatedAt: Date! - url: String! -} - -type WebhookError { - errorCodes: [WebhookErrorCode!]! -} - -enum WebhookErrorCode { - BAD_REQUEST - NOT_FOUND - UNAUTHORIZED -} - -enum WebhookEvent { - HIGHLIGHT_CREATED - HIGHLIGHT_DELETED - HIGHLIGHT_UPDATED - LABEL_CREATED - LABEL_DELETED - LABEL_UPDATED - PAGE_CREATED - PAGE_DELETED - PAGE_UPDATED -} - -union WebhookResult = WebhookError | WebhookSuccess - -type WebhookSuccess { - webhook: Webhook! -} - -type WebhooksError { - errorCodes: [WebhooksErrorCode!]! -} - -enum WebhooksErrorCode { - BAD_REQUEST - UNAUTHORIZED -} - -union WebhooksResult = WebhooksError | WebhooksSuccess - -type WebhooksSuccess { - webhooks: [Webhook!]! -} diff --git a/android/SaveToOmnivore/app/src/main/ic_launcher-playstore.png b/android/SaveToOmnivore/app/src/main/ic_launcher-playstore.png deleted file mode 100644 index 3f5ca0237..000000000 Binary files a/android/SaveToOmnivore/app/src/main/ic_launcher-playstore.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/AppDatastore.kt b/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/AppDatastore.kt deleted file mode 100644 index 2ad6b5ded..000000000 --- a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/AppDatastore.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.omnivore.savetoomnivore - -import android.annotation.SuppressLint -import android.content.Context -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.platform.LocalContext -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.core.edit -import androidx.datastore.preferences.core.stringPreferencesKey -import androidx.datastore.preferences.preferencesDataStore -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map - -class AppDatastore(private val context: Context) { - private val Context.datastore: DataStore by preferencesDataStore(name = "app_datastore") - private val APIKEY = stringPreferencesKey(name = "API_KEY") - - companion object { - @SuppressLint("StaticFieldLeak") - var INSTANCE: AppDatastore? = null - fun getInstance(base: Context): AppDatastore? { - if (INSTANCE == null) { - synchronized(AppDatastore::class.java) { - INSTANCE = AppDatastore(base.applicationContext) - } - } - - return INSTANCE - } - } - - suspend fun setApiKey(apiKey: String) { - context.datastore.edit { preferences -> - preferences[APIKEY] = apiKey - } - } - - val getApiKey: Flow = context.datastore.data.map { preferences -> - preferences[APIKEY] ?: "" - } -} \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ExtensionActivity.kt b/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ExtensionActivity.kt deleted file mode 100644 index f0545f764..000000000 --- a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ExtensionActivity.kt +++ /dev/null @@ -1,106 +0,0 @@ -package app.omnivore.savetoomnivore - -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.os.Bundle -import android.text.TextUtils.isEmpty -import android.widget.Toast -import androidx.activity.ComponentActivity -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.preferencesDataStore -import app.omnivore.generated.SaveUrlMutation -import app.omnivore.generated.type.SaveUrlInput -import com.apollographql.apollo3.ApolloClient -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.launch -import java.util.* -import java.util.regex.Matcher -import java.util.regex.Pattern - - -private val Context.dataStore: DataStore by preferencesDataStore( - name = "settings" -) - -class ExtensionActivity : ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - when { - intent?.action == Intent.ACTION_SEND -> { - if ("text/plain" == intent.type) { - handleSendText(intent) // Handle text being sent - } - } - } - finish() - } - - fun saveURL(url: String) { - - GlobalScope.launch { - val apiKey = AppDatastore.getInstance(baseContext)?.getApiKey?.first() - - val apolloClient = ApolloClient.Builder() - .serverUrl("https://api-prod.omnivore.app/api/graphql") - .addHttpHeader( - "Authorization", - value = apiKey.toString() - ) - .build() - - val source = "android" - val clientRequestId = UUID.randomUUID().toString() - val response = apolloClient.mutation( - SaveUrlMutation( - SaveUrlInput( - clientRequestId = clientRequestId, - source = source, - url = url - ) - ) - ).execute() - - val success = (response.data?.saveUrl?.onSaveSuccess?.url != null) - - GlobalScope.launch(Dispatchers.Main) { - runOnUiThread(Runnable { - val message = if (success) "Saved to Omnivore" else "Error saving to Omnivore" - Toast.makeText(baseContext, message, Toast.LENGTH_LONG).show() - }) - } - } - } - - private fun handleSendText(intent: Intent) { - intent.getStringExtra(Intent.EXTRA_TEXT)?.let { - val url = getUrl(it) - if (url == null || isEmpty(url)) { - Toast.makeText(this, "Error: no URL found.", Toast.LENGTH_LONG).show() - } else { - Toast.makeText(this, "Saving to Omnivore", Toast.LENGTH_LONG).show() - saveURL(it) - } - } - } - - fun getUrl(s: String): String? { - val pattern = - Pattern.compile("[(http(s)?):\\/\\/(www\\.)?a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)") - try { - val matcher: Matcher = pattern.matcher(s) - if (matcher.find()) { - return s.substring(matcher.start(), matcher.end()) - } - } catch (e: Exception) { - System.out.println("exception parsing string") - System.out.println(e) - return null - } - return null - } -} diff --git a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/MainActivity.kt b/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/MainActivity.kt deleted file mode 100644 index aaaff30e9..000000000 --- a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/MainActivity.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.omnivore.savetoomnivore - -import android.content.Context -import android.content.SharedPreferences -import android.os.Build -import android.os.Bundle -import android.provider.Settings -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.annotation.RequiresApi -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.material3.OutlinedTextField -import kotlinx.coroutines.launch -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.GlobalScope - -class MainActivity : ComponentActivity() { - - @RequiresApi(Build.VERSION_CODES.M) - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContent { - MaterialTheme { - // A surface container using the 'background' color from the theme - Surface( - modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.background - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.fillMaxWidth() - ) { - Text("Save to Omnivore") - var apiKey by remember { mutableStateOf("") } - OutlinedTextField( - value = apiKey, - onValueChange = { - apiKey = it - GlobalScope.launch { - setApiKey(apiKey) - } - }, - label = { Text("API Key") } - ) - Text("Get an API key from https://omnivore.app/settings/api") - } - } - } - } - } - - private suspend fun setApiKey(apiKey: String) { - AppDatastore.getInstance(base = baseContext)?.setApiKey(apiKey) - } -} diff --git a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Color.kt b/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Color.kt deleted file mode 100644 index babd26191..000000000 --- a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Color.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.omnivore.savetoomnivore.ui.theme - -import androidx.compose.ui.graphics.Color - -val Purple80 = Color(0xFFD0BCFF) -val PurpleGrey80 = Color(0xFFCCC2DC) -val Pink80 = Color(0xFFEFB8C8) - -val Purple40 = Color(0xFF6650a4) -val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Theme.kt b/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Theme.kt deleted file mode 100644 index 6dc8511dd..000000000 --- a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Theme.kt +++ /dev/null @@ -1,68 +0,0 @@ -package app.omnivore.savetoomnivore.ui.theme - -import android.app.Activity -import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalView -import androidx.core.view.ViewCompat - -private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 -) - -private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 - - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ -) - -@Composable -fun SaveToOmnivoreTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - // Dynamic color is available on Android 12+ - dynamicColor: Boolean = true, - content: @Composable () -> Unit -) { - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - darkTheme -> DarkColorScheme - else -> LightColorScheme - } - val view = LocalView.current - if (!view.isInEditMode) { - SideEffect { - (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb() - ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme - } - } - - MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content - ) -} \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Type.kt b/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Type.kt deleted file mode 100644 index be24a8304..000000000 --- a/android/SaveToOmnivore/app/src/main/java/app/omnivore/savetoomnivore/ui/theme/Type.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.omnivore.savetoomnivore.ui.theme - -import androidx.compose.material3.Typography -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -// Set of Material typography styles to start with -val Typography = Typography( - bodyLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp - ) - /* Other default text styles to override - titleLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 22.sp, - lineHeight = 28.sp, - letterSpacing = 0.sp - ), - labelSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Medium, - fontSize = 11.sp, - lineHeight = 16.sp, - letterSpacing = 0.5.sp - ) - */ -) \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/SaveToOmnivore/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d114..000000000 --- a/android/SaveToOmnivore/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/res/drawable/ic_launcher_background.xml b/android/SaveToOmnivore/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9cb..000000000 --- a/android/SaveToOmnivore/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 6b3619d2e..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index 84f3ca04b..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index a4756788b..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index f5837c7ba..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png deleted file mode 100644 index 43475955d..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 9cbca8c15..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 5caff3fed..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png deleted file mode 100644 index f70fdcea9..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 95fddeab7..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 624d9e310..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png deleted file mode 100644 index 7873c2cb6..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 24ef75825..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index de87fd987..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index b386ab807..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 0227993e3..000000000 Binary files a/android/SaveToOmnivore/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/SaveToOmnivore/app/src/main/res/values/colors.xml b/android/SaveToOmnivore/app/src/main/res/values/colors.xml deleted file mode 100644 index f8c6127d3..000000000 --- a/android/SaveToOmnivore/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF - \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/res/values/ic_launcher_background.xml b/android/SaveToOmnivore/app/src/main/res/values/ic_launcher_background.xml deleted file mode 100644 index c5d5899fd..000000000 --- a/android/SaveToOmnivore/app/src/main/res/values/ic_launcher_background.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - #FFFFFF - \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/res/values/strings.xml b/android/SaveToOmnivore/app/src/main/res/values/strings.xml deleted file mode 100644 index e537d2ef1..000000000 --- a/android/SaveToOmnivore/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Omnivore - \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/res/values/themes.xml b/android/SaveToOmnivore/app/src/main/res/values/themes.xml deleted file mode 100644 index 1a1372a95..000000000 --- a/android/SaveToOmnivore/app/src/main/res/values/themes.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/android/SaveToOmnivore/app/src/main/res/xml/backup_rules.xml b/android/SaveToOmnivore/app/src/main/res/xml/backup_rules.xml deleted file mode 100644 index fa0f996d2..000000000 --- a/android/SaveToOmnivore/app/src/main/res/xml/backup_rules.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/main/res/xml/data_extraction_rules.xml b/android/SaveToOmnivore/app/src/main/res/xml/data_extraction_rules.xml deleted file mode 100644 index 9ee9997b0..000000000 --- a/android/SaveToOmnivore/app/src/main/res/xml/data_extraction_rules.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android/SaveToOmnivore/app/src/test/java/app/omnivore/savetoomnivore/ExampleUnitTest.kt b/android/SaveToOmnivore/app/src/test/java/app/omnivore/savetoomnivore/ExampleUnitTest.kt deleted file mode 100644 index 332df63c4..000000000 --- a/android/SaveToOmnivore/app/src/test/java/app/omnivore/savetoomnivore/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.omnivore.savetoomnivore - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/android/SaveToOmnivore/build.gradle b/android/SaveToOmnivore/build.gradle deleted file mode 100644 index caac89d71..000000000 --- a/android/SaveToOmnivore/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -buildscript { - ext { - compose_version = '1.1.0-beta01' - } -}// Top-level build file where you can add configuration options common to all sub-projects/modules. -plugins { - id 'com.android.application' version '7.2.1' apply false - id 'com.android.library' version '7.2.1' apply false - id 'org.jetbrains.kotlin.android' version '1.6.20' apply false -} - -task clean(type: Delete) { - delete rootProject.buildDir -} \ No newline at end of file diff --git a/android/SaveToOmnivore/gradle.properties b/android/SaveToOmnivore/gradle.properties deleted file mode 100644 index cd0519bb2..000000000 --- a/android/SaveToOmnivore/gradle.properties +++ /dev/null @@ -1,23 +0,0 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app"s APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true -# Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file diff --git a/android/SaveToOmnivore/gradle/wrapper/gradle-wrapper.jar b/android/SaveToOmnivore/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c02..000000000 Binary files a/android/SaveToOmnivore/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/android/SaveToOmnivore/gradle/wrapper/gradle-wrapper.properties b/android/SaveToOmnivore/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 9e79af52e..000000000 --- a/android/SaveToOmnivore/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Tue Jul 19 16:31:46 PDT 2022 -distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip -distributionPath=wrapper/dists -zipStorePath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME diff --git a/android/SaveToOmnivore/gradlew b/android/SaveToOmnivore/gradlew deleted file mode 100755 index 4f906e0c8..000000000 --- a/android/SaveToOmnivore/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/android/SaveToOmnivore/gradlew.bat b/android/SaveToOmnivore/gradlew.bat deleted file mode 100644 index ac1b06f93..000000000 --- a/android/SaveToOmnivore/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/SaveToOmnivore/settings.gradle b/android/SaveToOmnivore/settings.gradle deleted file mode 100644 index 40d2999e2..000000000 --- a/android/SaveToOmnivore/settings.gradle +++ /dev/null @@ -1,16 +0,0 @@ -pluginManagement { - repositories { - gradlePluginPortal() - google() - mavenCentral() - } -} -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - } -} -rootProject.name = "SaveToOmnivore" -include ':app'