├── secret
└── .gitkeep
├── metadata
└── en-US
│ ├── video.txt
│ ├── title.txt
│ ├── short_description.txt
│ ├── images
│ ├── icon.png
│ ├── featureGraphic.png
│ └── phoneScreenshots
│ │ ├── 1_en-US.png
│ │ ├── 2_en-US.png
│ │ ├── 3_en-US.png
│ │ ├── 4_en-US.png
│ │ └── 5_en-US.png
│ ├── changelogs
│ ├── 32.txt
│ ├── 33.txt
│ ├── 36.txt
│ ├── 34.txt
│ ├── 35.txt
│ ├── 39.txt
│ ├── 38.txt
│ ├── 37.txt
│ └── 31.txt
│ └── full_description.txt
├── packages
├── android
│ ├── .idea
│ │ ├── .name
│ │ ├── compiler.xml
│ │ ├── vcs.xml
│ │ ├── misc.xml
│ │ ├── runConfigurations.xml
│ │ ├── gradle.xml
│ │ └── jarRepositories.xml
│ ├── app
│ │ ├── .gitignore
│ │ ├── src
│ │ │ ├── beta
│ │ │ │ └── res
│ │ │ │ │ └── values
│ │ │ │ │ └── strings.xml
│ │ │ ├── debug
│ │ │ │ └── res
│ │ │ │ │ └── values
│ │ │ │ │ └── strings.xml
│ │ │ ├── main
│ │ │ │ ├── java
│ │ │ │ │ └── io
│ │ │ │ │ │ └── literal
│ │ │ │ │ │ ├── lib
│ │ │ │ │ │ ├── Thunk.java
│ │ │ │ │ │ ├── Callback.java
│ │ │ │ │ │ ├── Callback2.java
│ │ │ │ │ │ ├── ResultCallback.java
│ │ │ │ │ │ ├── Callback3.java
│ │ │ │ │ │ ├── JsonMapper.java
│ │ │ │ │ │ ├── JsonReaderParser.java
│ │ │ │ │ │ ├── ArrayUtil.java
│ │ │ │ │ │ ├── Box.java
│ │ │ │ │ │ ├── AnnotationLib.java
│ │ │ │ │ │ ├── DateUtil.java
│ │ │ │ │ │ ├── Constants.java
│ │ │ │ │ │ ├── AnnotationCollectionLib.java
│ │ │ │ │ │ ├── FileActivityResultCallback.java
│ │ │ │ │ │ ├── AnnotationTargetLib.java
│ │ │ │ │ │ ├── ContentResolverLib.java
│ │ │ │ │ │ ├── AWSConfigurationLib.java
│ │ │ │ │ │ ├── AmazonS3URILib.java
│ │ │ │ │ │ ├── Crypto.java
│ │ │ │ │ │ └── JsonArrayUtil.java
│ │ │ │ │ │ ├── model
│ │ │ │ │ │ ├── AnnotationType.java
│ │ │ │ │ │ ├── SpecificResourceType.java
│ │ │ │ │ │ ├── ErrorRepositoryLevel.java
│ │ │ │ │ │ ├── SourceInitializationStatus.java
│ │ │ │ │ │ ├── Language.java
│ │ │ │ │ │ ├── Motivation.java
│ │ │ │ │ │ ├── TextDirection.java
│ │ │ │ │ │ ├── ResourceType.java
│ │ │ │ │ │ ├── SourceJavaScriptConfig.java
│ │ │ │ │ │ ├── State.java
│ │ │ │ │ │ ├── Body.java
│ │ │ │ │ │ ├── Format.java
│ │ │ │ │ │ └── Selector.java
│ │ │ │ │ │ ├── ui
│ │ │ │ │ │ ├── activity
│ │ │ │ │ │ │ └── InstrumentedActivity.java
│ │ │ │ │ │ └── MainApplication.java
│ │ │ │ │ │ ├── repository
│ │ │ │ │ │ ├── SharedPreferencesRepository.java
│ │ │ │ │ │ └── ToastRepository.java
│ │ │ │ │ │ └── service
│ │ │ │ │ │ └── SplashService.java
│ │ │ │ ├── res
│ │ │ │ │ ├── font
│ │ │ │ │ │ ├── roboto_mono.ttf
│ │ │ │ │ │ ├── roboto_mono_italic.ttf
│ │ │ │ │ │ └── font.xml
│ │ │ │ │ ├── drawable-hdpi
│ │ │ │ │ │ ├── done_white.png
│ │ │ │ │ │ ├── ic_stat_name.png
│ │ │ │ │ │ ├── highlight_white.png
│ │ │ │ │ │ └── toast_accent_frame.xml
│ │ │ │ │ ├── drawable-mdpi
│ │ │ │ │ │ ├── done_white.png
│ │ │ │ │ │ ├── ic_stat_name.png
│ │ │ │ │ │ └── highlight_white.png
│ │ │ │ │ ├── drawable-xhdpi
│ │ │ │ │ │ ├── done_white.png
│ │ │ │ │ │ ├── ic_stat_name.png
│ │ │ │ │ │ └── highlight_white.png
│ │ │ │ │ ├── drawable-xxhdpi
│ │ │ │ │ │ ├── done_white.png
│ │ │ │ │ │ ├── ic_stat_name.png
│ │ │ │ │ │ └── highlight_white.png
│ │ │ │ │ ├── drawable-xxxhdpi
│ │ │ │ │ │ ├── done_white.png
│ │ │ │ │ │ ├── ic_stat_name.png
│ │ │ │ │ │ └── highlight_white.png
│ │ │ │ │ ├── values
│ │ │ │ │ │ ├── dimens.xml
│ │ │ │ │ │ └── colors.xml
│ │ │ │ │ ├── drawable
│ │ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ │ ├── ic_launcher_foreground.xml
│ │ │ │ │ │ ├── toast_primary_frame.xml
│ │ │ │ │ │ ├── ic_baseline_arrow_drop_down_24.xml
│ │ │ │ │ │ ├── ic_baseline_keyboard_arrow_down_24.xml
│ │ │ │ │ │ ├── ic_baseline_more_vert_24.xml
│ │ │ │ │ │ ├── ic_baseline_build_24.xml
│ │ │ │ │ │ └── ic_logo.xml
│ │ │ │ │ ├── menu
│ │ │ │ │ │ ├── source_webview_create_annotation_menu.xml
│ │ │ │ │ │ ├── source_webview_edit_annotation_menu.xml
│ │ │ │ │ │ ├── source_webview_commit_edit_annotation_menu.xml
│ │ │ │ │ │ ├── source_webview_toolbar_create.xml
│ │ │ │ │ │ └── source_webview_toolbar_read.xml
│ │ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ │ └── ic_launcher.xml
│ │ │ │ │ ├── layout
│ │ │ │ │ │ ├── authentication_handler.xml
│ │ │ │ │ │ ├── fragment_app_web_view.xml
│ │ │ │ │ │ ├── splash.xml
│ │ │ │ │ │ ├── toast_accent.xml
│ │ │ │ │ │ ├── toast_primary.xml
│ │ │ │ │ │ ├── webview_toolbar_indeterminate_progress.xml
│ │ │ │ │ │ └── activity_share_target_handler.xml
│ │ │ │ │ └── values-v28
│ │ │ │ │ │ └── styles.xml
│ │ │ │ └── ic_launcher-playstore.png
│ │ │ ├── test
│ │ │ │ └── java
│ │ │ │ │ └── io
│ │ │ │ │ └── literal
│ │ │ │ │ └── ExampleUnitTest.java
│ │ │ ├── androidTest
│ │ │ │ └── java
│ │ │ │ │ └── io
│ │ │ │ │ └── literal
│ │ │ │ │ └── ExampleInstrumentedTest.java
│ │ │ └── foss
│ │ │ │ ├── res
│ │ │ │ └── raw
│ │ │ │ │ ├── awsconfiguration.json
│ │ │ │ │ └── amplifyconfiguration.json
│ │ │ │ └── java
│ │ │ │ └── io
│ │ │ │ └── literal
│ │ │ │ └── repository
│ │ │ │ └── AnalyticsRepository.java
│ │ └── proguard-rules.pro
│ ├── source-webview-scripts
│ │ ├── .nvmrc
│ │ ├── .gitignore
│ │ ├── build.sh
│ │ ├── annotation-renderer
│ │ │ ├── util.mjs
│ │ │ └── messenger.mjs
│ │ ├── get-scripts
│ │ │ └── index.mjs
│ │ ├── shared
│ │ │ ├── storage.mjs
│ │ │ └── xpath.mjs
│ │ ├── wrap-dist-with-executor.mjs
│ │ ├── package.json
│ │ ├── get-annotation-bounding-box
│ │ │ └── index.mjs
│ │ ├── webpack.config.js
│ │ └── get-annotation
│ │ │ └── index.mjs
│ ├── settings.gradle
│ ├── scripts
│ │ ├── amplify-pull-staging.sh
│ │ ├── amplify-pull-production.sh
│ │ ├── graphql-sync-schema-staging.sh
│ │ ├── graphql-sync-schema-production.sh
│ │ └── create-foss-amplify-and-aws-configuration.js
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── .graphqlconfig.yml
│ ├── build.gradle
│ ├── .gitignore
│ └── gradle.properties
├── pamphlet
│ ├── .gitignore
│ ├── templates
│ │ └── android-launch
│ │ │ └── variables.json
│ ├── tsconfig.json
│ ├── package.json
│ └── index.ts
├── bs-aws-sdk
│ ├── .gitignore
│ ├── bsconfig.json
│ └── package.json
├── model
│ ├── .gitignore
│ ├── src
│ │ ├── Language.re
│ │ ├── ResourceType.re
│ │ ├── TextDirection.re
│ │ ├── Language.js
│ │ ├── TextDirection.js
│ │ ├── Format.re
│ │ ├── ResourceType.js
│ │ ├── Motivation.re
│ │ ├── Format.js
│ │ ├── Motivation.js
│ │ ├── State.re
│ │ └── Annotation.re
│ ├── bsconfig.json
│ ├── package.json
│ └── package-lock.json
├── bs-amplitude
│ ├── .gitignore
│ ├── src
│ │ └── Amplitude.js
│ ├── bsconfig.json
│ └── package.json
├── bs-aws-amplify
│ ├── .gitignore
│ ├── bsconfig.json
│ └── package.json
├── bs-aws-appsync
│ ├── .gitignore
│ ├── bsconfig.json
│ ├── src
│ │ ├── AwsAppSync.js
│ │ └── AwsAppSync.re
│ ├── package-lock.json
│ └── package.json
├── web
│ ├── src
│ │ ├── externals
│ │ │ ├── Externals_Error.re
│ │ │ ├── uuid.re
│ │ │ ├── Externals_URLSearchParams.re
│ │ │ ├── MaterialUiLab.re
│ │ │ ├── Apollo.re
│ │ │ ├── Externals_Crypto.re
│ │ │ ├── LiteralWebview.re
│ │ │ ├── raw.re
│ │ │ ├── ramda.re
│ │ │ ├── FontFaceSet.re
│ │ │ ├── lodash.re
│ │ │ └── bowser.re
│ │ ├── components
│ │ │ ├── SourceListItem
│ │ │ │ ├── SourceListItem.module.css
│ │ │ │ └── SourceListItem_GraphQL.re
│ │ │ ├── TextInput
│ │ │ │ ├── TextInput.re
│ │ │ │ ├── TextInput_Basic.module.css
│ │ │ │ ├── TextInput_Loading.re
│ │ │ │ └── TextInput_Annotation.re
│ │ │ ├── Skeleton
│ │ │ │ ├── Skeleton.module.css
│ │ │ │ └── Skeleton.re
│ │ │ ├── Loading.re
│ │ │ ├── TagsList
│ │ │ │ └── TagsList.module.css
│ │ │ ├── Svg
│ │ │ │ ├── done.svg
│ │ │ │ ├── arrow-right.svg
│ │ │ │ ├── back.svg
│ │ │ │ ├── add.svg
│ │ │ │ ├── arrow-up.svg
│ │ │ │ ├── arrow-down.svg
│ │ │ │ ├── delete.svg
│ │ │ │ ├── delete-black.svg
│ │ │ │ ├── close.svg
│ │ │ │ ├── add-circle.svg
│ │ │ │ ├── more.svg
│ │ │ │ ├── remove-circle.svg
│ │ │ │ ├── text-fields.svg
│ │ │ │ ├── error-outline.svg
│ │ │ │ ├── label.svg
│ │ │ │ ├── logo.svg
│ │ │ │ ├── source.svg
│ │ │ │ ├── article.svg
│ │ │ │ ├── text-snippet.svg
│ │ │ │ ├── help-outline.svg
│ │ │ │ ├── highlight.svg
│ │ │ │ ├── share-black.svg
│ │ │ │ ├── android.svg
│ │ │ │ ├── apple.svg
│ │ │ │ ├── manage-accounts.svg
│ │ │ │ ├── language.svg
│ │ │ │ ├── waves.svg
│ │ │ │ └── Svg.re
│ │ │ ├── AddTagInput
│ │ │ │ └── AddTagInput.module.css
│ │ │ ├── Markdown
│ │ │ │ ├── Markdown.re
│ │ │ │ └── Markdown.module.css
│ │ │ ├── TagListItem
│ │ │ │ └── TagListItem_GraphQL.re
│ │ │ ├── AuthenticationFields
│ │ │ │ └── AuthenticationFields.module.css
│ │ │ ├── header.re
│ │ │ ├── FeatureIndicator
│ │ │ │ └── FeatureIndicator.re
│ │ │ ├── UnderlineLink
│ │ │ │ └── UnderlineLink.re
│ │ │ ├── ExternalTargetCard
│ │ │ │ ├── ExternalTargetCard_GraphQL.re
│ │ │ │ └── ExternalTargetCard.re
│ │ │ ├── TagList
│ │ │ │ └── TagList.re
│ │ │ ├── SourceList
│ │ │ │ └── SourceList.re
│ │ │ ├── Redirect.re
│ │ │ ├── BottomAlert.re
│ │ │ ├── ErrorBoundary
│ │ │ │ └── ErrorBoundary.re
│ │ │ ├── FloatingActionButton.re
│ │ │ ├── FeatureListItem
│ │ │ │ └── FeatureListItem.re
│ │ │ ├── Head.re
│ │ │ ├── FooterLink
│ │ │ │ └── FooterLink.re
│ │ │ └── PromptIconButton
│ │ │ │ └── PromptIconButton.re
│ │ ├── Lib
│ │ │ ├── Lib_GraphQL
│ │ │ │ ├── Lib_GraphQL_Language.re
│ │ │ │ ├── Lib_GraphQL_ResourceType.re
│ │ │ │ ├── Lib_GraphQL_TextDirection.re
│ │ │ │ ├── Lib_GraphQL_CreateAnnotationFromExternalTargetMutation.re
│ │ │ │ ├── Lib_GraphQL_Motivation.re
│ │ │ │ └── Lib_GraphQL_Agent.re
│ │ │ └── Lib_Apollo
│ │ │ │ └── Lib_Apollo_Cache.re
│ │ ├── Hooks
│ │ │ └── Hooks_SearchParams.re
│ │ ├── QueryRenderers
│ │ │ ├── QueryRenderers_NewAnnotation
│ │ │ │ └── QueryRenderers_NewAnnotation.re
│ │ │ ├── QueryRenderers_TagsFilter
│ │ │ │ └── QueryRenderers_TagsFilter_GraphQL.re
│ │ │ ├── QueryRenderers_NewAnnotationFromShare
│ │ │ │ └── QueryRenderers_NewAnnotationFromShare_GraphQL.re
│ │ │ └── QueryRenderers_WebView_EditAnnotationTags
│ │ │ │ └── QueryRenderers_WebView_EditAnnotationTags.re
│ │ ├── services
│ │ │ ├── Timer.re
│ │ │ └── Service_Log.re
│ │ ├── styles.re
│ │ ├── Containers
│ │ │ ├── Containers_NewAnnotationEditor
│ │ │ │ ├── Containers_NewAnnotationEditor_GraphQL.re
│ │ │ │ └── Containers_NewAnnotationEditor_Types.re
│ │ │ ├── Containers_AnnotationEditor
│ │ │ │ └── Containers_AnnotationEditor_Tag.re
│ │ │ ├── Containers_NewAnnotationFromShareHeader
│ │ │ │ └── Containers_NewAnnotationFromShareHeader_GraphQL.re
│ │ │ ├── Containers_NewAnnotationFromMessageEventHeader
│ │ │ │ └── Containers_NewAnnotationFromMessageEventHeader.re
│ │ │ ├── Containers_NewAnnotationHeader
│ │ │ │ └── Containers_NewAnnotationHeader.re
│ │ │ ├── Containers_NewAnnotationFromShareEditor
│ │ │ │ └── Containers_NewAnnotationFromShareEditor_GraphQL.re
│ │ │ └── Containers_AnnotationCollectionHeader
│ │ │ │ └── Containers_AnnotationCollectionHeader_GraphQL.re
│ │ ├── static
│ │ │ ├── json
│ │ │ │ └── writing.json
│ │ │ └── markdown
│ │ │ │ └── subprocessors.md
│ │ ├── Providers
│ │ │ ├── Providers_Apollo
│ │ │ │ ├── Providers_Apollo_Credentials.re
│ │ │ │ ├── Providers_Apollo_Client.re
│ │ │ │ └── Providers_Apollo_AppSync.re
│ │ │ ├── Providers_Authentication
│ │ │ │ ├── Providers_Authentication_Credentials.re
│ │ │ │ └── Providers_Authentication_GraphQL.re
│ │ │ ├── Providers_BottomNavigation
│ │ │ │ └── Providers_BottomNavigation.re
│ │ │ └── Providers_ModalNavigation
│ │ │ │ └── Providers_ModalNavigation.re
│ │ ├── routes
│ │ │ ├── Route_Creators_Id_Annotation_Collections.re
│ │ │ └── Route_Creators.re
│ │ └── app.css
│ ├── public
│ │ ├── logo-128.png
│ │ ├── favicon-32.png
│ │ ├── how-it-works-1.png
│ │ ├── how-it-works-2.png
│ │ ├── how-it-works-3.png
│ │ ├── how-it-works-4.png
│ │ ├── how-it-works-5.png
│ │ └── logo-opaque-128.png
│ ├── scripts
│ │ ├── bsb-post-clean.sh
│ │ ├── amplify-pull-staging.sh
│ │ ├── amplify-pull-production.sh
│ │ ├── graphql-sync-schema.sh
│ │ ├── generate-fragment-types.js
│ │ └── bsb-js-post-build.js
│ ├── postcss.config.js
│ ├── amplify
│ │ ├── .config
│ │ │ └── project-config.json
│ │ └── team-provider-info.json
│ ├── .gitignore
│ └── bsconfig.json
├── apollo-link-analytics
│ ├── .gitignore
│ ├── src
│ │ ├── ApolloLinkAnalytics.re
│ │ ├── ApolloLink.re
│ │ ├── ApolloLinkAnalytics.js
│ │ └── ApolloLink.js
│ ├── bsconfig.json
│ └── package.json
├── bs-amazon-cognito-identity-js
│ ├── .gitignore
│ ├── bsconfig.json
│ └── package.json
└── bs-sentry
│ ├── .gitignore
│ ├── bsconfig.json
│ ├── package.json
│ └── src
│ ├── SentryNode.re
│ └── SentryBrowser.re
├── .gitignore
├── lerna.json
└── package.json
/secret/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/metadata/en-US/video.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/metadata/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Literal
--------------------------------------------------------------------------------
/packages/android/.idea/.name:
--------------------------------------------------------------------------------
1 | Literal
--------------------------------------------------------------------------------
/packages/pamphlet/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | secret/
2 | node_modules
3 |
--------------------------------------------------------------------------------
/packages/android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/.nvmrc:
--------------------------------------------------------------------------------
1 | v15.9.0
2 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/packages/pamphlet/templates/android-launch/variables.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/packages/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name='Literal'
2 | include ':app'
3 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | "packages/*"
4 | ],
5 | "version": "0.0.0"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/bs-aws-sdk/.gitignore:
--------------------------------------------------------------------------------
1 | src/**/*.js
2 | .merlin
3 | .bsb.lock
4 | lib
5 | node_modules
6 |
--------------------------------------------------------------------------------
/packages/model/.gitignore:
--------------------------------------------------------------------------------
1 | src/**/*.bs.js
2 | .merlin
3 | .bsb.lock
4 | lib
5 | node_modules
6 |
--------------------------------------------------------------------------------
/packages/bs-amplitude/.gitignore:
--------------------------------------------------------------------------------
1 | src/**/*.bs.js
2 | .merlin
3 | .bsb.lock
4 | lib
5 | node_modules
6 |
--------------------------------------------------------------------------------
/packages/bs-aws-amplify/.gitignore:
--------------------------------------------------------------------------------
1 | src/**/*.js
2 | .merlin
3 | .bsb.lock
4 | lib
5 | node_modules
6 |
--------------------------------------------------------------------------------
/metadata/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Capture annotations, sources, and knowledge from text that you read.
--------------------------------------------------------------------------------
/packages/bs-aws-appsync/.gitignore:
--------------------------------------------------------------------------------
1 | src/**/*.bs.js
2 | .merlin
3 | .bsb.lock
4 | lib
5 | node_modules
6 |
--------------------------------------------------------------------------------
/packages/web/src/externals/Externals_Error.re:
--------------------------------------------------------------------------------
1 | [@bs.new] external make: string => Js.Exn.t = "Error";
2 |
--------------------------------------------------------------------------------
/packages/web/src/externals/uuid.re:
--------------------------------------------------------------------------------
1 | [@bs.val] [@bs.module "uuid"] external makeV4: unit => string = "v4";
2 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd "$(dirname "$0")" && npm run build
4 |
--------------------------------------------------------------------------------
/packages/apollo-link-analytics/.gitignore:
--------------------------------------------------------------------------------
1 | src/**/*.bs.js
2 | .merlin
3 | .bsb.lock
4 | lib
5 | node_modules
6 |
--------------------------------------------------------------------------------
/metadata/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/metadata/en-US/images/icon.png
--------------------------------------------------------------------------------
/packages/bs-amazon-cognito-identity-js/.gitignore:
--------------------------------------------------------------------------------
1 | src/**/*.js
2 | .merlin
3 | .bsb.lock
4 | lib
5 | node_modules
6 |
--------------------------------------------------------------------------------
/packages/web/public/logo-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/logo-128.png
--------------------------------------------------------------------------------
/packages/web/scripts/bsb-post-clean.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | find src/pages -name "*.js" -type f -delete
5 |
--------------------------------------------------------------------------------
/packages/bs-sentry/.gitignore:
--------------------------------------------------------------------------------
1 | lib/bs/
2 | lib/ocaml/
3 | src/**/*.js
4 | .merlin
5 | .bsb.lock
6 | node_modules
7 |
8 |
--------------------------------------------------------------------------------
/packages/web/public/favicon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/favicon-32.png
--------------------------------------------------------------------------------
/packages/web/scripts/amplify-pull-staging.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | amplify pull --appId d3h0fixyxiyfg5 --envName staging
4 |
--------------------------------------------------------------------------------
/packages/web/src/components/SourceListItem/SourceListItem.module.css:
--------------------------------------------------------------------------------
1 | .pathname {
2 | word-break: break-word;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/android/scripts/amplify-pull-staging.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | amplify pull --appId d3h0fixyxiyfg5 --envName staging
4 |
--------------------------------------------------------------------------------
/packages/web/scripts/amplify-pull-production.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | amplify pull --appId d3kn1jmjzilue --envName production
4 |
--------------------------------------------------------------------------------
/packages/android/scripts/amplify-pull-production.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | amplify pull --appId d3kn1jmjzilue --envName production
4 |
--------------------------------------------------------------------------------
/packages/web/public/how-it-works-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/how-it-works-1.png
--------------------------------------------------------------------------------
/packages/web/public/how-it-works-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/how-it-works-2.png
--------------------------------------------------------------------------------
/packages/web/public/how-it-works-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/how-it-works-3.png
--------------------------------------------------------------------------------
/packages/web/public/how-it-works-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/how-it-works-4.png
--------------------------------------------------------------------------------
/packages/web/public/how-it-works-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/how-it-works-5.png
--------------------------------------------------------------------------------
/packages/web/public/logo-opaque-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/web/public/logo-opaque-128.png
--------------------------------------------------------------------------------
/packages/web/src/components/TextInput/TextInput.re:
--------------------------------------------------------------------------------
1 | module Basic = TextInput_Basic;
2 | module Annotation = TextInput_Annotation;
3 |
--------------------------------------------------------------------------------
/metadata/en-US/images/featureGraphic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/metadata/en-US/images/featureGraphic.png
--------------------------------------------------------------------------------
/packages/android/app/src/beta/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Literal - Beta
3 |
4 |
--------------------------------------------------------------------------------
/packages/android/app/src/debug/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Literal - Debug
3 |
4 |
--------------------------------------------------------------------------------
/packages/model/src/Language.re:
--------------------------------------------------------------------------------
1 | type t = [ | `EN_US];
2 |
3 | let toString = t =>
4 | switch (t) {
5 | | `EN_US => "EN_US"
6 | };
7 |
--------------------------------------------------------------------------------
/packages/web/src/components/Skeleton/Skeleton.module.css:
--------------------------------------------------------------------------------
1 | .skeleton {
2 | background-color: rgba(255, 255, 255, .25) !important;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/Thunk.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public interface Thunk{
4 | void invoke();
5 | }
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/1_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/metadata/en-US/images/phoneScreenshots/1_en-US.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/2_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/metadata/en-US/images/phoneScreenshots/2_en-US.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/3_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/metadata/en-US/images/phoneScreenshots/3_en-US.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/4_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/metadata/en-US/images/phoneScreenshots/4_en-US.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/5_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/metadata/en-US/images/phoneScreenshots/5_en-US.png
--------------------------------------------------------------------------------
/packages/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/packages/model/src/ResourceType.re:
--------------------------------------------------------------------------------
1 | [@bs.deriving jsConverter]
2 | type t = [ | `DATASET | `IMAGE | `SOUND | `TEXT | `VIDEO];
3 |
4 | let toJs = tToJs;
5 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/font/roboto_mono.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/font/roboto_mono.ttf
--------------------------------------------------------------------------------
/packages/web/src/components/Loading.re:
--------------------------------------------------------------------------------
1 | open Styles;
2 |
3 | [@react.component]
4 | let make = () =>
;
5 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/AnnotationType.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum AnnotationType {
4 | ANNOTATION
5 | }
6 |
--------------------------------------------------------------------------------
/packages/web/src/Lib/Lib_GraphQL/Lib_GraphQL_Language.re:
--------------------------------------------------------------------------------
1 | type t = [ | `EN_US];
2 |
3 | let toString = t =>
4 | switch (t) {
5 | | `EN_US => "EN_US"
6 | };
7 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-hdpi/done_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-hdpi/done_white.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-mdpi/done_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-mdpi/done_white.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/font/roboto_mono_italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/font/roboto_mono_italic.ttf
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/SpecificResourceType.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum SpecificResourceType {
4 | SPECIFIC_RESOURCE
5 | }
6 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-hdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-hdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-mdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-mdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xhdpi/done_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xhdpi/done_white.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xxhdpi/done_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xxhdpi/done_white.png
--------------------------------------------------------------------------------
/packages/web/src/Lib/Lib_GraphQL/Lib_GraphQL_ResourceType.re:
--------------------------------------------------------------------------------
1 | [@bs.deriving jsConverter]
2 | type t = [ | `DATASET | `IMAGE | `SOUND | `TEXT | `VIDEO];
3 |
4 | let toJs = tToJs;
5 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/ErrorRepositoryLevel.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum ErrorRepositoryLevel {
4 | INFO,
5 | ERROR;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-hdpi/highlight_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-hdpi/highlight_white.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-mdpi/highlight_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-mdpi/highlight_white.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xhdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xhdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xxhdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xxhdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xxxhdpi/done_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xxxhdpi/done_white.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xhdpi/highlight_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xhdpi/highlight_white.png
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xxhdpi/highlight_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xxhdpi/highlight_white.png
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/32.txt:
--------------------------------------------------------------------------------
1 | Initial F-Droid release.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.24
4 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/33.txt:
--------------------------------------------------------------------------------
1 | Initial F-Droid release.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.25
4 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/Callback.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public interface Callback {
4 | void invoke(TError e, TData data);
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/Callback2.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public interface Callback2 {
4 | void invoke(Exception e, T1 data1, T2 data2);
5 | }
6 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/ResultCallback.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public interface ResultCallback {
4 | R invoke(Exception e, T data);
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-xxxhdpi/highlight_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/literal-io/literal/HEAD/packages/android/app/src/main/res/drawable-xxxhdpi/highlight_white.png
--------------------------------------------------------------------------------
/packages/model/src/TextDirection.re:
--------------------------------------------------------------------------------
1 | type t = [ | `LTR | `RTL | `AUTO];
2 |
3 | let toString = t =>
4 | switch (t) {
5 | | `LTR => "LTR"
6 | | `RTL => "RTL"
7 | | `AUTO => "AUTO"
8 | };
9 |
--------------------------------------------------------------------------------
/packages/web/src/components/TagsList/TagsList.module.css:
--------------------------------------------------------------------------------
1 | .underline {
2 | padding: 4px 0 7px;
3 | }
4 |
5 | .underline:after {
6 | border-bottom-color: rgba(255, 255, 255, .92) !important;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/Callback3.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public interface Callback3 {
4 | void invoke(Exception e, T1 data1, T2 data2, T3 data3);
5 | }
6 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/done.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/AddTagInput/AddTagInput.module.css:
--------------------------------------------------------------------------------
1 | .underline:before {
2 | border-bottom: none !important;
3 | }
4 | .underline:after {
5 | border-bottom-color: rgba(255, 255, 255, .72) !important;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/android/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/web/src/Lib/Lib_GraphQL/Lib_GraphQL_TextDirection.re:
--------------------------------------------------------------------------------
1 | type t = [ | `LTR | `RTL | `AUTO];
2 |
3 | let toString = t =>
4 | switch (t) {
5 | | `LTR => "LTR"
6 | | `RTL => "RTL"
7 | | `AUTO => "AUTO"
8 | };
9 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/arrow-right.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/back.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/36.txt:
--------------------------------------------------------------------------------
1 | Improves the rendering of annotations within web archives.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.28
4 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/add.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/TextInput/TextInput_Basic.module.css:
--------------------------------------------------------------------------------
1 | .underline:before {
2 | border-bottom-width: 0px !important;
3 | }
4 | .underline:after {
5 | border-bottom-color: rgba(255, 255, 255, .92) !important;
6 | }
7 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/34.txt:
--------------------------------------------------------------------------------
1 | Various stability improvements to annotation creation and capture.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.26
4 |
--------------------------------------------------------------------------------
/packages/android/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/JsonMapper.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import org.json.JSONException;
4 |
5 | public interface JsonMapper {
6 | Out invoke(In in) throws JSONException;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/model/src/Language.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | function toString(t) {
6 | return "EN_US";
7 | }
8 |
9 | exports.toString = toString;
10 | /* No side effect */
11 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/SourceInitializationStatus.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum SourceInitializationStatus {
4 | UNINITIALIZED,
5 | IN_PROGRESS,
6 | FAILED,
7 | INITIALIZED
8 | }
9 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/arrow-up.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 18dp
4 | 4dp
5 |
6 |
--------------------------------------------------------------------------------
/packages/web/src/components/Markdown/Markdown.re:
--------------------------------------------------------------------------------
1 | let styles = [%raw "require('./Markdown.module.css')"];
2 |
3 | [@react.component]
4 | let make = (~html) => {
5 | ;
6 | };
7 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/35.txt:
--------------------------------------------------------------------------------
1 | Improves stability of annotation creation to reduce crashes and improve capture reliability.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.27
4 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/39.txt:
--------------------------------------------------------------------------------
1 | Fixes tagging on annotation creation and tweaks annotation export to broaden share targets.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.30
4 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/arrow-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/delete.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/externals/Externals_URLSearchParams.re:
--------------------------------------------------------------------------------
1 | type t;
2 |
3 | [@bs.new] external make: string => t = "URLSearchParams";
4 | [@bs.new] external makeWithJson: Js.Json.t => t = "URLSearchParams";
5 | [@bs.send] external toString: t => string = "toString";
6 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/38.txt:
--------------------------------------------------------------------------------
1 | Adds annotation export (text and markdown) and includes source pathname when viewing a collection.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.30
4 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/Language.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum Language {
4 | EN_US;
5 |
6 | public type.Language toGraphQL() {
7 | return type.Language.valueOf(this.name());
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/delete-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/close.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable-hdpi/toast_accent_frame.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/37.txt:
--------------------------------------------------------------------------------
1 | Fixes a bug affecting creating annotations from source from within the application and polishes the color scheme.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.29
4 |
--------------------------------------------------------------------------------
/packages/web/src/components/TagListItem/TagListItem_GraphQL.re:
--------------------------------------------------------------------------------
1 | module AnnotationCollectionFragment = [%graphql
2 | {|
3 | fragment TagListItem_AnnotationCollection on AnnotationCollection {
4 | id
5 | label
6 | total
7 | }
8 | |}
9 | ];
10 |
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/31.txt:
--------------------------------------------------------------------------------
1 | Promotes the Collections view to be a top-level screen accessible via the bottom bar, and fixes bugs affecting source archiving.
2 |
3 | See the full release notes and source code for this release here: https://github.com/literal-io/literal/releases/tag/v1.1.23
--------------------------------------------------------------------------------
/packages/web/src/components/SourceListItem/SourceListItem_GraphQL.re:
--------------------------------------------------------------------------------
1 | module AnnotationCollectionFragment = [%graphql
2 | {|
3 | fragment SourceListItem_AnnotationCollection on AnnotationCollection {
4 | id
5 | label
6 | total
7 | }
8 | |}
9 | ];
10 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/JsonReaderParser.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import android.util.JsonReader;
4 |
5 | import java.io.IOException;
6 |
7 | public interface JsonReaderParser {
8 | public T invoke(JsonReader reader) throws IOException;
9 | }
10 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/Motivation.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum Motivation {
4 | TAGGING,
5 | HIGHLIGHTING;
6 |
7 | public type.Motivation toGraphQL() {
8 | return type.Motivation.valueOf(this.name());
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/web/src/Hooks/Hooks_SearchParams.re:
--------------------------------------------------------------------------------
1 | let use = parser => {
2 | let router = Next.Router.useRouter();
3 |
4 | router.asPath
5 | ->Js.String2.split("?")
6 | ->Belt.Array.get(1)
7 | ->Belt.Option.getWithDefault("")
8 | ->Webapi.Url.URLSearchParams.make
9 | ->parser;
10 | };
11 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/menu/source_webview_create_annotation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Sep 05 13:11:17 EDT 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/packages/web/src/components/Skeleton/Skeleton.re:
--------------------------------------------------------------------------------
1 | let styles = [%raw "require('./Skeleton.module.css')"];
2 |
3 | [@react.component]
4 | let make = (~variant, ~className=?) =>
5 | ;
9 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/add-circle.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/TextDirection.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum TextDirection {
4 | LTR,
5 | RTL,
6 | AUTO;
7 |
8 | public type.TextDirection toGraphQL() {
9 | return type.TextDirection.valueOf(this.name());
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/more.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/remove-circle.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/text-fields.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/apollo-link-analytics/src/ApolloLinkAnalytics.re:
--------------------------------------------------------------------------------
1 | let make = onOperation =>
2 | ApolloLink.make((operation, forward) => {
3 | forward(operation)
4 | ->ApolloLink.Observable.map(data => {
5 | onOperation(operation, data);
6 | data;
7 | })
8 | ->Js.Option.some
9 | });
10 |
--------------------------------------------------------------------------------
/packages/web/src/Lib/Lib_GraphQL/Lib_GraphQL_CreateAnnotationFromExternalTargetMutation.re:
--------------------------------------------------------------------------------
1 | module Input = {
2 | let make = (~creatorUsername, ~annotationId, ~externalTarget) => {
3 | "creatorUsername": creatorUsername,
4 | "annotationId": annotationId,
5 | "externalTarget": externalTarget,
6 | };
7 | };
8 |
--------------------------------------------------------------------------------
/packages/web/src/QueryRenderers/QueryRenderers_NewAnnotation/QueryRenderers_NewAnnotation.re:
--------------------------------------------------------------------------------
1 | open Styles;
2 |
3 | [@react.component]
4 | let make = (~identityId, ~initialPhaseState=?) =>
5 | <>
6 |
7 |
8 | >
9 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/toast_primary_frame.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/web/src/components/AuthenticationFields/AuthenticationFields.module.css:
--------------------------------------------------------------------------------
1 | .underline:after {
2 | border-bottom-color: rgba(255, 255, 255, .92) !important;
3 | }
4 |
5 | .underlineError {
6 | border: none !important;
7 | }
8 |
9 | .underlineError:after {
10 | border-bottom-color: #B00020 !important;
11 | }
12 |
--------------------------------------------------------------------------------
/packages/web/src/services/Timer.re:
--------------------------------------------------------------------------------
1 | let thunkP = (~label, fn) => {
2 | let begin_ = Js.Date.now();
3 | fn()
4 | |> Js.Promise.then_(result => {
5 | let end_ = Js.Date.now();
6 | Js.log3("timing", label, Js.Float.toString(end_ -. begin_) ++ "ms");
7 | Js.Promise.resolve(result);
8 | });
9 | };
10 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/ResourceType.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum ResourceType {
4 | DATASET,
5 | IMAGE,
6 | VIDEO,
7 | SOUND,
8 | TEXT;
9 |
10 | public type.ResourceType toGraphQL() {
11 | return type.ResourceType.valueOf(this.name());
12 | }
13 | }
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/error-outline.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/header.re:
--------------------------------------------------------------------------------
1 | open Styles;
2 |
3 | [@react.component]
4 | let make = (~children=React.null, ~className=?, ~style=?) =>
5 | ;
15 |
--------------------------------------------------------------------------------
/packages/web/src/externals/MaterialUiLab.re:
--------------------------------------------------------------------------------
1 | module Skeleton = {
2 | [@bs.module "@material-ui/lab/Skeleton/index.js"] [@react.component]
3 | external make:
4 | (
5 | ~variant: [@bs.string] [ | `text | `circle | `rect],
6 | ~classes: {. "root": string}=?
7 | ) =>
8 | React.element =
9 | "default";
10 | };
11 |
--------------------------------------------------------------------------------
/packages/web/src/services/Service_Log.re:
--------------------------------------------------------------------------------
1 | let log = (tag, message) =>
2 | if (Constants.Env.nodeEnv != "production") {
3 | Js.log2("[" ++ tag ++ "]", message);
4 | };
5 |
6 | let log2 = (tag, message1, message2) =>
7 | if (Constants.Env.nodeEnv != "production") {
8 | Js.log3("[" ++ tag ++ "]", message1, message2);
9 | };
10 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/label.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/font/font.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/packages/web/scripts/graphql-sync-schema.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | OWN_PATH=`realpath $0`
5 | ROOT_DIR=`realpath "$(dirname $OWN_PATH)/../"`
6 | AWS_PROFILE=amplify-literal
7 |
8 | aws appsync get-introspection-schema \
9 | --format JSON \
10 | --api-id $API_ID \
11 | --profile $AWS_PROFILE \
12 | "$ROOT_DIR/graphql-schema.json"
13 |
14 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/logo.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/packages/web/src/styles.re:
--------------------------------------------------------------------------------
1 | let cn = Cn.make;
2 |
3 | let style = ReactDOMRe.Style.make;
4 |
5 | let rem = r => Js.Float.toString(r) ++ "rem";
6 |
7 | let unsafeStyle = (style, unsafeList) =>
8 | List.fold_left(
9 | (acc, (prop, value)) =>
10 | ReactDOMRe.Style.unsafeAddProp(acc, prop, value),
11 | style,
12 | unsafeList,
13 | );
14 |
--------------------------------------------------------------------------------
/packages/model/src/TextDirection.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | function toString(t) {
6 | if (t === "RTL") {
7 | return "RTL";
8 | } else if (t === "AUTO") {
9 | return "AUTO";
10 | } else {
11 | return "LTR";
12 | }
13 | }
14 |
15 | exports.toString = toString;
16 | /* No side effect */
17 |
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_NewAnnotationEditor/Containers_NewAnnotationEditor_GraphQL.re:
--------------------------------------------------------------------------------
1 | module CreateAnnotationMutation = [%graphql
2 | {|
3 | mutation CreateAnnotation($input: CreateAnnotationInput!) {
4 | createAnnotation(input: $input) {
5 | annotation {
6 | id
7 | }
8 | }
9 | }
10 | |}
11 | ];
12 |
--------------------------------------------------------------------------------
/packages/web/src/externals/Apollo.re:
--------------------------------------------------------------------------------
1 | module Client = {
2 | type readFragmentArgs('a) = {
3 | fragment: ReasonApolloTypes.queryString,
4 | id: string,
5 | };
6 |
7 | [@bs.send] [@bs.return nullable]
8 | external readFragment:
9 | (ApolloClient.generatedApolloClient, readFragmentArgs('a)) =>
10 | option(Js.Json.t) =
11 | "readFragment";
12 | };
13 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/ArrayUtil.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import java.util.Arrays;
4 |
5 | public class ArrayUtil {
6 | public static T[] add(T[] arr, T item) {
7 | int idx = arr.length;
8 | T[] copy = Arrays.copyOf(arr, idx + 1);
9 | copy[idx] = item;
10 |
11 | return copy;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/Box.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public class Box {
4 | private T value;
5 |
6 | public Box(T init) {
7 | this.value = init;
8 | }
9 |
10 | public T get() {
11 | return value;
12 | }
13 |
14 | public void set(T value) {
15 | this.value = value;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/menu/source_webview_edit_annotation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/ic_baseline_arrow_drop_down_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/source.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | "tailwindcss",
4 | "postcss-flexbugs-fixes",
5 | [
6 | "postcss-preset-env",
7 | {
8 | autoprefixer: {
9 | flexbox: "no-2009",
10 | },
11 | stage: 3,
12 | features: {
13 | "custom-properties": false,
14 | },
15 | },
16 | ],
17 | ],
18 | };
19 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/article.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/menu/source_webview_commit_edit_annotation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/bs-amplitude/src/Amplitude.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | var getInstance = (function () {
6 | if (window) {
7 | return require("amplitude-js")
8 | } else {
9 | return {
10 | init: () => {},
11 | logWithEvent: () => {}
12 | }
13 | }
14 | });
15 |
16 | exports.getInstance = getInstance;
17 | /* No side effect */
18 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/annotation-renderer/util.mjs:
--------------------------------------------------------------------------------
1 | export const isElementInViewport = (elem) => {
2 | const rect = elem.getBoundingClientRect();
3 | return (
4 | rect.top >= 0 &&
5 | rect.left >= 0 &&
6 | rect.bottom <=
7 | (window.innerHeight || document.documentElement.clientHeight) &&
8 | rect.right <= (window.innerWidth || document.documentElement.clientWidth)
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/packages/bs-aws-sdk/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-aws-sdk",
3 | "reason": {
4 | "react-jsx": 3
5 | },
6 | "sources": {
7 | "dir": "src",
8 | "subdirs": true
9 | },
10 | "package-specs": [
11 | {
12 | "module": "es6-global",
13 | "in-source": true
14 | }
15 | ],
16 | "suffix": ".bs.js",
17 | "bs-dependencies": [],
18 | "ppx-flags": [],
19 | "refmt": 3
20 | }
21 |
--------------------------------------------------------------------------------
/packages/bs-sentry/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-sentry",
3 | "reason": {
4 | "react-jsx": 3
5 | },
6 | "sources": {
7 | "dir": "src",
8 | "subdirs": true
9 | },
10 | "package-specs": [
11 | {
12 | "module": "es6-global",
13 | "in-source": true
14 | }
15 | ],
16 | "suffix": ".bs.js",
17 | "bs-dependencies": [],
18 | "ppx-flags": [],
19 | "refmt": 3
20 | }
21 |
--------------------------------------------------------------------------------
/packages/pamphlet/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "esModuleInterop": true,
5 | "target": "es6",
6 | "noImplicitAny": true,
7 | "moduleResolution": "node",
8 | "sourceMap": true,
9 | "outDir": "dist",
10 | "baseUrl": ".",
11 | "paths": {
12 | "*": [
13 | "node_modules/*",
14 | "src/types/*"
15 | ]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/text-snippet.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/get-scripts/index.mjs:
--------------------------------------------------------------------------------
1 | import "core-js/index.js";
2 | import "regenerator-runtime/runtime.js";
3 |
4 | export default () => {
5 | return Array.from(document.scripts).map((scriptElem) => ({
6 | attributes: Array.from(scriptElem.attributes).reduce(
7 | (agg, attr) => ({ ...agg, [attr.name]: attr.value }),
8 | {}
9 | ),
10 | text: scriptElem.text,
11 | }));
12 | };
13 |
--------------------------------------------------------------------------------
/packages/bs-amplitude/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-amplitude",
3 | "reason": {
4 | "react-jsx": 3
5 | },
6 | "sources": {
7 | "dir": "src",
8 | "subdirs": true
9 | },
10 | "package-specs": [
11 | {
12 | "module": "es6-global",
13 | "in-source": true
14 | }
15 | ],
16 | "suffix": ".bs.js",
17 | "bs-dependencies": [],
18 | "ppx-flags": [],
19 | "refmt": 3
20 | }
21 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/help-outline.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/menu/source_webview_toolbar_create.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/components/FeatureIndicator/FeatureIndicator.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~enabled, ~className=?) =>
3 | ;
15 |
--------------------------------------------------------------------------------
/packages/web/src/externals/Externals_Crypto.re:
--------------------------------------------------------------------------------
1 | type textEncoder;
2 |
3 | [@bs.new] external makeTextEncoder: unit => textEncoder = "TextEncoder";
4 | [@bs.send]
5 | external encode: (textEncoder, string) => Js.TypedArray2.Uint8Array.t =
6 | "encode";
7 |
8 | [@bs.val] [@bs.scope ("window", "crypto", "subtle")]
9 | external digest:
10 | (string, Js.TypedArray2.Uint8Array.t) =>
11 | Js.Promise.t(Js.TypedArray2.array_buffer) =
12 | "digest";
13 |
--------------------------------------------------------------------------------
/packages/bs-amazon-cognito-identity-js/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-amazon-cognito-identity-js",
3 | "reason": {
4 | "react-jsx": 3
5 | },
6 | "sources": {
7 | "dir": "src",
8 | "subdirs": true
9 | },
10 | "package-specs": [
11 | {
12 | "module": "es6-global",
13 | "in-source": true
14 | }
15 | ],
16 | "suffix": ".bs.js",
17 | "bs-dependencies": [],
18 | "ppx-flags": [],
19 | "refmt": 3
20 | }
21 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/highlight.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/model/src/Format.re:
--------------------------------------------------------------------------------
1 | type t = [
2 | | `TEXT_PLAIN
3 | | `TEXT_HTML
4 | | `APPLICATION_OCTET_STREAM
5 | | `APPLICATION_X_MIMEARCHIVE
6 | | `IMAGE_PNG
7 | ];
8 |
9 | let toString = t =>
10 | switch (t) {
11 | | `TEXT_PLAIN => "TEXT_PLAIN"
12 | | `TEXT_HTML => "TEXT_HTML"
13 | | `APPLICATION_X_MIMEARCHIVE => "APPLICATION_X_MIMEARCHIVE"
14 | | `APPLICATION_OCTET_STREAM => "APPLICATION_OCTET_STREAM"
15 | | `IMAGE_PNG => "IMAGE_PNG"
16 | };
17 |
--------------------------------------------------------------------------------
/packages/web/amplify/.config/project-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "providers": [
3 | "awscloudformation"
4 | ],
5 | "projectName": "literal - production",
6 | "version": "3.0",
7 | "frontend": "javascript",
8 | "javascript": {
9 | "framework": "react",
10 | "config": {
11 | "SourceDir": "src",
12 | "DistributionDir": "out",
13 | "BuildCommand": "npm run-script build",
14 | "StartCommand": "npm run-script start"
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_NewAnnotationEditor/Containers_NewAnnotationEditor_Types.re:
--------------------------------------------------------------------------------
1 | [@bs.deriving jsConverter]
2 | type phase = [ | `PhasePrompt | `PhaseTextInput];
3 |
4 | let phase_encode = p => p->phaseToJs->Js.Json.string;
5 | let phase_decode = json =>
6 | switch (json->Js.Json.decodeString->Belt.Option.flatMap(phaseFromJs)) {
7 | | Some(p) => Ok(p)
8 | | None =>
9 | Error(Decco.{path: "", message: "Not a phase value.", value: json})
10 | };
11 |
12 |
--------------------------------------------------------------------------------
/packages/model/src/ResourceType.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | var _map = {"DATASET":"DATASET","IMAGE":"IMAGE","SOUND":"SOUND","TEXT":"TEXT","VIDEO":"VIDEO"};
6 |
7 | function tToJs(param) {
8 | return param;
9 | }
10 |
11 | function tFromJs(param) {
12 | return _map[param];
13 | }
14 |
15 | var toJs = tToJs;
16 |
17 | exports.tToJs = tToJs;
18 | exports.tFromJs = tFromJs;
19 | exports.toJs = toJs;
20 | /* No side effect */
21 |
--------------------------------------------------------------------------------
/packages/bs-aws-amplify/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-aws-amplify",
3 | "reason": {
4 | "react-jsx": 3
5 | },
6 | "sources": {
7 | "dir": "src",
8 | "subdirs": true
9 | },
10 | "package-specs": [
11 | {
12 | "module": "es6-global",
13 | "in-source": true
14 | }
15 | ],
16 | "suffix": ".bs.js",
17 | "bs-dependencies": ["bs-webapi", "@literal-io/bs-amazon-cognito-identity-js"],
18 | "ppx-flags": [],
19 | "refmt": 3
20 | }
21 |
--------------------------------------------------------------------------------
/packages/web/scripts/generate-fragment-types.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require("fs");
4 | const path = require("path");
5 |
6 | const schema = require("../graphql-schema.json");
7 |
8 | const fragmentTypes = schema.data.__schema.types.filter(
9 | (type) => type.possibleTypes !== null
10 | );
11 |
12 | schema.data.__schema.types = fragmentTypes;
13 |
14 | fs.writeFileSync(
15 | path.resolve(__dirname, "../fragment-types.json"),
16 | JSON.stringify(schema.data)
17 | );
18 |
--------------------------------------------------------------------------------
/packages/android/app/src/test/java/io/literal/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package io.literal;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/packages/web/src/components/UnderlineLink/UnderlineLink.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~text, ~href) =>
3 |
4 |
15 | {React.string(text)}
16 |
17 | ;
18 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/AnnotationLib.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public class AnnotationLib {
4 | public static String idComponentFromId(String annotationId) {
5 | String[] parts = annotationId.split("/");
6 | return parts[parts.length - 1];
7 | }
8 |
9 | public static String creatorUsernameFromId(String annotationId) {
10 | String[] parts = annotationId.split("/");
11 | return parts[parts.length - 3];
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/android/scripts/graphql-sync-schema-staging.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | OWN_PATH=`realpath $0`
5 | ROOT_DIR=`realpath "$(dirname $OWN_PATH)/../"`
6 | AWS_PROFILE=amplify-literal
7 | API_ID=to6hgjbvbjb7roq46jyzhxr2my
8 |
9 | aws appsync get-introspection-schema \
10 | --format JSON \
11 | --api-id $API_ID \
12 | --profile $AWS_PROFILE \
13 | "$ROOT_DIR/app/src/main/graphql/schema.json"
14 |
15 | # Warning: overrites any manual tuning in autogenerated files
16 | # amplify codegen
17 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/shared/storage.mjs:
--------------------------------------------------------------------------------
1 | const NAMESPACE = "__literal";
2 |
3 | export const KEY_SERVICE_HIGHLIGHTER = "SERVICE_HIGHLIGHTER"
4 | export const KEY_SERVICE_ANNOTATION_FOCUS_MANAGER = "SERVICE_ANNOTATION_FOCUS_MANAGER"
5 |
6 | export const initialize = () => {
7 | window[NAMESPACE] = window[NAMESPACE] || {};
8 | };
9 |
10 | export const set = (key, value) => {
11 | window[NAMESPACE][key] = value;
12 | };
13 |
14 | export const get = (key) => window[NAMESPACE][key];
15 |
--------------------------------------------------------------------------------
/packages/android/scripts/graphql-sync-schema-production.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | OWN_PATH=`realpath $0`
5 | ROOT_DIR=`realpath "$(dirname $OWN_PATH)/../"`
6 | AWS_PROFILE=amplify-literal
7 | API_ID=rkihsloeqbdabdpebem3fqqjuy
8 |
9 | aws appsync get-introspection-schema \
10 | --format JSON \
11 | --api-id $API_ID \
12 | --profile $AWS_PROFILE \
13 | "$ROOT_DIR/app/src/main/graphql/schema.json"
14 |
15 | # Warning: overrites any manual tuning in autogenerated files
16 | # amplify codegen
17 |
--------------------------------------------------------------------------------
/packages/web/src/externals/LiteralWebview.re:
--------------------------------------------------------------------------------
1 | type literalWebview;
2 | [@bs.get] [@bs.return nullable]
3 | external inst: Dom.window => option(literalWebview) = "literalWebview";
4 |
5 | [@bs.send] external isWebview: literalWebview => bool = "isWebview";
6 | [@bs.send] external getVersionName: literalWebview => string = "getVersionName";
7 | [@bs.send] external isFlavorFoss: literalWebview => bool = "isFlavorFoss";
8 |
9 | [@bs.send]
10 | external sendMessagePort: literalWebview => unit = "sendMessagePort";
11 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/layout/authentication_handler.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/values-v28/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
--------------------------------------------------------------------------------
/packages/web/src/static/json/writing.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "Implementing Guest Authentication with AWS Amplify",
4 | "subtitle": "A technical walkthrough of Literal's guest authentication implementation.",
5 | "date": "2021-06-08",
6 | "filename": "implementing-guest-authentication-with-amplify-cognito-appsync"
7 | },
8 | {
9 | "title": "Prologue",
10 | "subtitle": "Introducing Literal, today and tomorrow.",
11 | "date": "2020-12-26",
12 | "filename": "prologue"
13 | }
14 | ]
15 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/share-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/DateUtil.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import java.text.DateFormat;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 | import java.util.TimeZone;
7 |
8 | public class DateUtil {
9 | public static String toISO8601UTC(Date date) {
10 | TimeZone tz = TimeZone.getTimeZone("UTC");
11 | DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
12 | df.setTimeZone(tz);
13 | return df.format(date);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/model/src/Motivation.re:
--------------------------------------------------------------------------------
1 | let toString = t =>
2 | switch (t) {
3 | | `TAGGING => "TAGGING"
4 | | `ACCESSING => "ACCESSING"
5 | | `BOOKMARKING => "BOOKMARKING"
6 | | `CLASSIFYING => "CLASSIFYING"
7 | | `COMMENTING => "COMMENTING"
8 | | `DESCRIBING => "DESCRIBING"
9 | | `EDITING => "EDITING"
10 | | `HIGHLIGHTING => "HIGHLIGHTING"
11 | | `IDENTIFYING => "IDENTIFYING"
12 | | `LINKING => "LINKING"
13 | | `MODERATING => "MODERATING"
14 | | `QUESTIONING => "QUESTIONING"
15 | | `REPLYING => "REPLYING"
16 | };
17 |
--------------------------------------------------------------------------------
/packages/web/src/components/ExternalTargetCard/ExternalTargetCard_GraphQL.re:
--------------------------------------------------------------------------------
1 | module ExternalTargetFragment = [%graphql
2 | {|
3 | fragment externalTargetCard_ExternalTargetFragment on ExternalTarget {
4 | externalTargetId: id
5 | format
6 | __typename
7 | }
8 | |}
9 | ];
10 |
11 | module TextualTargetFragment = [%graphql
12 | {|
13 | fragment externalTargetCard_TextualTargetFragment on TextualTarget {
14 | textualTargetId: id
15 | value
16 | __typename
17 | }
18 | |}
19 | ];
20 |
--------------------------------------------------------------------------------
/packages/android/.graphqlconfig.yml:
--------------------------------------------------------------------------------
1 | projects:
2 | literal:
3 | schemaPath: app/src/main/graphql/schema.json
4 | includes:
5 | - app/src/main/graphql/**/*.graphql
6 | excludes:
7 | - ./amplify/**
8 | extensions:
9 | amplify:
10 | codeGenTarget: ''
11 | generatedFileName: ''
12 | docsFilePath: app/src/main/graphql/com/amazonaws/amplify/generated/graphql
13 | region: us-east-1
14 | apiId: null
15 | maxDepth: 2
16 | extensions:
17 | amplify:
18 | version: 3
19 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/ic_baseline_more_vert_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/web/src/Lib/Lib_GraphQL/Lib_GraphQL_Motivation.re:
--------------------------------------------------------------------------------
1 | let toString = t =>
2 | switch (t) {
3 | | `TAGGING => "TAGGING"
4 | | `ACCESSING => "ACCESSING"
5 | | `BOOKMARKING => "BOOKMARKING"
6 | | `CLASSIFYING => "CLASSIFYING"
7 | | `COMMENTING => "COMMENTING"
8 | | `DESCRIBING => "DESCRIBING"
9 | | `EDITING => "EDITING"
10 | | `HIGHLIGHTING => "HIGHLIGHTING"
11 | | `IDENTIFYING => "IDENTIFYING"
12 | | `LINKING => "LINKING"
13 | | `MODERATING => "MODERATING"
14 | | `QUESTIONING => "QUESTIONING"
15 | | `REPLYING => "REPLYING"
16 | };
17 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/ic_baseline_build_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/Constants.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | public class Constants {
4 | public static final String NAMESPACE = "io.literal";
5 | public static final String LOG_TAG = "Literal";
6 |
7 | public static final String RECENT_ANNOTATION_COLLECTION_ID_COMPONENT = "034a7e52c5c9534b709dc1dba403868399b0949f7c1933a67325c22077ffc221";
8 | public static final String RECENT_ANNOTATION_COLLECTION_LABEL = "recent";
9 |
10 | public static final String INTENT_MANUAL_FOR_RESULT_DATA = "MANUAL_FOR_RESULT_DATA";
11 | }
12 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #0C0C0C
4 | #0C0C0C
5 | #2A2A2A
6 | #2A2A2A
7 | #E0E0E0
8 | #F2FFFFFF
9 | #99FFFFFF
10 | #EB000000
11 |
12 |
--------------------------------------------------------------------------------
/packages/model/src/Format.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | function toString(t) {
6 | if (t === "TEXT_HTML") {
7 | return "TEXT_HTML";
8 | } else if (t === "APPLICATION_OCTET_STREAM") {
9 | return "APPLICATION_OCTET_STREAM";
10 | } else if (t === "TEXT_PLAIN") {
11 | return "TEXT_PLAIN";
12 | } else if (t === "APPLICATION_X_MIMEARCHIVE") {
13 | return "APPLICATION_X_MIMEARCHIVE";
14 | } else {
15 | return "IMAGE_PNG";
16 | }
17 | }
18 |
19 | exports.toString = toString;
20 | /* No side effect */
21 |
--------------------------------------------------------------------------------
/packages/bs-aws-appsync/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-aws-appsync",
3 | "reason": {
4 | "react-jsx": 3
5 | },
6 | "sources": {
7 | "dir": "src",
8 | "subdirs": true
9 | },
10 | "package-specs": [
11 | {
12 | "module": "es6-global",
13 | "in-source": true
14 | }
15 | ],
16 | "suffix": ".bs.js",
17 | "bs-dependencies": [
18 | "reason-react",
19 | "reason-apollo",
20 | "@literal-io/bs-aws-amplify",
21 | "@literal-io/bs-amazon-cognito-identity-js"
22 | ],
23 | "ppx-flags": [],
24 | "refmt": 3
25 | }
26 |
--------------------------------------------------------------------------------
/packages/model/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/model",
3 | "version": "1.0.0",
4 | "reason": {
5 | "react-jsx": 3
6 | },
7 | "sources": [
8 | {
9 | "dir": "src",
10 | "subdirs": true
11 | }
12 | ],
13 | "package-specs": {
14 | "module": "commonjs",
15 | "in-source": true
16 | },
17 | "suffix": ".js",
18 | "bs-dependencies": [
19 | "decco"
20 | ],
21 | "ppx-flags": [
22 | "decco/ppx"
23 | ],
24 | "warnings": {
25 | "error": "+101"
26 | },
27 | "namespace": "LiteralModel",
28 | "refmt": 3
29 | }
30 |
--------------------------------------------------------------------------------
/packages/web/src/components/TagList/TagList.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~data, ~renderItem, ~itemKey, ~itemClassName, ~className=?) =>
3 |
10 | {data
11 | ->Belt.Array.mapWithIndex((idx, item) =>
12 | -
14 | {renderItem(~item, ~idx)}
15 |
16 | )
17 | ->React.array}
18 |
;
19 |
--------------------------------------------------------------------------------
/packages/web/src/components/SourceList/SourceList.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~data, ~renderItem, ~itemKey, ~itemClassName, ~className=?) =>
3 |
10 | {data
11 | ->Belt.Array.mapWithIndex((idx, item) =>
12 | -
14 | {renderItem(~item, ~idx)}
15 |
16 | )
17 | ->React.array}
18 |
;
19 |
--------------------------------------------------------------------------------
/packages/web/.gitignore:
--------------------------------------------------------------------------------
1 | lib/bs
2 | src/**/*.js
3 | .merlin
4 | .bsb.lock
5 |
6 | amplify/backend
7 |
8 | .graphql_ppx_cache
9 |
10 | out
11 | .next
12 |
13 | #amplify
14 | amplify/\#current-cloud-backend
15 | amplify/.config/local-*
16 | amplify/logs
17 | amplify/mock-data
18 | amplify/backend/amplify-meta.json
19 | amplify/backend/awscloudformation
20 | amplify/backend/.temp
21 | build/
22 | dist/
23 | node_modules/
24 | aws-exports.js
25 | awsconfiguration.json
26 | amplifyconfiguration.json
27 | amplify-build-config.json
28 | amplify-gradle-config.json
29 | amplifytools.xcconfig
30 | .secret-*
--------------------------------------------------------------------------------
/packages/web/src/QueryRenderers/QueryRenderers_TagsFilter/QueryRenderers_TagsFilter_GraphQL.re:
--------------------------------------------------------------------------------
1 | module AnnotationCollectionLabelAutocomplete = [%graphql
2 | {|
3 | query annotationCollectionLabelAutocomplete(
4 | $creatorUsername: String!,
5 | $labelBeginsWith: String!
6 | ) {
7 | listAnnotationCollectionsByLabel(
8 | creatorUsername: $creatorUsername,
9 | label: {
10 | beginsWith: $labelBeginsWith
11 | }
12 | ) {
13 | items {
14 | id
15 | label
16 | }
17 | }
18 | }
19 | |}
20 | ];
21 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/drawable/ic_logo.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/apollo-link-analytics/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/apollo-link-analytics",
3 | "sources": {
4 | "dir": "src",
5 | "subdirs": true
6 | },
7 | "reason": {
8 | "react-jsx": 3
9 | },
10 | "package-specs": [
11 | {
12 | "module": "es6-global",
13 | "in-source": true
14 | }
15 | ],
16 | "suffix": ".bs.js",
17 | "bs-dependencies": [
18 | "reason-apollo"
19 | ],
20 | "bs-devDependencies": [
21 | "reason-react"
22 | ],
23 | "bsc-flags": [
24 | "-bs-super-errors"
25 | ],
26 | "ppx-flags": [],
27 | "refmt": 3
28 | }
29 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/wrap-dist-with-executor.mjs:
--------------------------------------------------------------------------------
1 | import { readdirSync, readFileSync, writeFileSync, mkdirSync } from "fs";
2 |
3 | const OUTPUT_DIR = new URL("../app/src/main/assets/", import.meta.url);
4 | const INPUT_DIR = new URL("./dist/", import.meta.url);
5 |
6 | const wrapExecutor = (contents) => contents + "\n Literal.default();";
7 |
8 | mkdirSync(OUTPUT_DIR, { recursive: true })
9 |
10 | readdirSync(INPUT_DIR).forEach((fileName) => {
11 | writeFileSync(
12 | new URL(fileName, OUTPUT_DIR),
13 | wrapExecutor(readFileSync(new URL(fileName, INPUT_DIR)))
14 | );
15 | });
16 |
--------------------------------------------------------------------------------
/packages/web/src/components/Redirect.re:
--------------------------------------------------------------------------------
1 | let encodeSearch = [%raw
2 | {|
3 | function encodeSearch(o) {
4 | return "?" + (new URLSearchParams(o)).toString()
5 | }
6 | |}
7 | ];
8 |
9 | [@react.component]
10 | let make = (~path, ~staticPath, ~search=?, ~children) => {
11 | let _ =
12 | React.useEffect0(_ => {
13 | let stringifiedSearch =
14 | search
15 | ->Belt.Option.map(encodeSearch)
16 | ->Belt.Option.getWithDefault("");
17 | let _ =
18 | Next.Router.(replaceWithAs(staticPath, path ++ stringifiedSearch));
19 | None;
20 | });
21 | children;
22 | };
23 |
--------------------------------------------------------------------------------
/packages/android/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/SourceJavaScriptConfig.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public class SourceJavaScriptConfig {
4 | public enum Reason {
5 | AUTOMATIC,
6 | USER_TOGGLED
7 | }
8 | private final boolean isEnabled;
9 | private final Reason reason;
10 |
11 | public SourceJavaScriptConfig(boolean isEnabled, Reason reason) {
12 | this.isEnabled = isEnabled;
13 | this.reason = reason;
14 | }
15 |
16 | public boolean isEnabled() {
17 | return isEnabled;
18 | }
19 |
20 | public Reason getReason() {
21 | return reason;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/layout/fragment_app_web_view.xml:
--------------------------------------------------------------------------------
1 |
8 |
14 |
--------------------------------------------------------------------------------
/packages/apollo-link-analytics/src/ApolloLink.re:
--------------------------------------------------------------------------------
1 | module Observable = {
2 | type t;
3 |
4 | [@bs.send] external map: (t, Js.Json.t => Js.Json.t) => t = "map";
5 | };
6 |
7 | [@bs.deriving accessors]
8 | type operation = {
9 | query: Js.Json.t,
10 | variables: Js.Json.t,
11 | operationName: string,
12 | extensions: Js.Json.t,
13 | setContext: Js.Json.t => Js.Json.t,
14 | getContext: unit => Js.Json.t,
15 | toKey: unit => string,
16 | };
17 |
18 | type requestHandler =
19 | (operation, operation => Observable.t) => option(Observable.t);
20 |
21 | [@bs.new] [@bs.module "apollo-link"]
22 | external make: requestHandler => ReasonApolloTypes.apolloLink = "ApolloLink";
23 |
--------------------------------------------------------------------------------
/packages/web/src/components/BottomAlert.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~text) =>
3 |
14 |
15 | {React.string(text)}
16 |
17 |
26 |
;
27 |
--------------------------------------------------------------------------------
/packages/bs-aws-appsync/src/AwsAppSync.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | function authWithCognitoUserPools(jwtToken) {
6 | return {
7 | type: "AMAZON_COGNITO_USER_POOLS",
8 | jwtToken: jwtToken
9 | };
10 | }
11 |
12 | function authWithIAM(credentials) {
13 | return {
14 | type: "AWS_IAM",
15 | credentials: credentials
16 | };
17 | }
18 |
19 | var Client = {
20 | authWithCognitoUserPools: authWithCognitoUserPools,
21 | authWithIAM: authWithIAM
22 | };
23 |
24 | var Rehydrated = {};
25 |
26 | exports.Client = Client;
27 | exports.Rehydrated = Rehydrated;
28 | /* No side effect */
29 |
--------------------------------------------------------------------------------
/packages/web/src/components/ErrorBoundary/ErrorBoundary.re:
--------------------------------------------------------------------------------
1 | module RawErrorBoundary = {
2 | [@bs.module "./raw-error-boundary.js"] [@react.component]
3 | external make:
4 | (
5 | ~onComponentDidCatch: Js.Exn.t => unit,
6 | ~renderErrorBoundary: unit => React.element,
7 | ~children: React.element
8 | ) =>
9 | React.element =
10 | "default";
11 | };
12 |
13 | [@react.component]
14 | let make = (~children) => {
15 | }
17 | onComponentDidCatch={error => {
18 | let _ = SentryBrowser.captureException(error);
19 | ();
20 | }}>
21 | children
22 | ;
23 | };
24 |
--------------------------------------------------------------------------------
/packages/web/src/components/FloatingActionButton.re:
--------------------------------------------------------------------------------
1 | open Styles;
2 |
3 | [@react.component]
4 | let make = (~onClick=?, ~className=?, ~disabled=?, ~children) =>
5 |
6 |
10 | children
11 |
25 |
26 |
;
27 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/layout/splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
16 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/android.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/model/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/model",
3 | "version": "1.0.0",
4 | "description": "BuckleScript bindings for the Web Annotation data model as implemented by Literal.",
5 | "repository": "https://github.com/literal-io/literal/tree/master/packages/model",
6 | "main": "index.js",
7 | "scripts": {
8 | "bsb:build": "bsb -make-world",
9 | "bsb:start": "bsb -make-world -w",
10 | "bsb:clean": "bsb -clean-world"
11 | },
12 | "author": {
13 | "name": "Daniel Ramirez",
14 | "email": "javamonn@hey.com",
15 | "url": "https://javamonn.com"
16 | },
17 | "license": "MIT - Hippocratic 1.2",
18 | "devDependencies": {
19 | "bs-platform": "^8.4.2",
20 | "decco": "^1.3.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/packages/web/src/Providers/Providers_Apollo/Providers_Apollo_Credentials.re:
--------------------------------------------------------------------------------
1 | [@decco]
2 | type tokens = {
3 | idToken: string,
4 | refreshToken: string,
5 | accessToken: string,
6 | };
7 |
8 | [@decco]
9 | type awsCredentials = {
10 | accessKeyId: string,
11 | secretAccessKey: string,
12 | identityId: string,
13 | sessionToken: string,
14 | };
15 |
16 | external fromAmplifyCredentials: AwsAmplify.Credentials.t => awsCredentials =
17 | "%identity";
18 |
19 | external toAmplifyCredentials: awsCredentials => AwsAmplify.Credentials.t =
20 | "%identity";
21 |
22 | [@decco]
23 | type t = {
24 | tokens: option(tokens),
25 | awsCredentials: option(awsCredentials),
26 | };
27 |
28 | let decode = t_decode;
29 | let encode = t_encode;
30 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/AnnotationCollectionLib.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import io.literal.repository.ErrorRepository;
4 |
5 | public class AnnotationCollectionLib {
6 | public static String makeId(String creatorUsername, String labelText) {
7 | try {
8 | String idComponent = Crypto.sha256Hex(labelText);
9 | return WebRoutes.creatorsIdAnnotationCollectionId(
10 | WebRoutes.getAPIHost(),
11 | creatorUsername,
12 | idComponent
13 | );
14 | } catch (java.security.NoSuchAlgorithmException ex) {
15 | ErrorRepository.captureException(ex);
16 | return null;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/apollo-link-analytics/src/ApolloLinkAnalytics.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Curry = require("bs-platform/lib/js/curry.js");
5 | var Js_option = require("bs-platform/lib/js/js_option.js");
6 | var ApolloLink = require("apollo-link");
7 |
8 | function make(onOperation) {
9 | return new ApolloLink.ApolloLink((function (operation, forward) {
10 | return Js_option.some(Curry._1(forward, operation).map(function (data) {
11 | Curry._2(onOperation, operation, data);
12 | return data;
13 | }));
14 | }));
15 | }
16 |
17 | exports.make = make;
18 | /* apollo-link Not a pure module */
19 |
--------------------------------------------------------------------------------
/packages/pamphlet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/pamphlet",
3 | "version": "1.0.0",
4 | "description": "Email templates",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "ts-node index.ts"
9 | },
10 | "repository": "https://github.com/literal-io/literal/tree/master/packages/pamphlet",
11 | "author": {
12 | "name": "Daniel Ramirez",
13 | "email": "javamonn@hey.com",
14 | "url": "https://javamonn.com"
15 | },
16 | "license": "MIT - Hippocratic 1.2",
17 | "dependencies": {
18 | "mjml": "^4.8.0",
19 | "ts-node": "^9.1.1",
20 | "typescript": "^4.1.3"
21 | },
22 | "devDependencies": {
23 | "@types/mjml": "^4.7.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/web/src/Providers/Providers_Authentication/Providers_Authentication_Credentials.re:
--------------------------------------------------------------------------------
1 | [@decco]
2 | type tokens = {
3 | idToken: string,
4 | refreshToken: string,
5 | accessToken: string,
6 | };
7 |
8 | [@decco]
9 | type awsCredentials = {
10 | accessKeyId: string,
11 | secretAccessKey: string,
12 | identityId: string,
13 | sessionToken: string,
14 | };
15 |
16 | external fromAmplifyCredentials: AwsAmplify.Credentials.t => awsCredentials =
17 | "%identity";
18 |
19 | external toAmplifyCredentials: awsCredentials => AwsAmplify.Credentials.t =
20 | "%identity";
21 |
22 | [@decco]
23 | type t = {
24 | tokens: option(tokens),
25 | awsCredentials: option(awsCredentials),
26 | };
27 |
28 | let decode = t_decode;
29 | let encode = t_encode;
30 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/shared/xpath.mjs:
--------------------------------------------------------------------------------
1 | export const evaluate = (value) =>
2 | document.evaluate(
3 | value,
4 | document,
5 | null,
6 | XPathResult.FIRST_ORDERED_NODE_TYPE,
7 | null
8 | ).singleNodeValue;
9 |
10 | export const xPathRangeSelectorPredicate = ({
11 | type,
12 | startSelector,
13 | endSelector,
14 | }) =>
15 | type === "RANGE_SELECTOR" &&
16 | startSelector.type === "XPATH_SELECTOR" &&
17 | (startSelector.refinedBy || []).some(
18 | (refinedBySelector) => refinedBySelector.type === "TEXT_POSITION_SELECTOR"
19 | ) &&
20 | endSelector.type === "XPATH_SELECTOR" &&
21 | (endSelector.refinedBy || []).some(
22 | (refinedBySelector) => refinedBySelector.type === "TEXT_POSITION_SELECTOR"
23 | );
24 |
--------------------------------------------------------------------------------
/packages/web/src/externals/raw.re:
--------------------------------------------------------------------------------
1 | let merge = [%raw {|
2 | function(a, b) { return {...a, ...b} }
3 | |}];
4 |
5 | let unsafeEq = [%raw
6 | {| function(a, b) { return a === b } |}
7 | ];
8 |
9 | let global = [%raw {|
10 | function () {
11 | if (typeof self !== 'undefined') { return self; }
12 | if (typeof window !== 'undefined') { return window; }
13 | if (typeof global !== 'undefined') { return global; }
14 | throw new Error('unable to locate global object');
15 | }
16 | |}];
17 |
18 | let isBrowser = [%raw {|
19 | function () {
20 | return typeof window !== 'undefined'
21 | }
22 | |}];
23 |
24 | let maybeScrollTo = [%raw {|
25 | function (elem, params) {
26 | if (elem.scrollTo) {
27 | elem.scrollTo(params)
28 | }
29 | }
30 | |}];
31 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "source-webview-scripts",
3 | "version": "1.0.0",
4 | "type": "module",
5 | "description": "",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "npm run build:webpack && npm run build:wrap-executor",
9 | "build:webpack": "webpack",
10 | "build:wrap-executor": "node ./wrap-dist-with-executor.mjs"
11 | },
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "@babel/core": "^7.13.16",
16 | "@babel/preset-env": "^7.13.15",
17 | "babel-loader": "^8.2.2",
18 | "core-js": "^3.11.1",
19 | "regenerator-runtime": "^0.13.7",
20 | "webpack": "^5.24.3",
21 | "webpack-cli": "^4.5.0"
22 | },
23 | "dependencies": {
24 | "p-wait-for": "^3.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/web/src/Providers/Providers_Authentication/Providers_Authentication_GraphQL.re:
--------------------------------------------------------------------------------
1 | module MergeUserIdentitiesMutation = [%graphql
2 | {|
3 | mutation MergeUserIdentities($input: MergeUserIdentitiesInput!) {
4 | mergeUserIdentities(input: $input) {
5 | _
6 | }
7 | }
8 | |}
9 | ];
10 |
11 | module Input = {
12 | let make =
13 | (
14 | ~sourceGuestUserCredentials: Providers_Authentication_Credentials.awsCredentials,
15 | ~targetUserCredentials: AmazonCognitoIdentity.UserSession.t,
16 | ) => {
17 | "targetUserIdToken":
18 | AmazonCognitoIdentity.(
19 | targetUserCredentials
20 | ->UserSession.getIdToken
21 | ->IdToken.getJwtToken
22 | ->JwtToken.toString
23 | ),
24 | };
25 | };
26 |
--------------------------------------------------------------------------------
/packages/bs-sentry/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-sentry",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "bsb:build": "bsb -make-world",
7 | "bsb:start": "bsb -make-world -w",
8 | "bsb:clean": "bsb -clean-world"
9 | },
10 | "author": {
11 | "name": "Daniel Ramirez",
12 | "email": "javamonn@hey.com",
13 | "url": "https://javamonn.com"
14 | },
15 | "repository": "https://github.com/literal-io/literal/tree/master/packages/bs-sentry",
16 | "description": "BuckleScript bindings for @sentry/browser.",
17 | "keywords": [
18 | "bucklescript",
19 | "reason",
20 | "sentry"
21 | ],
22 | "license": "MIT - Hippocratic 1.2",
23 | "devDependencies": {
24 | "@sentry/browser": "^5.24.2",
25 | "bs-platform": "^8.4.2"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/web/src/externals/ramda.re:
--------------------------------------------------------------------------------
1 | [@bs.module]
2 | external mergeDeepLeft: ('a, 'b) => 'c = "ramda/src/mergeDeepLeft";
3 |
4 | [@bs.module] external _assoc: (string, 'a, 'b) => 'b = "ramda/src/assoc";
5 | [@bs.module]
6 | external _sortBy: ('a => 'b, Js.Array.t('a)) => Js.Array.t('a) =
7 | "ramda/src/sortBy";
8 | [@bs.module]
9 | external _sort: ((. 'a, 'a) => int, Js.Array.t('a)) => Js.Array.t('a) =
10 | "ramda/src/sortBy";
11 | [@bs.module]
12 | external _uniqBy: ('a => 'b, Js.Array.t('a)) => Js.Array.t('a) =
13 | "ramda/src/uniqBy";
14 |
15 | /** pipe-first variants, ramda is pipe-last **/
16 | let sortBy = (arr, pred) => _sortBy(pred, arr);
17 | let sort = (arr, pred) => _sort(pred, arr);
18 | let assoc = (obj, key, data) => _assoc(key, data, obj);
19 | let uniqBy = (arr, pred) => _uniqBy(pred, arr);
20 |
--------------------------------------------------------------------------------
/packages/web/src/static/markdown/subprocessors.md:
--------------------------------------------------------------------------------
1 | # Subprocessors
2 |
3 | We use third party subprocessors, such as cloud computing providers and analytics software, to run Literal. We establish GDPR-compliant data processing agreements with each subprocessor, extending GDPR safeguards everywhere personal data is processed.
4 |
5 | The following is a list of personal data subprocessors we use. These subprocessors are all located in the United States:
6 |
7 | - [Amazon Web Services](https://aws.amazon.com/compliance/gdpr-center/). Cloud services provider.
8 | - [Google Cloud Platform](https://cloud.google.com/security/gdpr/resource-center/). Cloud services provider.
9 | - [Sentry](https://blog.sentry.io/2018/03/14/gdpr-sentry-and-you). Error reporting software.
10 | - [Amplitude](https://blog.amplitude.com/amplitude-gdpr). Product analytics software.
11 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/layout/toast_accent.xml:
--------------------------------------------------------------------------------
1 |
7 |
17 |
18 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/layout/toast_primary.xml:
--------------------------------------------------------------------------------
1 |
7 |
17 |
18 |
--------------------------------------------------------------------------------
/packages/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/packages/bs-amazon-cognito-identity-js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-amazon-cognito-identity-js",
3 | "version": "1.0.0",
4 | "main": "src/AmazonCognitoIdentity.bs.js",
5 | "description": "BuckleScript bindings for amazon-cognito-identity-js.",
6 | "keywords": [
7 | "bucklescript",
8 | "reason",
9 | "amazon-cognito-identity-js"
10 | ],
11 | "repository": "https://github.com/literal-io/literal/tree/master/packages/apollo-link-analytics",
12 | "scripts": {
13 | "test": "echo \"Error: no test specified\" && exit 1"
14 | },
15 | "author": {
16 | "name": "Daniel Ramirez",
17 | "email": "javamonn@hey.com",
18 | "url": "https://javamonn.com"
19 | },
20 | "license": "MIT - Hippocratic 1.2",
21 | "devDependencies": {
22 | "amazon-cognito-identity-js": "^4.5.0",
23 | "bs-platform": "^8.4.2"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 |
3 | repositories {
4 | maven {
5 | url "https://plugins.gradle.org/m2/"
6 | }
7 | google()
8 | jcenter()
9 | mavenCentral()
10 | }
11 |
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:4.0.1'
14 | classpath 'com.amazonaws:aws-android-sdk-appsync-gradle-plugin:3.1.0'
15 |
16 | // NOTE: Do not place your application dependencies here; they belong
17 | // in the individual module build.gradle files
18 | }
19 | }
20 |
21 | allprojects {
22 | repositories {
23 | maven {
24 | url "https://plugins.gradle.org/m2/"
25 | }
26 | google()
27 | jcenter()
28 | mavenCentral()
29 | }
30 | }
31 |
32 | task clean(type: Delete) {
33 | delete rootProject.buildDir
34 | }
35 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/apple.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/FileActivityResultCallback.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import android.net.Uri;
4 | import android.util.Log;
5 | import android.webkit.ValueCallback;
6 |
7 | import androidx.activity.result.ActivityResultCallback;
8 |
9 | import java.io.File;
10 |
11 | public class FileActivityResultCallback implements ActivityResultCallback {
12 | ValueCallback callback;
13 |
14 | @Override
15 | public void onActivityResult(Uri result) {
16 | if (callback != null) {
17 | callback.onReceiveValue(new Uri[]{result});
18 | } else {
19 | Log.i(Constants.LOG_TAG, "Received onActivityResult: " + result + ", but no callback set.");
20 | }
21 | }
22 |
23 | public void setFilePathCallback(ValueCallback callback) {
24 | this.callback = callback;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/AnnotationTargetLib.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import java.util.UUID;
4 |
5 | import io.literal.model.ExternalTarget;
6 | import io.literal.model.SpecificTarget;
7 | import io.literal.model.Target;
8 | import io.literal.model.TextualTarget;
9 |
10 | public class AnnotationTargetLib {
11 | public static String makeId(String annotationId) {
12 | return annotationId + "/targets/" + UUID.randomUUID().toString();
13 | }
14 |
15 | public static String getID(Target target) {
16 | if (target instanceof ExternalTarget) {
17 | return ((ExternalTarget) target).getId().toString();
18 | } else if (target instanceof SpecificTarget) {
19 | return ((SpecificTarget) target).getId();
20 | } else {
21 | return ((TextualTarget) target).getId();
22 | }
23 | };
24 | }
25 |
--------------------------------------------------------------------------------
/packages/web/src/components/FeatureListItem/FeatureListItem.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~enabled, ~title, ~description, ~className=?) =>
3 |
4 |
5 |
6 |
13 | {React.string(title)}
14 |
15 |
21 | {React.string(description)}
22 |
23 |
24 | ;
25 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/manage-accounts.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/menu/source_webview_toolbar_read.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/android/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/packages/android/app/src/androidTest/java/io/literal/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package io.literal;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 |
25 | assertEquals("io.literal", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/layout/webview_toolbar_indeterminate_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/packages/web/amplify/team-provider-info.json:
--------------------------------------------------------------------------------
1 | {
2 | "production": {
3 | "awscloudformation": {
4 | "Region": "us-east-1",
5 | "DeploymentBucketName": "amplify-literal-production-114446-deployment",
6 | "UnauthRoleName": "amplify-literal-production-114446-unauthRole",
7 | "StackName": "amplify-literal-production-114446",
8 | "StackId": "arn:aws:cloudformation:us-east-1:046525304497:stack/amplify-literal-production-114446/cc4d0500-5b12-11ea-883c-12002b7e66d1",
9 | "AuthRoleName": "amplify-literal-production-114446-authRole",
10 | "UnauthRoleArn": "arn:aws:iam::046525304497:role/amplify-literal-production-114446-unauthRole",
11 | "AuthRoleArn": "arn:aws:iam::046525304497:role/amplify-literal-production-114446-authRole",
12 | "AmplifyAppId": "d3kn1jmjzilue"
13 | },
14 | "categories": {
15 | "auth": {
16 | "literalAuth": {}
17 | }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/ContentResolverLib.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import android.content.Context;
4 | import android.net.Uri;
5 | import android.util.Log;
6 |
7 | import org.apache.commons.io.FileUtils;
8 |
9 | import java.io.File;
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 |
13 | public class ContentResolverLib {
14 | public static File toFile (Context context, File directory, Uri uri, String fileName) {
15 | try {
16 | InputStream inputStream = context.getContentResolver().openInputStream(uri);
17 | File outputFile = new File(directory, fileName);
18 | FileUtils.copyInputStreamToFile(inputStream, outputFile);
19 | return outputFile;
20 | } catch (IOException e) {
21 | Log.e("", "Failed to perform ContentResolverLib.toFile", e);
22 | return null;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/get-annotation-bounding-box/index.mjs:
--------------------------------------------------------------------------------
1 | import "core-js/index.js";
2 | import "regenerator-runtime/runtime.js";
3 |
4 | import {
5 | get as storageGet,
6 | initialize as storageInitialize,
7 | } from "../shared/storage.mjs";
8 | const ANNOTATION = JSON.parse(process.env.PARAM_ANNOTATION);
9 |
10 | export default () => {
11 | storageInitialize();
12 |
13 | const ranges = storageGet("annotationRanges");
14 | if (!ranges || !ranges[ANNOTATION.id]) {
15 | console.error("[Literal] Unable to find range for annotation.");
16 | return;
17 | }
18 |
19 | const boundingBox = ranges[ANNOTATION.id].getBoundingClientRect();
20 | return {
21 | left: boundingBox.left * window.devicePixelRatio,
22 | top: boundingBox.top * window.devicePixelRatio,
23 | right: boundingBox.right * window.devicePixelRatio,
24 | bottom: boundingBox.bottom * window.devicePixelRatio,
25 | };
26 | };
27 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/ui/activity/InstrumentedActivity.java:
--------------------------------------------------------------------------------
1 | package io.literal.ui.activity;
2 |
3 | import android.os.Bundle;
4 |
5 | import androidx.annotation.Nullable;
6 | import androidx.appcompat.app.AppCompatActivity;
7 |
8 | import io.literal.lib.Thunk;
9 | import io.literal.repository.AnalyticsRepository;
10 | import io.literal.repository.ErrorRepository;
11 |
12 | public class InstrumentedActivity extends AppCompatActivity {
13 |
14 | private Thunk errorRepositoryCleanup;
15 |
16 | @Override
17 | protected void onCreate(@Nullable Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | errorRepositoryCleanup = ErrorRepository.initialize();
20 | AnalyticsRepository.initialize(getApplication());
21 | }
22 |
23 | @Override
24 | protected void onDestroy() {
25 | super.onDestroy();
26 |
27 | errorRepositoryCleanup.invoke();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/language.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "literal",
3 | "version": "1.0.0",
4 | "description": "A textual annotation management system.",
5 | "main": "index.js",
6 | "scripts": {
7 | "lerna": "lerna",
8 | "lerna:bootstrap": "lerna bootstrap --hoist -- --legacy-peer-deps",
9 | "fastlane:supply:init": "fastlane supply init --json_key secret/fastlane-gcp-service-account.json"
10 | },
11 | "engines": {
12 | "node": "^15"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/literal-io/literal.git"
17 | },
18 | "author": {
19 | "name": "Daniel Ramirez",
20 | "email": "javamonn@hey.com",
21 | "url": "https://javamonn.com"
22 | },
23 | "license": "GPL-3.0-only",
24 | "bugs": {
25 | "url": "https://github.com/literal-io/literal/issues"
26 | },
27 | "homepage": "https://literal.io",
28 | "devDependencies": {
29 | "lerna": "^3.20.2",
30 | "prettier": "^1.19.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/AWSConfigurationLib.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import android.content.Context;
4 |
5 | import com.amazonaws.mobile.config.AWSConfiguration;
6 |
7 | public class AWSConfigurationLib {
8 | private static volatile AWSConfiguration configuration;
9 | private static volatile AWSConfiguration guestConfiguration;
10 |
11 | public static AWSConfiguration getConfiguration(Context context) {
12 | if (configuration == null) {
13 | configuration = new AWSConfiguration(context);
14 | }
15 | return configuration;
16 | }
17 |
18 | public static AWSConfiguration getGuestConfiguration(Context context) {
19 | if (guestConfiguration == null) {
20 | guestConfiguration = new AWSConfiguration(context);
21 | guestConfiguration.setConfiguration("literal_AWS_IAM");
22 | }
23 | return guestConfiguration;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/android/app/src/foss/res/raw/awsconfiguration.json:
--------------------------------------------------------------------------------
1 | {"UserAgent":"aws-amplify-cli/0.1.0","Version":"0.1.0","IdentityManager":{"Default":{}},"CredentialsProvider":{"CognitoIdentity":{"Default":{"PoolId":"us-east-1:12bb0b85-e6e1-4964-9f0d-24d14b90398d","Region":"us-east-1"}}},"CognitoUserPool":{"Default":{"PoolId":"us-east-1_EWCESLVzL","AppClientId":"1geu7qgt6hdrs4a3e9tn4leg1","Region":"us-east-1"}},"Auth":{"Default":{"authenticationFlowType":"USER_SRP_AUTH"}},"AppSync":{"Default":{"ApiUrl":"https://2dxxqoarong2jd4ukbeugsg5t4.appsync-api.us-east-1.amazonaws.com/graphql","Region":"us-east-1","AuthMode":"AMAZON_COGNITO_USER_POOLS","ClientDatabasePrefix":"literal_AMAZON_COGNITO_USER_POOLS"},"literal_AWS_IAM":{"ApiUrl":"https://2dxxqoarong2jd4ukbeugsg5t4.appsync-api.us-east-1.amazonaws.com/graphql","Region":"us-east-1","AuthMode":"AWS_IAM","ClientDatabasePrefix":"literal_AWS_IAM"}},"S3TransferUtility":{"Default":{"Bucket":"literal-storage114446-production","Region":"us-east-1"}}}
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/AmazonS3URILib.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import android.content.Context;
4 |
5 | import com.amazonaws.services.s3.AmazonS3URI;
6 |
7 | import java.net.URI;
8 | import java.net.URISyntaxException;
9 |
10 | import io.literal.repository.StorageRepository;
11 |
12 | public class AmazonS3URILib {
13 |
14 | /**
15 | * AmazonS3URI.getURI formats with s3:// scheme, we persist https:// equivalent for consistency
16 | */
17 | public static URI toHTTPs(Context context, AmazonS3URI uri) {
18 | try {
19 | return new URI(
20 | "https",
21 | uri.getURI().getHost() + ".s3." + StorageRepository.getBucketRegion(context) +".amazonaws.com",
22 | uri.getURI().getPath(),
23 | null
24 | );
25 | } catch (URISyntaxException e) {
26 | return null;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/bs-amplitude/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-amplitude",
3 | "version": "1.0.0",
4 | "description": "BuckleScript bindings for amplitude-js.",
5 | "repository": "https://github.com/literal-io/literal/tree/master/packages/apollo-link-analytics",
6 | "keywords": [
7 | "bucklescript",
8 | "reason",
9 | "amplitude",
10 | "amplitude-js"
11 | ],
12 | "main": "index.js",
13 | "scripts": {
14 | "test": "echo \"Error: no test specified\" && exit 1",
15 | "bsb:build": "bsb -make-world",
16 | "bsb:start": "bsb -make-world -w",
17 | "bsb:clean": "bsb -clean-world",
18 | "start": "npm run bsb:start"
19 | },
20 | "author": "Daniel Ramirez ",
21 | "license": "MIT - Hippocratic 1.2",
22 | "peerDependencies": {
23 | "bs-platform": "^8.4.2"
24 | },
25 | "devDependencies": {
26 | "bs-platform": "^8.4.2"
27 | },
28 | "dependencies": {
29 | "amplitude-js": "^7.2.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/apollo-link-analytics/src/ApolloLink.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | var Observable = {};
6 |
7 | function query(param) {
8 | return param.query;
9 | }
10 |
11 | function variables(param) {
12 | return param.variables;
13 | }
14 |
15 | function operationName(param) {
16 | return param.operationName;
17 | }
18 |
19 | function extensions(param) {
20 | return param.extensions;
21 | }
22 |
23 | function setContext(param) {
24 | return param.setContext;
25 | }
26 |
27 | function getContext(param) {
28 | return param.getContext;
29 | }
30 |
31 | function toKey(param) {
32 | return param.toKey;
33 | }
34 |
35 | exports.Observable = Observable;
36 | exports.query = query;
37 | exports.variables = variables;
38 | exports.operationName = operationName;
39 | exports.extensions = extensions;
40 | exports.setContext = setContext;
41 | exports.getContext = getContext;
42 | exports.toKey = toKey;
43 | /* No side effect */
44 |
--------------------------------------------------------------------------------
/packages/web/src/externals/FontFaceSet.re:
--------------------------------------------------------------------------------
1 | type t;
2 |
3 | include Webapi.Dom.EventTarget.Impl({
4 | type nonrec t = t;
5 | });
6 |
7 | [@bs.scope "document"] [@bs.val] external inst: t = "fonts";
8 |
9 | [@bs.deriving jsConverter]
10 | type status = [ | [@bs.as "loading"] `Loading | [@bs.as "loaded"] `Loaded];
11 | [@bs.get] external _status: t => string = "status";
12 | let status = inst => inst->_status->statusFromJs->Belt.Option.getExn;
13 |
14 | [@bs.get] external ready: t => Js.Promise.t(unit) = "ready";
15 |
16 | module LoadingDoneEvent = {
17 | [@bs.deriving accessors]
18 | type fontface = {
19 | family: string,
20 | status: string,
21 | style: string,
22 | };
23 |
24 | [@bs.deriving accessors]
25 | type t = {fontfaces: array(fontface)};
26 |
27 | include Webapi.Dom.Event.Impl({
28 | type nonrec t = t;
29 | });
30 |
31 | external unsafeOfEvent: Dom.event => t = "%identity";
32 | };
33 |
34 | [@bs.send] external check: (t, string) => bool = "check";
35 |
--------------------------------------------------------------------------------
/packages/android/scripts/create-foss-amplify-and-aws-configuration.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require("fs");
4 | const path = require("path");
5 | const amplifyConfiguration = require("../app/src/main/res/raw/amplifyconfiguration.json");
6 | const awsConfiguration = require("../app/src/main/res/raw/awsconfiguration.json");
7 | const fossPath = path.resolve(__dirname, "../app/src/foss/res/raw");
8 |
9 | amplifyConfiguration.auth.plugins.awsCognitoAuthPlugin.Auth.Default.OAuth = undefined;
10 | amplifyConfiguration.auth.plugins.awsCognitoAuthPlugin.CognitoUserPool.Default.AppClientSecret = undefined;
11 | awsConfiguration.Auth.Default.OAuth = undefined;
12 | awsConfiguration.CognitoUserPool.Default.AppClientSecret = undefined;
13 |
14 | fs.writeFileSync(
15 | path.resolve(fossPath, "amplifyconfiguration.json"),
16 | JSON.stringify(amplifyConfiguration)
17 | );
18 | fs.writeFileSync(
19 | path.resolve(fossPath, "awsconfiguration.json"),
20 | JSON.stringify(awsConfiguration)
21 | );
22 |
--------------------------------------------------------------------------------
/packages/web/src/externals/lodash.re:
--------------------------------------------------------------------------------
1 | type debounced1('a, 'b) = (. 'a) => 'b;
2 | type debounced2('a, 'b, 'c) = (. 'a, 'b) => 'c;
3 | type debounced3('a, 'b, 'c, 'd) = (. 'a, 'b, 'c) => 'd;
4 | [@bs.send] external flush1: debounced1('a, 'b) => unit = "flush";
5 | [@bs.send] external flush2: debounced2('a, 'b, 'c) => unit = "flush";
6 | [@bs.send] external flush3: debounced3('a, 'b, 'c, 'd) => unit = "flush";
7 | [@bs.module]
8 | external debounce1: ((. 'a) => 'b, int) => debounced1('a, 'b) =
9 | "lodash/debounce";
10 | [@bs.module]
11 | external debounce2: ((. 'a, 'b) => 'c, int) => debounced2('a, 'b, 'c) =
12 | "lodash/debounce";
13 | [@bs.module]
14 | external debounce3: ((. 'a, 'b, 'c) => 'd, int) => debounced3('a, 'b, 'c, 'd) =
15 | "lodash/debounce";
16 |
17 | module Throttled3 = {
18 | type t('a, 'b, 'c, 'd) = (. 'a, 'b, 'c) => 'd;
19 | [@bs.send] external flush: t('a, 'b, 'c, 'd) => unit = "flush";
20 | [@bs.module]
21 | external make: ((. 'a, 'b, 'c) => 'd, int) => t('a, 'b, 'c, 'd) =
22 | "lodash/throttle";
23 | };
24 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/repository/SharedPreferencesRepository.java:
--------------------------------------------------------------------------------
1 | package io.literal.repository;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | public class SharedPreferencesRepository {
7 | private static final String FILE_KEY = "io.literal.SHARED_PREFERENCES_REPOSITORY";
8 |
9 | private static final String IS_SIGNED_OUT_KEY = "IS_SIGNED_OUT";
10 |
11 | private static SharedPreferences getSharedPreferences(Context context) {
12 | return context.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE);
13 | }
14 |
15 | public static boolean getIsSignedOut(Context context) {
16 | return getSharedPreferences(context).getBoolean(IS_SIGNED_OUT_KEY, false);
17 | }
18 | public static void setIsSignedOut(Context context, boolean hasSignedOut) {
19 | SharedPreferences.Editor editor = getSharedPreferences(context).edit();
20 | editor.putBoolean(IS_SIGNED_OUT_KEY, hasSignedOut);
21 | editor.apply();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/pamphlet/index.ts:
--------------------------------------------------------------------------------
1 | import mjml from "mjml";
2 |
3 | import fs from "fs";
4 | import path from "path";
5 |
6 | const OUT_DIR = path.resolve(__dirname, "./dist");
7 | const MJML_OPTIONS = {
8 | fonts: {
9 | "Roboto Mono":
10 | "https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap",
11 | Domine: "https://fonts.googleapis.com/css2?family=Domine&display=swap",
12 | },
13 | };
14 |
15 | fs.mkdirSync(OUT_DIR, { recursive: true })
16 |
17 | fs.readdirSync(path.resolve(__dirname, "./templates")).forEach((fileName) => {
18 | const filePath = path.resolve(
19 | __dirname,
20 | "./templates",
21 | fileName,
22 | "template.mjml"
23 | );
24 | const fileContent = fs.readFileSync(filePath, { encoding: "utf8" });
25 | const outPath = path.resolve(OUT_DIR, fileName + ".html");
26 |
27 | const { html, errors } = mjml(fileContent, MJML_OPTIONS);
28 |
29 | if (errors) {
30 | errors.forEach((e) => {
31 | throw e;
32 | });
33 | }
34 |
35 | fs.writeFileSync(outPath, html);
36 | });
37 |
--------------------------------------------------------------------------------
/packages/bs-aws-sdk/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-aws-sdk",
3 | "version": "1.0.0",
4 | "main": "src/AWSSDK.bs.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1",
7 | "bsb:build": "bsb -make-world",
8 | "bsb:start": "bsb -make-world -w",
9 | "bsb:clean": "bsb -clean-world",
10 | "start": "npm run bsb:start",
11 | "build": "npm run bsb:build"
12 | },
13 | "author": {
14 | "name": "Daniel Ramirez",
15 | "email": "javamonn@hey.com",
16 | "url": "https://javamonn.com"
17 | },
18 | "repository": "https://github.com/literal-io/literal/tree/master/packages/bs-aws-sdk",
19 | "description": "BuckleScript bindings for aws-sdk.",
20 | "keywords": [
21 | "bucklescript",
22 | "reason",
23 | "aws-sdk"
24 | ],
25 | "license": "MIT - Hippocratic 1.2",
26 | "peerDependencies": {
27 | "aws-sdk": "^2.541.0",
28 | "bs-platform": "^8.4.2"
29 | },
30 | "devDependencies": {
31 | "aws-sdk": "^2.541.0",
32 | "bs-platform": "^8.4.2"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_AnnotationEditor/Containers_AnnotationEditor_Tag.re:
--------------------------------------------------------------------------------
1 | type t = {
2 | id: option(string),
3 | href: option(string),
4 | text: string,
5 | };
6 |
7 | let ensureId = (~identityId, tag) => {
8 | let id =
9 | switch (tag.id) {
10 | | Some(id) => Js.Promise.resolve(id)
11 | | None =>
12 | Lib_GraphQL.AnnotationCollection.makeId(~identityId, ~label=tag.text)
13 | };
14 | id |> Js.Promise.then_(id => Js.Promise.resolve({...tag, id: Some(id)}));
15 | };
16 |
17 | let asTextualBody = tag =>
18 | tag.id
19 | ->Belt.Option.map(id =>
20 | `TextualBody({
21 | "__typename": "TextualBody",
22 | "id": id,
23 | "format": Some(`TEXT_PLAIN),
24 | "language": Some(`EN_US),
25 | "processingLanguage": Some(`EN_US),
26 | "textDirection": Some(`LTR),
27 | "accessibility": None,
28 | "rights": None,
29 | "purpose": Some([|`TAGGING|]),
30 | "value": tag.text,
31 | "type": Some(`TEXTUAL_BODY),
32 | })
33 | );
34 |
--------------------------------------------------------------------------------
/packages/web/src/externals/bowser.re:
--------------------------------------------------------------------------------
1 |
2 | type t;
3 |
4 | [@bs.deriving abstract]
5 | type navigator = {userAgent: string};
6 |
7 | external asNavigator: Webapi.Dom.Window.navigator => navigator = "%identity";
8 |
9 | [@bs.deriving abstract]
10 | type browser = {
11 | name: string,
12 | version: string,
13 | };
14 |
15 | [@bs.deriving jsConverter]
16 | type browserName = [ | `Firefox | `Chrome | `Safari];
17 |
18 | let getBrowserName = browser => browser |> nameGet |> browserNameFromJs;
19 |
20 | [@bs.val] [@bs.module "bowser"] external make: string => t = "getParser";
21 |
22 | [@bs.send] external getBrowser: t => browser = "getBrowser";
23 |
24 | // https://github.com/lancedikson/bowser/blob/master/src/constants.js#L93
25 | [@bs.deriving jsConverter]
26 | type osName = [
27 | | [@bs.as "macOS"] `MacOS
28 | | `Android
29 | | [@bs.as "iOS"] `iOS
30 | ];
31 |
32 | type os = {
33 | name: string,
34 | version: string
35 | };
36 |
37 | [@bs.send] external getOS: t => os = "getOS";
38 |
39 | let getOSName = os => osNameFromJs(os.name);
40 |
--------------------------------------------------------------------------------
/packages/model/src/Motivation.js:
--------------------------------------------------------------------------------
1 | // Generated by ReScript, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | function toString(t) {
6 | if (t === "HIGHLIGHTING") {
7 | return "HIGHLIGHTING";
8 | } else if (t === "BOOKMARKING") {
9 | return "BOOKMARKING";
10 | } else if (t === "DESCRIBING") {
11 | return "DESCRIBING";
12 | } else if (t === "COMMENTING") {
13 | return "COMMENTING";
14 | } else if (t === "IDENTIFYING") {
15 | return "IDENTIFYING";
16 | } else if (t === "REPLYING") {
17 | return "REPLYING";
18 | } else if (t === "ACCESSING") {
19 | return "ACCESSING";
20 | } else if (t === "QUESTIONING") {
21 | return "QUESTIONING";
22 | } else if (t === "CLASSIFYING") {
23 | return "CLASSIFYING";
24 | } else if (t === "LINKING") {
25 | return "LINKING";
26 | } else if (t === "EDITING") {
27 | return "EDITING";
28 | } else if (t === "TAGGING") {
29 | return "TAGGING";
30 | } else {
31 | return "MODERATING";
32 | }
33 | }
34 |
35 | exports.toString = toString;
36 | /* No side effect */
37 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/ui/MainApplication.java:
--------------------------------------------------------------------------------
1 | package io.literal.ui;
2 |
3 | import android.app.Application;
4 |
5 | import java.util.concurrent.BlockingQueue;
6 | import java.util.concurrent.LinkedBlockingQueue;
7 | import java.util.concurrent.ThreadPoolExecutor;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | public class MainApplication extends Application {
11 | private static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
12 | private final BlockingQueue workQueue = new LinkedBlockingQueue();
13 | private static final int KEEP_ALIVE_TIME = 1;
14 | private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
15 |
16 | ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
17 | NUMBER_OF_CORES,
18 | NUMBER_OF_CORES,
19 | KEEP_ALIVE_TIME,
20 | KEEP_ALIVE_TIME_UNIT,
21 | workQueue
22 | );
23 |
24 | public ThreadPoolExecutor getThreadPoolExecutor() {
25 | return threadPoolExecutor;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/web/src/Lib/Lib_GraphQL/Lib_GraphQL_Agent.re:
--------------------------------------------------------------------------------
1 | let cacheAgentFragment =
2 | ApolloClient.gql(.
3 | {|
4 | fragment CacheAgent on Agent {
5 | id
6 | email
7 | email_sha1
8 | type_: type
9 | username
10 | homepage
11 | name
12 | nickname
13 | }
14 | |},
15 | );
16 |
17 | let makeId = (~identityId) => Constants.apiOrigin ++ "/agents/" ++ identityId;
18 |
19 | let makeCache = (~identityId) =>
20 | Js.Json.object_(
21 | Js.Dict.fromList([
22 | ("__typename", "Agent"->Js.Json.string),
23 | ("id", makeId(~identityId)->Js.Json.string),
24 | ("email", Js.Json.null),
25 | ("email_sha1", Js.Json.null),
26 | ("type", "PERSON"->Js.Json.string),
27 | ("username", identityId->Js.Json.string),
28 | ("homepage", Js.Json.null),
29 | ("name", Js.Json.null),
30 | ("nickname", Js.Json.null),
31 | ]),
32 | );
33 |
34 | let readCache = id => {
35 | Apollo.Client.readFragment(
36 | Providers_Apollo_Client.inst^,
37 | {id: "Agent:" ++ id, fragment: cacheAgentFragment},
38 | );
39 | };
40 |
--------------------------------------------------------------------------------
/packages/web/src/Providers/Providers_BottomNavigation/Providers_BottomNavigation.re:
--------------------------------------------------------------------------------
1 | type context = {
2 | setIsVisible: bool => unit,
3 | isVisible: bool,
4 | };
5 |
6 | let context = React.createContext({setIsVisible: _ => (), isVisible: false});
7 |
8 | module ContextProvider = {
9 | include React.Context;
10 |
11 | let makeProps = (~value, ~children, ()) => {
12 | "value": value,
13 | "children": children,
14 | };
15 | let make = React.Context.provider(context);
16 | };
17 |
18 | [@react.component]
19 | let make = (~children) => {
20 | let (isVisible, setIsVisible) = React.useState(_ => false);
21 | let router = Next.Router.useRouter();
22 |
23 | let _ =
24 | React.useEffect3(
25 | () => {
26 | let _ = setIsVisible(_ => true);
27 | None;
28 | },
29 | (router.asPath, router.route, router.query),
30 | );
31 |
32 | let handleSetIsVisible = newIsVisible => setIsVisible(_ => newIsVisible);
33 |
34 |
35 | children
36 | ;
37 | };
38 |
--------------------------------------------------------------------------------
/packages/web/src/routes/Route_Creators_Id_Annotation_Collections.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let default = (~rehydrated) => {
3 | let Providers_Authentication.{user} =
4 | React.useContext(Providers_Authentication.authenticationContext);
5 | let router = Next.Router.useRouter();
6 |
7 | let _ =
8 | React.useEffect1(
9 | () => {
10 | let _ =
11 | switch (user) {
12 | | SignedOutPromptAuthentication =>
13 | Next.Router.replace(Routes.Authenticate.path())
14 | | _ => ()
15 | };
16 | None;
17 | },
18 | [|user|],
19 | );
20 |
21 | switch (
22 | Routes.CreatorsIdAnnotationCollections.params_decode(router.Next.query)
23 | ) {
24 | | Ok(_) =>
25 | | _ =>
26 | ()}
29 | />
30 | };
31 | };
32 |
33 | let page = "creators/[identityId]/annotation-collections.js";
34 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/Crypto.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import android.os.Build;
4 |
5 | import androidx.annotation.RequiresApi;
6 |
7 | import java.nio.charset.StandardCharsets;
8 | import java.security.MessageDigest;
9 | import java.security.NoSuchAlgorithmException;
10 |
11 | public class Crypto {
12 | public static String sha256Hex(String input) throws NoSuchAlgorithmException {
13 | MessageDigest digest = MessageDigest.getInstance("SHA-256");
14 |
15 | byte[] hash = null;
16 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
17 | hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
18 | } else {
19 | hash = digest.digest(input.getBytes());
20 | }
21 |
22 | StringBuffer output = new StringBuffer();
23 | for (int i = 0; i < hash.length; i++) {
24 | String hex = Integer.toHexString(0xff & hash[i]);
25 | if(hex.length() == 1) output.append('0');
26 | output.append(hex);
27 | }
28 | return output.toString();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/web/src/routes/Route_Creators.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let default = (~rehydrated) => {
3 | let Providers_Authentication.{user} =
4 | React.useContext(Providers_Authentication.authenticationContext);
5 |
6 | let _ =
7 | React.useEffect1(
8 | () => {
9 | let _ =
10 | switch (user) {
11 | | SignedInUser({identityId})
12 | | GuestUser({identityId}) =>
13 | Routes.CreatorsIdAnnotationCollectionsId.(
14 | Next.Router.replaceWithAs(
15 | staticPath,
16 | path(
17 | ~identityId,
18 | ~annotationCollectionIdComponent=Lib_GraphQL.AnnotationCollection.recentAnnotationCollectionIdComponent,
19 | ),
20 | )
21 | )
22 | | SignedOutPromptAuthentication =>
23 | Next.Router.replace(Routes.Authenticate.path())
24 | | Unknown => ()
25 | };
26 |
27 | None;
28 | },
29 | [|user|],
30 | );
31 |
32 | ;
33 | };
34 |
35 | let page = "creators.js"
36 |
--------------------------------------------------------------------------------
/metadata/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | Literal is a textual information browser for augmenting your reading experience; capture sources, annotations, and knowledge.
2 |
3 | CAPTURE ANNOTATIONS
4 | Share URLs, text, and images to Literal to annotate and highlight.
5 |
6 | COLLECT INFORMATION
7 | Over time, Literal becomes a personal knowledge base containing information and knowledge along with their source.
8 |
9 | VIEW ANNOTATIONS IN CONTEXT
10 | Quickly view the annotation's source context by tapping it.
11 |
12 | ORGANIZE BY TAG AND SOURCE
13 | Go beyond folders with a tag-based organization system, or view annotations by their shared source.
14 |
15 | OPEN SOURCE, OPEN STANDARDS
16 | Literal is open source (https://github.com/literal-io/literal) and implements the W3C Web Annotation standard (https://www.w3.org/TR/annotation-model/) to ensure that your data is portable. The application currently interfaces with proprietary network services hosted on Amazon Web Services, though local-only functionality may be supported in the future (https://github.com/literal-io/literal/issues/123).
17 |
18 | View https://literal.io/ for more information.
19 |
--------------------------------------------------------------------------------
/packages/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | app/beta
16 | app/foss
17 | app/full
18 |
19 | # Signing
20 | app/release-keystore.jks
21 | app/beta-keystore.jks
22 | signing.properties
23 |
24 |
25 | app/src/main/assets/SourceWebView*
26 | build/
27 | dist/
28 | node_modules/
29 | aws-exports.js
30 | amplify-gradle-config.json
31 | amplifyxc.config
32 |
33 |
34 | app/src/main/res/raw/amplifyconfiguration.json
35 | app/src/main/res/raw/awsconfiguration.json
36 |
37 | #amplify
38 | amplify/\#current-cloud-backend
39 | amplify/.config/local-*
40 | amplify/logs
41 | amplify/mock-data
42 | amplify/backend/amplify-meta.json
43 | amplify/backend/awscloudformation
44 | amplify/backend/.temp
45 | build/
46 | dist/
47 | node_modules/
48 | aws-exports.js
49 | awsconfiguration.json
50 | amplifyconfiguration.json
51 | amplify-build-config.json
52 | amplify-gradle-config.json
53 | amplifytools.xcconfig
54 | .secret-*
--------------------------------------------------------------------------------
/packages/bs-sentry/src/SentryNode.re:
--------------------------------------------------------------------------------
1 | type config = {
2 | dsn: string,
3 | normalizeDepth: option(int),
4 | };
5 |
6 | [@bs.module "@sentry/node"] external init: config => unit = "init";
7 |
8 | type exceptionContext = {
9 | tags: option(Js.Dict.t(string)),
10 | extra: option(Js.Json.t),
11 | user: option(Js.Json.t),
12 | level: option(Js.Json.t),
13 | fingerprint: option(Js.Json.t),
14 | };
15 |
16 | let makeExceptionContext =
17 | (~tags=?, ~extra=?, ~user=?, ~level=?, ~fingerprint=?, ()) => {
18 | tags,
19 | extra,
20 | user,
21 | level,
22 | fingerprint,
23 | };
24 |
25 | [@bs.module "@sentry/node"]
26 | external captureExceptionWithContext: (Js.Exn.t, exceptionContext) => unit =
27 | "captureException";
28 |
29 | [@bs.module "@sentry/node"]
30 | external captureException: Js.Exn.t => unit = "captureException";
31 |
32 | [@bs.module "@sentry/node"]
33 | external captureMessage: string => unit = "captureMessage";
34 |
35 | [@bs.module "@sentry/node"]
36 | external setContext: (string, Js.Json.t) => unit = "setContext";
37 |
38 | [@bs.module "@sentry/node"]
39 | external lastEventId: unit => string = "lastEventId";
40 |
--------------------------------------------------------------------------------
/packages/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/State.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | import android.util.Log;
4 |
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import io.literal.repository.ErrorRepository;
9 | import type.StateInput;
10 |
11 | public class State {
12 | public enum Type {
13 | TIME_STATE
14 | }
15 |
16 | protected final Type type;
17 |
18 | public State(Type type) { this.type = type; }
19 |
20 | public Type getType() { return this.type; }
21 |
22 | public JSONObject toJson() throws JSONException {
23 | throw new JSONException("Serialization not implemented.");
24 | }
25 |
26 | public StateInput toStateInput() {
27 | ErrorRepository.captureException(new Exception("Attempted to call toAnnotationTarget, but not implemented."));
28 | return null;
29 | }
30 |
31 | public static State fromJson(JSONObject json) throws JSONException {
32 | String type = json.getString("type");
33 | if (type.equals(Type.TIME_STATE.name())) {
34 | return TimeState.fromJson(json);
35 | }
36 |
37 | return null;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_NewAnnotationFromShareHeader/Containers_NewAnnotationFromShareHeader_GraphQL.re:
--------------------------------------------------------------------------------
1 | module GetAnnotationFragment = [%graphql
2 | {|
3 | fragment headerAnnotationFragment on Annotation {
4 | id
5 | body {
6 | ... on TextualBody {
7 | __typename
8 | id
9 | value
10 | purpose
11 | }
12 | }
13 | target {
14 | ... on ExternalTarget {
15 | __typename
16 | externalTargetId: id
17 | format
18 | }
19 | ... on SpecificTarget {
20 | __typename
21 | specificTargetId: id
22 | source {
23 | ... on ExternalTarget {
24 | externalTargetId: id,
25 | format
26 | __typename
27 | }
28 | }
29 | }
30 | }
31 | }
32 | |}
33 | ];
34 |
35 | module DeleteAnnotationMutation = [%graphql
36 | {|
37 | mutation deleteAnnotation($input: DeleteAnnotationInput!) {
38 | deleteAnnotation(input: $input) {
39 | annotation {
40 | id
41 | }
42 | }
43 | }
44 | |}
45 | ];
46 |
47 |
--------------------------------------------------------------------------------
/packages/web/src/app.css:
--------------------------------------------------------------------------------
1 | /* purgecss start ignore */
2 | @tailwind base;
3 | @tailwind components;
4 | /* purgecss end ignore */
5 |
6 | @tailwind utilities;
7 |
8 | /* base */
9 |
10 | :root {
11 | --root-height: 100vh;
12 | }
13 |
14 | html {
15 | font-size: 16px;
16 | -moz-osx-font-smoothing: grayscale;
17 | -webkit-font-smoothing: antialiased;
18 | -webkit-tap-highlight-color: transparent;
19 | }
20 |
21 | #__next {
22 | width: 100vw;
23 | height: var(--root-height);
24 | background-color: #0C0C0C;
25 | position: relative;
26 | overflow-y: auto;
27 | display: flex;
28 | flex-direction: column;
29 | flex-grow: 0;
30 | }
31 |
32 | .awsappsync {
33 | width: 100%;
34 | height: 100%;
35 | }
36 |
37 | .awsappsync--rehydrating {
38 | display: none;
39 | }
40 |
41 |
42 | button:focus,
43 | input:focus {
44 | outline: none;
45 | }
46 |
47 | ::selection {
48 | background-color: #FFF;
49 | color: rgba(0, 0, 0, .92);
50 | }
51 |
52 | /* utility classes */
53 |
54 | .box-decoration-break-clone {
55 | -webkit-box-decoration-break: clone;
56 | box-decoration-break: clone;
57 | }
58 |
59 | .touch-none {
60 | touch-action: none;
61 | }
62 |
--------------------------------------------------------------------------------
/packages/apollo-link-analytics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/apollo-link-analytics",
3 | "version": "1.0.0",
4 | "main": "./src/ApolloLinkAnalytics.bs.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1",
7 | "bsb:build": "bsb -make-world",
8 | "bsb:start": "bsb -make-world -w",
9 | "bsb:clean": "bsb -clean-world",
10 | "start": "npm run bsb:start"
11 | },
12 | "author": {
13 | "name": "Daniel Ramirez",
14 | "email": "javamonn@hey.com",
15 | "url": "https://javamonn.com"
16 | },
17 | "repository": "https://github.com/literal-io/literal/tree/chore-fdroid/packages/apollo-link-analytics",
18 | "description": "Automatic product analytics derived from GraphQL operations executed by Apollo.",
19 | "keywords": [
20 | "bucklescript",
21 | "reason",
22 | "apollo",
23 | "graphql",
24 | "analytics"
25 | ],
26 | "license": "MIT - Hippocratic 1.2",
27 | "dependencies": {
28 | "apollo-link": "1.2.3",
29 | "reason-apollo": "^0.20.0"
30 | },
31 | "peerDependencies": {
32 | "bs-platform": "^8.4.2"
33 | },
34 | "devDependencies": {
35 | "bs-platform": "^8.4.2"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/bs-sentry/src/SentryBrowser.re:
--------------------------------------------------------------------------------
1 | [@bs.deriving abstract]
2 | type config = {
3 | dsn: string,
4 | normalizeDepth: int,
5 | };
6 |
7 | [@bs.module "@sentry/browser"] external init: config => unit = "init";
8 |
9 | type exceptionContext = {
10 | tags: option(Js.Dict.t(string)),
11 | extra: option(Js.Json.t),
12 | user: option(Js.Json.t),
13 | level: option(Js.Json.t),
14 | fingerprint: option(Js.Json.t),
15 | };
16 |
17 | let makeExceptionContext =
18 | (~tags=?, ~extra=?, ~user=?, ~level=?, ~fingerprint=?, ()) => {
19 | tags,
20 | extra,
21 | user,
22 | level,
23 | fingerprint,
24 | };
25 |
26 | [@bs.module "@sentry/browser"]
27 | external captureExceptionWithContext: (Js.Exn.t, exceptionContext) => unit =
28 | "captureException";
29 |
30 | [@bs.module "@sentry/browser"]
31 | external captureException: Js.Exn.t => unit = "captureException";
32 |
33 | [@bs.module "@sentry/browser"]
34 | external captureMessage: string => unit = "captureMessage";
35 |
36 | [@bs.module "@sentry/browser"]
37 | external setContext: (string, Js.Json.t) => unit = "setContext";
38 |
39 | [@bs.module "@sentry/browser"]
40 | external lastEventId: unit => string = "lastEventId";
41 |
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_NewAnnotationFromMessageEventHeader/Containers_NewAnnotationFromMessageEventHeader.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~onDismiss) => {
3 |
4 | onDismiss()}
8 | _TouchRippleProps={
9 | "classes": {
10 | "child": Cn.fromList(["bg-white"]),
11 | "rippleVisible": Cn.fromList(["opacity-50"]),
12 | },
13 | }
14 | classes={MaterialUi.IconButton.Classes.make(
15 | ~root=Cn.fromList(["p-0"]),
16 | (),
17 | )}>
18 |
22 |
23 |
32 | {React.string("Edit Annotation")}
33 |
34 | ;
35 | };
36 |
--------------------------------------------------------------------------------
/packages/web/src/components/Head.re:
--------------------------------------------------------------------------------
1 | let makeMeta =
2 | (
3 | ~title="Literal",
4 | ~description="Literal is a textual annotation management system. The act of annotation is only the beginning. Leverage your highlights to enhance your reading experience.",
5 | ~image=Constants.apiOrigin ++ "/logo-opaque-128.png",
6 | (),
7 | ) =>
8 | <>
9 | {React.string(title)}
10 |
11 |
12 |
13 |
14 | >;
15 |
16 | [@react.component]
17 | let make = (~children=React.null) =>
18 |
19 |
24 |
25 |
26 |
27 | {makeMeta()}
28 | children
29 | ;
30 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/webpack.config.js:
--------------------------------------------------------------------------------
1 | const resolvePath = (path) => new URL(path, import.meta.url).pathname;
2 |
3 | const config = {
4 | mode: "production",
5 | optimization: {
6 | minimize: false,
7 | },
8 | entry: {
9 | GetAnnotation: resolvePath("./get-annotation/index.mjs"),
10 | AnnotationRenderer: resolvePath("./annotation-renderer/index.mjs"),
11 | GetAnnotationBoundingBox: resolvePath(
12 | "./get-annotation-bounding-box/index.mjs"
13 | ),
14 | GetScripts: resolvePath("./get-scripts/index.mjs"),
15 | },
16 | output: {
17 | filename: "SourceWebView[name].js",
18 | path: resolvePath("./dist"),
19 | library: "Literal",
20 | },
21 | module: {
22 | rules: [
23 | {
24 | test: /\.m?js$/,
25 | exclude: [
26 | // \\ for Windows, \/ for Mac OS and Linux
27 | /node_modules[\\\/]core-js/,
28 | /node_modules[\\\/]webpack[\\\/]buildin/,
29 | ],
30 | use: {
31 | loader: "babel-loader",
32 | options: {
33 | presets: ["@babel/preset-env"],
34 | },
35 | },
36 | },
37 | ],
38 | },
39 | };
40 |
41 | export default config;
42 |
--------------------------------------------------------------------------------
/packages/web/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "web",
3 | "version": "1.0.0",
4 | "reason": {
5 | "react-jsx": 3
6 | },
7 | "sources": [
8 | {
9 | "dir": "src",
10 | "subdirs": true
11 | }
12 | ],
13 | "package-specs": {
14 | "module": "commonjs",
15 | "in-source": true
16 | },
17 | "suffix": ".js",
18 | "js-post-build": {
19 | "cmd": "./scripts/bsb-js-post-build.js"
20 | },
21 | "bs-dependencies": [
22 | "@literal-io/bs-aws-amplify",
23 | "decco",
24 | "bs-webapi",
25 | "bs-fetch",
26 | "reason-react",
27 | "re-classnames",
28 | "reason-apollo",
29 | "reason-apollo-hooks",
30 | "@literal-io/bs-aws-appsync",
31 | "@literal-io/bs-amplitude",
32 | "@literal-io/apollo-link-analytics",
33 | "@literal-io/bs-sentry",
34 | "@literal-io/bs-amazon-cognito-identity-js",
35 | "@literal-io/model",
36 | "@jsiebern/bs-material-ui"
37 | ],
38 | "ppx-flags": [
39 | [
40 | "@reasonml-community/graphql-ppx/ppx",
41 | "-schema ./graphql-schema.json",
42 | "-apollo-mode"
43 | ],
44 | "decco/ppx"
45 | ],
46 | "warnings": {
47 | "error": "+101"
48 | },
49 | "namespace": true,
50 | "refmt": 3
51 | }
52 |
--------------------------------------------------------------------------------
/packages/web/scripts/bsb-js-post-build.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const { readFileSync, mkdirSync, writeFileSync } = require("fs");
4 | const { resolve, dirname, relative } = require("path");
5 |
6 | if (process.argv.length === 2) {
7 | return;
8 | }
9 |
10 | const path = process.argv[2];
11 |
12 | if (path.includes("src/routes/Route_")) {
13 | const file = readFileSync(path, { encoding: "utf-8" });
14 | const [_, page] = file.match(/^var page \= "(.*)".*$/m) || [];
15 |
16 | if (page) {
17 | const absPagePath = resolve(__dirname, "../src/pages", page);
18 | const reExports = [
19 | "default",
20 | /^exports\.getStaticProps/m.test(file) && "getStaticProps",
21 | /^exports\.getStaticPaths/m.test(file) && "getStaticPaths",
22 | ].filter(Boolean);
23 |
24 | const pathRelativeToOutput = relative(dirname(absPagePath), resolve(path));
25 | const output = `export { ${reExports.join(
26 | ","
27 | )} } from "${pathRelativeToOutput}"`;
28 | mkdirSync(dirname(absPagePath), { recursive: true });
29 | writeFileSync(absPagePath, output);
30 | } else {
31 | throw new Error(
32 | `Expected \"page\" declaration in Route ${path}, but found none.`
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/bs-aws-appsync/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-aws-appsync",
3 | "version": "1.0.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@literal-io/bs-aws-appsync",
9 | "version": "1.0.1",
10 | "license": "MIT - Hippocratic 1.2",
11 | "devDependencies": {
12 | "bs-platform": "^8.2.0"
13 | },
14 | "peerDependencies": {
15 | "bs-platform": "^8.2.0"
16 | }
17 | },
18 | "node_modules/bs-platform": {
19 | "version": "8.2.0",
20 | "resolved": "https://registry.npmjs.org/bs-platform/-/bs-platform-8.2.0.tgz",
21 | "integrity": "sha512-quvmUac/ZxGDsT7L5+6RNXrLPvLHkWFownacaqlwVoyAm770bPyupTRU49ALPGk3HpjfD5eE+lpGdOSPtuwJiA==",
22 | "dev": true,
23 | "hasInstallScript": true,
24 | "bin": {
25 | "bsb": "bsb",
26 | "bsc": "bsc",
27 | "bsrefmt": "bsrefmt",
28 | "bstracing": "lib/bstracing"
29 | }
30 | }
31 | },
32 | "dependencies": {
33 | "bs-platform": {
34 | "version": "8.2.0",
35 | "resolved": "https://registry.npmjs.org/bs-platform/-/bs-platform-8.2.0.tgz",
36 | "integrity": "sha512-quvmUac/ZxGDsT7L5+6RNXrLPvLHkWFownacaqlwVoyAm770bPyupTRU49ALPGk3HpjfD5eE+lpGdOSPtuwJiA==",
37 | "dev": true
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/bs-aws-appsync/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-aws-appsync",
3 | "version": "1.0.1",
4 | "main": "src/AwsAppSync.bs.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1",
7 | "bsb:build": "bsb -make-world",
8 | "bsb:start": "bsb -make-world -w",
9 | "bsb:clean": "bsb -clean-world",
10 | "start": "npm run bsb:start"
11 | },
12 | "author": {
13 | "name": "Daniel Ramirez",
14 | "email": "javamonn@hey.com",
15 | "url": "https://javamonn.com"
16 | },
17 | "repository": "https://github.com/literal-io/literal/tree/master/packages/bs-aws-appsync",
18 | "description": "BuckleScript bindings to aws-appsync.",
19 | "keywords": [
20 | "bucklescript",
21 | "reason",
22 | "aws-appsync"
23 | ],
24 | "license": "MIT - Hippocratic 1.2",
25 | "dependencies": {
26 | "aws-appsync": "^4.0.0",
27 | "aws-appsync-react": "^4.0.0",
28 | "reason-apollo": "^0.20.0",
29 | "reason-react": "^0.9.1",
30 | "@literal-io/bs-aws-amplify": "1.0.0",
31 | "@literal-io/bs-amazon-cognito-identity-js": "1.0.0"
32 | },
33 | "peerDependencies": {
34 | "bs-platform": "^8.4.2"
35 | },
36 | "devDependencies": {
37 | "bs-platform": "^8.4.2"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/Body.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | import org.json.JSONException;
4 | import org.json.JSONObject;
5 |
6 | import io.literal.repository.ErrorRepository;
7 | import type.AnnotationBodyInput;
8 |
9 | public class Body {
10 | public enum Type {
11 | TEXTUAL_BODY
12 | }
13 |
14 | protected final Type type;
15 |
16 | public Body(Type type) {
17 | this.type = type;
18 | }
19 |
20 | public Type getType() {
21 | return type;
22 | }
23 |
24 | public JSONObject toJson() throws JSONException {
25 | throw new JSONException("toJson not implemented.");
26 | };
27 |
28 | public AnnotationBodyInput toAnnotationBodyInput() {
29 | ErrorRepository.captureException(new Exception("Attempted to call toAnnotationBodyInput, but not implemented."));
30 | return null;
31 | }
32 |
33 | public static Body fromJson(JSONObject json) throws JSONException {
34 | String type = json.getString("type");
35 | if (type.equals(Type.TEXTUAL_BODY.name())) {
36 | return TextualBody.fromJson(json);
37 | } else {
38 | throw new JSONException("fromJson not implemented.");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/get-annotation/index.mjs:
--------------------------------------------------------------------------------
1 | import "core-js/index.js";
2 | import "regenerator-runtime/runtime.js";
3 |
4 | import { makeAnnotationFromSelection } from "./model.mjs";
5 | import {
6 | get as storageGet,
7 | KEY_SERVICE_HIGHLIGHTER,
8 | KEY_SERVICE_ANNOTATION_FOCUS_MANAGER,
9 | } from "../shared/storage.mjs";
10 |
11 | export default () => {
12 | const highlighterService = storageGet(KEY_SERVICE_HIGHLIGHTER);
13 | const annotationFocusManagerService = storageGet(
14 | KEY_SERVICE_ANNOTATION_FOCUS_MANAGER
15 | );
16 |
17 | if (!highlighterService || !annotationFocusManagerService) {
18 | console.error(
19 | "[Literal] Expected annotationFocusManager and highlighter services, but found null.",
20 | highlighterService,
21 | annotationFocusManagerService
22 | );
23 |
24 | return null;
25 | }
26 |
27 | annotationFocusManagerService._handleBlurAnnotation({ disableNotify: true })
28 | highlighterService.removeHighlights()
29 |
30 | const output =
31 | window.getSelection().rangeCount > 0
32 | ? makeAnnotationFromSelection({ selection: window.getSelection() })
33 | : null;
34 |
35 | window.getSelection().removeAllRanges();
36 |
37 | return output;
38 | };
39 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/lib/JsonArrayUtil.java:
--------------------------------------------------------------------------------
1 | package io.literal.lib;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONException;
5 | import org.json.JSONObject;
6 |
7 | import java.util.Arrays;
8 |
9 | public class JsonArrayUtil {
10 | public static String[] parseJsonStringArray(JSONArray input) throws JSONException {
11 | String[] output = new String[input.length()];
12 | for (int i = 0; i < input.length(); i++) {
13 | output[i] = input.getString(i);
14 | }
15 | return output;
16 | }
17 |
18 | public static T[] parseJsonObjectArray(JSONArray input, T[] output, JsonMapper mapper) throws JSONException {
19 | T[] sizedOutput = Arrays.copyOf(output, input.length());
20 | for (int i = 0; i < input.length(); i++) {
21 | sizedOutput[i] = mapper.invoke(input.getJSONObject(i));
22 | }
23 | return sizedOutput;
24 | }
25 |
26 | public static JSONArray stringifyObjectArray(T[] input, JsonMapper mapper) throws JSONException {
27 | JSONArray output = new JSONArray();
28 | for (int i = 0; i < input.length; i++) {
29 | output.put(mapper.invoke(input[i]));
30 | }
31 | return output;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/model/src/State.re:
--------------------------------------------------------------------------------
1 | [@decco]
2 | type timeState = {
3 | cached: option(array(string)),
4 | sourceDate: option(array(Js.Json.t)),
5 | [@decco.default "TIME_STATE"] [@decco.key "type"]
6 | type_: string,
7 | [@decco.default "TimeState"] [@decco.key "__typename"]
8 | typename: string,
9 | };
10 |
11 | type t =
12 | | TimeState(timeState)
13 | | NotImplemented_Passthrough(Js.Json.t);
14 |
15 | let makeTimeState = (~cached, ~sourceDate, ()) => {
16 | cached,
17 | sourceDate,
18 | type_: "TIME_STATE",
19 | typename: "TimeState",
20 | };
21 |
22 | let makeTimeStateFromGraphQL = timeState =>
23 | TimeState(
24 | makeTimeState(
25 | ~cached=timeState##cached,
26 | ~sourceDate=timeState##sourceDate,
27 | (),
28 | ),
29 | );
30 |
31 | let t_decode = json =>
32 | switch (json->Js.Json.classify) {
33 | | JSONObject(_) =>
34 | switch (timeState_decode(json)) {
35 | | Ok(timeState) => Ok(TimeState(timeState))
36 | | _ => Ok(NotImplemented_Passthrough(json))
37 | }
38 | | _ =>
39 | Error({
40 | Decco.path: "",
41 | message: "Expected JSONObject for state.",
42 | value: json,
43 | })
44 | };
45 |
46 | let t_encode =
47 | fun
48 | | TimeState(t) => timeState_encode(t)
49 | | NotImplemented_Passthrough(t) => t;
50 |
--------------------------------------------------------------------------------
/packages/model/src/Annotation.re:
--------------------------------------------------------------------------------
1 | [@decco]
2 | type t = {
3 | created: option(Js.Json.t),
4 | modified: option(Js.Json.t),
5 | id: option(string),
6 | target:
7 | array(
8 | [@decco.codec Target.codec] Target.t,
9 | ),
10 | body:
11 | option(
12 | array(
13 | [@decco.codec Body.codec] Body.t,
14 | ),
15 | ),
16 | [@decco.default "Annotation"] [@decco.key "__typename"]
17 | typename: string,
18 | };
19 |
20 | let make = (~id=?, ~target, ~body=?, ~created=?, ~modified=?, ()) => {
21 | id,
22 | target,
23 | body,
24 | typename: "Annotation",
25 | created:
26 | created
27 | ->Belt.Option.getWithDefault(
28 | Js.Date.(make()->toISOString)->Js.Json.string,
29 | )
30 | ->Js.Option.some,
31 | modified:
32 | modified
33 | ->Belt.Option.getWithDefault(
34 | Js.Date.(make()->toISOString)->Js.Json.string,
35 | )
36 | ->Js.Option.some,
37 | };
38 |
39 | let makeAnnotationFromGraphQL = (~makeTarget, ~makeBody, annotation) =>
40 | make(
41 | ~id=annotation##id,
42 | ~target=annotation##target->Belt.Array.keepMap(makeTarget),
43 | ~body=?
44 | annotation##body->Belt.Option.map(a => a->Belt.Array.keepMap(makeBody)),
45 | (),
46 | );
47 |
48 | let encode = t_encode;
49 | let decode = t_decode;
50 |
--------------------------------------------------------------------------------
/packages/web/src/QueryRenderers/QueryRenderers_NewAnnotationFromShare/QueryRenderers_NewAnnotationFromShare_GraphQL.re:
--------------------------------------------------------------------------------
1 | module GetAnnotationQuery = [%graphql
2 | {|
3 | query GetAnnotation($creatorUsername: String!, $id: String!) {
4 | getAnnotation(creatorUsername: $creatorUsername, id: $id) {
5 | id
6 | created
7 | __typename
8 | ...Containers_AnnotationEditor_GraphQL.GetAnnotationFragment.EditorNotesAnnotationFragment @bsField(name: "editorAnnotationFragment")
9 | ...Containers_NewAnnotationFromShareHeader_GraphQL.GetAnnotationFragment.HeaderAnnotationFragment @bsField(name: "headerAnnotationFragment")
10 | }
11 | }
12 | |}
13 | ];
14 |
15 | module CreateAnnotationMutation = [%graphql
16 | {|
17 | mutation NewAnnotationFromShare_CreateAnnotation($input: CreateAnnotationInput!) {
18 | createAnnotation(input: $input) {
19 | annotation {
20 | id
21 | created
22 | __typename
23 | ...Containers_AnnotationEditor_GraphQL.GetAnnotationFragment.EditorNotesAnnotationFragment @bsField(name: "editorAnnotationFragment")
24 | ...Containers_NewAnnotationFromShareHeader_GraphQL.GetAnnotationFragment.HeaderAnnotationFragment @bsField(name: "headerAnnotationFragment")
25 | }
26 | }
27 | }
28 | |}
29 | ];
30 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/Format.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | public enum Format {
4 | APPLICATION_X_MIMEARCHIVE,
5 | APPLICATION_OCTET_STREAM,
6 | MULTIPART_RELATED,
7 | IMAGE_PNG,
8 | TEXT_PLAIN,
9 | TEXT_HTML;
10 |
11 | public type.Format toGraphQL() {
12 | return type.Format.valueOf(this.name());
13 | }
14 |
15 | public static Format fromMimeType(String mimeType) {
16 | switch (mimeType.toLowerCase()) {
17 | case "image/png": return IMAGE_PNG;
18 | case "application/x-mimearchive": return APPLICATION_X_MIMEARCHIVE;
19 | case "text/plain": return TEXT_PLAIN;
20 | case "text/html": return TEXT_HTML;
21 | case "multipart/related": return MULTIPART_RELATED;
22 | default: return APPLICATION_OCTET_STREAM;
23 | }
24 | }
25 |
26 | public String toMimeType() {
27 | switch (this) {
28 | case APPLICATION_X_MIMEARCHIVE: return "application/x-mimearchive";
29 | case MULTIPART_RELATED: return "multipart/related";
30 | case IMAGE_PNG: return "image/png";
31 | case TEXT_PLAIN: return "text/plain";
32 | case TEXT_HTML: return "text/html";
33 | default: return "application/octet-stream";
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/bs-aws-amplify/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/bs-aws-amplify",
3 | "version": "1.0.1",
4 | "description": "BuckleScript bindings for aws-amplify.",
5 | "keywords": [
6 | "bucklescript",
7 | "reason",
8 | "aws-amplify"
9 | ],
10 | "main": "src/AwsAmplify.bs.js",
11 | "scripts": {
12 | "test": "echo \"Error: no test specified\" && exit 1",
13 | "bsb:build": "bsb -make-world",
14 | "bsb:start": "bsb -make-world -w",
15 | "bsb:clean": "bsb -clean-world",
16 | "start": "npm run bsb:start"
17 | },
18 | "author": {
19 | "name": "Daniel Ramirez",
20 | "email": "javamonn@hey.com",
21 | "url": "https://javamonn.com"
22 | },
23 | "repository": "https://github.com/literal-io/literal/tree/master/packages/apollo-link-analytics",
24 | "license": "MIT - Hippocratic 1.2",
25 | "dependencies": {
26 | "@aws-amplify/api": "^3.1.23",
27 | "@aws-amplify/auth": "^3.3.5",
28 | "@aws-amplify/cache": "^3.1.23",
29 | "@aws-amplify/core": "^3.4.6",
30 | "@aws-amplify/pubsub": "^3.0.24",
31 | "@aws-amplify/storage": "^3.2.13",
32 | "@literal-io/bs-amazon-cognito-identity-js": "^1.0.0",
33 | "bs-webapi": "^0.19.1"
34 | },
35 | "peerDependencies": {
36 | "bs-platform": "^8.4.2"
37 | },
38 | "devDependencies": {
39 | "bs-platform": "^8.4.2"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/web/src/components/TextInput/TextInput_Loading.re:
--------------------------------------------------------------------------------
1 | open Styles;
2 |
3 | [@react.component]
4 | let make = (~className=?, ~lineCount=8) => {
5 | let (margins, _setMargins) =
6 | React.useState(_ => {
7 | let margins = [|"", "mr-1", "mr-2", "mr-3", "mr-4", "mr-5"|];
8 | Belt.Array.make(lineCount, 0)
9 | ->Belt.Array.map(_ =>
10 | margins[Js.Math.random_int(0, Js.Array2.length(margins))]
11 | );
12 | });
13 |
14 |
16 |
17 | {Belt.Array.make(lineCount, 0)
18 | ->Belt.Array.mapWithIndex((idx, _) => {
19 |
24 | })
25 | ->React.array}
26 |
27 |
38 |
42 |
43 |
;
44 | };
45 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/repository/ToastRepository.java:
--------------------------------------------------------------------------------
1 | package io.literal.repository;
2 |
3 | import android.app.Activity;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 | import android.widget.Toast;
9 |
10 | import io.literal.R;
11 |
12 | public class ToastRepository {
13 |
14 | public static int STYLE_DARK_PRIMARY = 0;
15 | public static int STYLE_DARK_ACCENT = 1;
16 |
17 | public static void show(Activity activity, int resourceId, int style) {
18 | LayoutInflater inflater = activity.getLayoutInflater();
19 |
20 | View layout = inflater.inflate(
21 | style == STYLE_DARK_PRIMARY ? R.layout.toast_primary : R.layout.toast_accent,
22 | activity.findViewById(R.id.custom_toast_container)
23 | );
24 | TextView textView = layout.findViewById(R.id.text);
25 | textView.setText(activity.getResources().getText(resourceId));
26 |
27 | Toast toast = new Toast(activity.getApplicationContext());
28 | toast.setDuration(Toast.LENGTH_LONG);
29 | toast.setView(layout);
30 | toast.show();
31 | }
32 |
33 | public static void show(Activity activity, int textResourceId) {
34 | ToastRepository.show(activity, textResourceId, STYLE_DARK_PRIMARY);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/web/src/components/FooterLink/FooterLink.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~href, ~title, ~description) =>
3 |
4 |
12 |
19 |
20 |
26 | {React.string(title)}
27 |
28 |
34 | {React.string(description)}
35 |
36 |
37 |
46 |
47 |
48 | ;
49 |
--------------------------------------------------------------------------------
/packages/android/app/src/foss/res/raw/amplifyconfiguration.json:
--------------------------------------------------------------------------------
1 | {"UserAgent":"aws-amplify-cli/2.0","Version":"1.0","api":{"plugins":{"awsAPIPlugin":{"literal":{"endpointType":"GraphQL","endpoint":"https://2dxxqoarong2jd4ukbeugsg5t4.appsync-api.us-east-1.amazonaws.com/graphql","region":"us-east-1","authorizationType":"AMAZON_COGNITO_USER_POOLS"}}}},"auth":{"plugins":{"awsCognitoAuthPlugin":{"UserAgent":"aws-amplify-cli/0.1.0","Version":"0.1.0","IdentityManager":{"Default":{}},"CredentialsProvider":{"CognitoIdentity":{"Default":{"PoolId":"us-east-1:12bb0b85-e6e1-4964-9f0d-24d14b90398d","Region":"us-east-1"}}},"CognitoUserPool":{"Default":{"PoolId":"us-east-1_EWCESLVzL","AppClientId":"1geu7qgt6hdrs4a3e9tn4leg1","Region":"us-east-1"}},"Auth":{"Default":{"authenticationFlowType":"USER_SRP_AUTH"}},"AppSync":{"Default":{"ApiUrl":"https://2dxxqoarong2jd4ukbeugsg5t4.appsync-api.us-east-1.amazonaws.com/graphql","Region":"us-east-1","AuthMode":"AMAZON_COGNITO_USER_POOLS","ClientDatabasePrefix":"literal_AMAZON_COGNITO_USER_POOLS"},"literal_AWS_IAM":{"ApiUrl":"https://2dxxqoarong2jd4ukbeugsg5t4.appsync-api.us-east-1.amazonaws.com/graphql","Region":"us-east-1","AuthMode":"AWS_IAM","ClientDatabasePrefix":"literal_AWS_IAM"}},"S3TransferUtility":{"Default":{"Bucket":"literal-storage114446-production","Region":"us-east-1"}}}}},"storage":{"plugins":{"awsS3StoragePlugin":{"bucket":"literal-storage114446-production","region":"us-east-1","defaultAccessLevel":"guest"}}}}
--------------------------------------------------------------------------------
/packages/web/src/components/Markdown/Markdown.module.css:
--------------------------------------------------------------------------------
1 | .md {
2 | @apply text-lightPrimary;
3 | }
4 | .md > h1 {
5 | @apply mb-8 font-serif text-xl;
6 | }
7 | .md > h2 {
8 | @apply pb-2 mt-12 mb-8 font-serif text-xl border-b border-dotted border-lightDisabled;
9 | }
10 | .md > h3 {
11 | @apply mt-8 mb-4 font-serif text-xl;
12 | }
13 | .md > p {
14 | @apply mb-8 font-sans text-lg leading-relaxed;
15 | color: rgba(255, 255, 255, 0.92);
16 | }
17 |
18 | .md > details {
19 | @apply mt-12;
20 | }
21 |
22 | .md ol li,
23 | .md ul li {
24 | @apply mb-4 font-sans text-lg leading-relaxed;
25 | color: rgba(255, 255, 255, 0.92);
26 | }
27 | .md a {
28 | @apply underline;
29 | }
30 | .md > ul {
31 | @apply mb-10 ml-6 list-inside list-square;
32 | }
33 |
34 | .md > blockquote {
35 | @apply pl-4 mt-8 mb-8 font-serif text-lg leading-relaxed border-l-2 text-lightPrimary;
36 | }
37 |
38 | .md > figure > figcaption {
39 | @apply ml-4 italic text-lightSecondary;
40 | }
41 |
42 | .md > figure {
43 | @apply mb-10;
44 | }
45 |
46 | .md > iframe {
47 | @apply w-full mt-8 mb-8;
48 | }
49 |
50 | .md > div {
51 | @apply mb-8 !important;
52 | }
53 |
54 | .md > p > code,
55 | .md > ul > li > code {
56 | @apply p-1 rounded-sm bg-lightPrimary;
57 | color: rgba(0, 0, 0, .92);
58 | }
59 |
60 | .md > details > summary {
61 | @apply mb-4;
62 | }
63 |
64 | .md > details > p {
65 | @apply text-lg text-lightPrimary;
66 | }
67 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/res/layout/activity_share_target_handler.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
19 |
20 |
21 |
22 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/packages/web/src/components/PromptIconButton/PromptIconButton.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~icon, ~label, ~className=?, ~onClick=?, ~href=?) => {
3 |
27 |
31 |
42 |
50 | {React.string(label)}
51 |
52 |
53 | ;
54 | };
55 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/waves.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_NewAnnotationHeader/Containers_NewAnnotationHeader.re:
--------------------------------------------------------------------------------
1 | open Styles;
2 |
3 | [@react.component]
4 | let make = () => {
5 | let handleClose = () => {
6 | let _ = Next.Router.back();
7 | ();
8 | };
9 |
10 |
23 | {
27 | let _ =
28 | Service_Analytics.(track(Click({action: "close", label: None})));
29 | handleClose();
30 | }}
31 | _TouchRippleProps={
32 | "classes": {
33 | "child": cn(["bg-white"]),
34 | "rippleVisible": cn(["opacity-50"]),
35 | },
36 | }
37 | classes={MaterialUi.IconButton.Classes.make(~root=cn(["p-0"]), ())}>
38 |
42 |
43 |
51 | {React.string("Create Annotation")}
52 |
53 | ;
54 | };
55 |
--------------------------------------------------------------------------------
/packages/web/src/Providers/Providers_ModalNavigation/Providers_ModalNavigation.re:
--------------------------------------------------------------------------------
1 | type context = {
2 | onNext: (unit => unit) => unit,
3 | setOnNext: option(unit => unit) => unit,
4 | };
5 |
6 | let context = React.createContext({onNext: _ => (), setOnNext: _ => ()});
7 |
8 | module ContextProvider = {
9 | include React.Context;
10 |
11 | let makeProps = (~value, ~children, ()) => {
12 | "value": value,
13 | "children": children,
14 | };
15 | let make = React.Context.provider(context);
16 | };
17 |
18 | [@react.component]
19 | let make = (~children) => {
20 | let preparedNavigation = React.useRef(false);
21 | let (onNext, setOnNext) = React.useState(_ => None);
22 | let router = Next.Router.useRouter();
23 |
24 | let handleOnNext = defaultAction => {
25 | let cb = onNext->Belt.Option.getWithDefault(defaultAction);
26 | let _ = setOnNext(_ => None);
27 | let _ = cb();
28 | ();
29 | };
30 | let _ =
31 | React.useEffect3(
32 | () => {
33 | if (!preparedNavigation.current) {
34 | let _ = setOnNext(_ => None);
35 | ();
36 | };
37 | preparedNavigation.current = false;
38 | None;
39 | },
40 | (router.asPath, router.route, router.query),
41 | );
42 |
43 | let handleSetOnNext = action => {
44 | setOnNext(_ => action);
45 | preparedNavigation.current = true;
46 | ();
47 | };
48 |
49 |
50 | children
51 | ;
52 | };
53 |
--------------------------------------------------------------------------------
/packages/android/source-webview-scripts/annotation-renderer/messenger.mjs:
--------------------------------------------------------------------------------
1 | export class Messenger {
2 | constructor() {
3 | this.handlers = new Map();
4 | this.eventQueue = [];
5 |
6 | window.addEventListener("message", (ev) => {
7 | if (ev.ports && ev.ports.length > 0 && !window.literalMessagePort) {
8 | window.literalMessagePort = ev.ports[0];
9 | this.eventQueue.forEach(this.postMessage);
10 | this.eventQueue = [];
11 | }
12 |
13 | this._handleMessage(ev);
14 | });
15 |
16 | if (!window.literalMessagePort && window.literalWebview) {
17 | window.literalWebview.sendMessagePort();
18 | }
19 | }
20 |
21 | _handleMessage(ev) {
22 | try {
23 | const data = JSON.parse(ev.data);
24 |
25 | console.log("[Literal] Receieved message", ev.data);
26 | if (this.handlers.has(data.type)) {
27 | this.handlers.get(data.type).forEach((handler) => handler(data));
28 | }
29 | } catch (e) {
30 | console.log("[Literal] Unable to parse message", ev.data);
31 | }
32 | }
33 |
34 | postMessage(ev) {
35 | if (!window.literalMessagePort) {
36 | this.eventQueue.push(ev);
37 | return;
38 | }
39 | console.log("[Literal] postMessage: " + JSON.stringify(ev))
40 | window.literalMessagePort.postMessage(JSON.stringify(ev));
41 | }
42 |
43 | on(type, handler) {
44 | if (!this.handlers.has(type)) {
45 | this.handlers.set(type, [handler]);
46 | } else {
47 | this.handlers.get(type).push(handler);
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/packages/web/src/Lib/Lib_Apollo/Lib_Apollo_Cache.re:
--------------------------------------------------------------------------------
1 | module type CacheConfig = {type t;};
2 |
3 | module Make = (Query: ReasonApolloTypes.Config, CacheConfig: CacheConfig) => {
4 | module CacheReadQuery = ApolloClient.ReadQuery(Query);
5 | module CacheWriteQuery = ApolloClient.WriteQuery(Query);
6 |
7 | external unsafeToCache: Js.Json.t => CacheConfig.t = "%identity";
8 | external unsafeCacheToJson: CacheConfig.t => Js.Json.t = "%identity";
9 |
10 | /**
11 | * FIXME: Return type is not actually Query.t, as Apollo cache
12 | * does not persist fragment alias fields -- everything is
13 | * inlined on the root type.
14 | */
15 | let readCache = (~query, ~client, ()) => {
16 | let readQueryOptions =
17 | CacheReadQuery.{
18 | query: ApolloClient.gql(. query##query),
19 | variables: Js.Nullable.fromOption(Some(query##variables)),
20 | };
21 | switch (CacheReadQuery.readQuery(client, readQueryOptions)) {
22 | | exception _ => None
23 | | cachedResponse =>
24 | cachedResponse->Js.Nullable.toOption->Belt.Option.map(unsafeToCache)
25 | };
26 | };
27 |
28 | /**
29 | * Data in cache format, i.e. everything inlined on GraphQL types. Not a good
30 | * way to enforce type safety.
31 | */
32 | external unsafeFromCache: CacheConfig.t => Query.t = "%identity";
33 | let writeCache = (~query, ~client, ~data: CacheConfig.t, ()) =>
34 | CacheWriteQuery.make(
35 | ~client,
36 | ~variables=query##variables,
37 | ~data=unsafeFromCache(data),
38 | (),
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/packages/android/app/src/foss/java/io/literal/repository/AnalyticsRepository.java:
--------------------------------------------------------------------------------
1 | package io.literal.repository;
2 |
3 | import android.app.Application;
4 | import android.util.Log;
5 | import org.json.JSONObject;
6 |
7 |
8 | public class AnalyticsRepository {
9 |
10 | public static final String TYPE_GRAPH_QL_OPERATION = "GRAPH_QL_OPERATION";
11 | public static final String TYPE_ACTIVITY_START = "ACTIVITY_START";
12 | public static final String TYPE_DISPATCHED_WEB_EVENT = "DISPATCHED_WEB_EVENT";
13 | public static final String TYPE_RECEIVED_WEB_EVENT = "RECEIVED_WEB_EVENT";
14 | public static final String TYPE_CLICK = "CLICK";
15 | public static final String TYPE_DISPATCH_SERVICE_INTENT = "DISPATCH_SERVICE_INTENT";
16 | public static final String TYPE_HANDLE_INTENT_START = "HANDLE_INTENT_START";
17 | public static final String TYPE_HANDLE_INTENT_COMPLETE = "HANDLE_INTENT_COMPLETE";
18 | public static final String TYPE_ANNOTATION_RENDERER_INITIALIZED = "ANNOTATION_RENDERER_INITIALIZED";
19 | public static final String TYPE_ANNOTATION_RENDERER_FAILED_TO_INITIALIZE = "ANNOTATION_RENDERER_FAILED_TO_INITIALIZE";
20 |
21 | public static void initialize(Application application) {
22 | Log.d("AnalyticsRepository", "initialize");
23 | }
24 |
25 | public static void logEvent(String type, JSONObject data) {
26 | Log.d("AnalyticsRepository", "logEvent: " + type + ", " + data.toString());
27 | }
28 |
29 | public static void setUserId(String userId) {
30 | Log.d("AnalyticsRepository", "setUserId: " + userId);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/web/src/QueryRenderers/QueryRenderers_WebView_EditAnnotationTags/QueryRenderers_WebView_EditAnnotationTags.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~identityId, ~annotation, ~onAnnotationChange, ~onCollapse) => {
3 | let handleAnnotationChange = newAnnotation => {
4 | let _ = onAnnotationChange(newAnnotation);
5 |
6 | let allBodiesHaveId =
7 | newAnnotation.LiteralModel.Annotation.body
8 | ->Belt.Option.getWithDefault([||])
9 | ->Belt.Array.every(
10 | fun
11 | | TextualBody({id}) when Js.String2.startsWith(id, "https") => true
12 | | TextualBody(_) => false
13 | | _ => true,
14 | );
15 |
16 | let _ =
17 | if (allBodiesHaveId) {
18 | let _ =
19 | Webview.(
20 | postMessage(
21 | WebEvent.make(
22 | ~type_="EDIT_ANNOTATION_TAGS_RESULT",
23 | ~data=LiteralModel.Annotation.encode(newAnnotation),
24 | (),
25 | ),
26 | )
27 | );
28 | ();
29 | };
30 | ();
31 | };
32 |
33 |
43 | onCollapse()}
45 | />
46 |
51 |
;
52 | };
53 |
--------------------------------------------------------------------------------
/packages/android/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/model/Selector.java:
--------------------------------------------------------------------------------
1 | package io.literal.model;
2 |
3 | import android.util.JsonReader;
4 | import android.util.Log;
5 |
6 | import org.json.JSONException;
7 | import org.json.JSONObject;
8 |
9 | import io.literal.repository.ErrorRepository;
10 | import type.AnnotationTargetInput;
11 | import type.SelectorInput;
12 |
13 | public class Selector {
14 | public enum Type {
15 | RANGE_SELECTOR,
16 | XPATH_SELECTOR,
17 | TEXT_POSITION_SELECTOR
18 | };
19 |
20 | private final Type type;
21 |
22 | public Selector(Type type) {
23 | this.type = type;
24 | }
25 |
26 | public Type getType() {
27 | return type;
28 | }
29 |
30 | public JSONObject toJson() throws JSONException {
31 | throw new JSONException("toJson not implemented.");
32 | };
33 |
34 | public SelectorInput toSelectorInput() {
35 | ErrorRepository.captureException(new Exception("Attempted to call toSelectorInput, but not implemented."));
36 | return null;
37 | }
38 |
39 | public static Selector fromJson(JSONObject json) throws JSONException {
40 | String type = json.getString("type");
41 | if (type.equals(Type.RANGE_SELECTOR.name())) {
42 | return RangeSelector.fromJson(json);
43 | } else if (type.equals(Type.XPATH_SELECTOR.name())) {
44 | return XPathSelector.fromJson(json);
45 | } else if (type.equals(Type.TEXT_POSITION_SELECTOR.name())) {
46 | return TextPositionSelector.fromJson(json);
47 | }
48 |
49 | return null;
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_NewAnnotationFromShareEditor/Containers_NewAnnotationFromShareEditor_GraphQL.re:
--------------------------------------------------------------------------------
1 | module PatchAnnotationMutation = [%graphql
2 | {|
3 | mutation PatchAnnotation(
4 | $input: PatchAnnotationInput!
5 | ) {
6 | patchAnnotation(input: $input) {
7 | annotation {
8 | ...Containers_AnnotationEditor_GraphQL.GetAnnotationFragment.EditorNotesAnnotationFragment @bsField(name: "editorAnnotationFragment")
9 | }
10 | }
11 | }
12 | |}
13 | ];
14 |
15 | module GetAnnotationFragment = [%graphql
16 | {|
17 | fragment editorNewFromShareAnnotationFragment on Annotation {
18 | id
19 | modified
20 | target {
21 | ... on TextualTarget {
22 | value
23 | __typename
24 |
25 | textualTargetId: id
26 | format
27 | language
28 | processingLanguage
29 | textDirection
30 | accessibility
31 | rights
32 | }
33 | ... on ExternalTarget {
34 | __typename
35 |
36 | externalTargetId: id
37 | format
38 | language
39 | processingLanguage
40 | textDirection
41 | type_: type
42 | accessibility
43 | rights
44 | }
45 | }
46 | body {
47 | ... on TextualBody {
48 | id
49 | value
50 | purpose
51 | __typename
52 |
53 | format
54 | language
55 | processingLanguage
56 | textDirection
57 | accessibility
58 | rights
59 | }
60 | }
61 | }
62 | |}
63 | ];
64 |
--------------------------------------------------------------------------------
/packages/web/src/Providers/Providers_Apollo/Providers_Apollo_Client.re:
--------------------------------------------------------------------------------
1 | let fragmentTypes = [%raw "require('../../../fragment-types.json')"];
2 |
3 | let appSyncCache =
4 | ApolloInMemoryCache.createInMemoryCache(
5 | ~fragmentMatcher=
6 | ApolloInMemoryCache.introspectionFragmentMatcher({
7 | "introspectionQueryResultData": fragmentTypes,
8 | }),
9 | (),
10 | );
11 |
12 | let makeClientFromUser = user => {
13 | let auth =
14 | switch (user) {
15 | | Providers_Authentication_User.GuestUser({credentials}) =>
16 | credentials
17 | ->Providers_Apollo_AppSync.makeGuestClientAuthOptions
18 | ->Js.Option.some
19 | | SignedInUser({cognitoUserSession})
20 | | SignedInUserMergingIdentites({cognitoUserSession}) =>
21 | cognitoUserSession
22 | ->Providers_Apollo_AppSync.makeAuthenticatedClientAuthOptions
23 | ->Js.Option.some
24 | | SignedOutPromptAuthentication
25 | | Unknown => None
26 | };
27 |
28 | let appSyncLinkOptions =
29 | Providers_Apollo_AppSync.makeAppSyncLinkOptions(~auth);
30 | let appSyncLink = Providers_Apollo_AppSync.(makeLink(appSyncLinkOptions));
31 |
32 | AwsAppSync.Client.(
33 | makeWithOptions(
34 | appSyncLinkOptions,
35 | {
36 | link:
37 | Some(
38 | ApolloLinks.from([|
39 | Providers_Apollo_AnalyticsLink.link,
40 | appSyncLink,
41 | |]),
42 | ),
43 | cache: Some(appSyncCache),
44 | },
45 | )
46 | );
47 | };
48 |
49 | // FIXME: This should get exposed via react context.
50 | let inst = ref(makeClientFromUser(Providers_Authentication_User.Unknown));
51 |
--------------------------------------------------------------------------------
/packages/android/app/src/main/java/io/literal/service/SplashService.java:
--------------------------------------------------------------------------------
1 | package io.literal.service;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.app.Activity;
6 | import android.view.View;
7 | import android.view.Window;
8 |
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | import io.literal.R;
12 |
13 | public class SplashService {
14 |
15 | public static void hide(Activity activity, @NotNull View view) {
16 | int shortAnimationDuration = activity.getResources().getInteger(android.R.integer.config_shortAnimTime);
17 | view.animate()
18 | .alpha(0f)
19 | .setDuration(shortAnimationDuration)
20 | .setListener(new AnimatorListenerAdapter() {
21 | @Override
22 | public void onAnimationEnd(Animator animation) {
23 | view.setVisibility(View.GONE);
24 | }
25 | });
26 | setChromeColor(activity, R.color.colorDarkAccent);
27 | }
28 |
29 | public static boolean isVisible(@NotNull View view) {
30 | return view.getVisibility() == View.VISIBLE;
31 | }
32 |
33 | public static void show(Activity activity, @NotNull View view) {
34 | view.setVisibility(View.VISIBLE);
35 | setChromeColor(activity, R.color.colorPrimaryDark);
36 | }
37 |
38 | private static void setChromeColor(@NotNull Activity activity, int colorId) {
39 | Window window = activity.getWindow();
40 | int color = activity.getResources().getColor(colorId, activity.getTheme());
41 |
42 | window.setStatusBarColor(color);
43 | window.setNavigationBarColor(color);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/packages/model/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@literal-io/model",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@literal-io/model",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "bs-platform": "8.2.0",
13 | "decco": "1.3.0"
14 | }
15 | },
16 | "node_modules/bs-platform": {
17 | "version": "8.2.0",
18 | "resolved": "https://registry.npmjs.org/bs-platform/-/bs-platform-8.2.0.tgz",
19 | "integrity": "sha512-quvmUac/ZxGDsT7L5+6RNXrLPvLHkWFownacaqlwVoyAm770bPyupTRU49ALPGk3HpjfD5eE+lpGdOSPtuwJiA==",
20 | "dev": true,
21 | "hasInstallScript": true,
22 | "bin": {
23 | "bsb": "bsb",
24 | "bsc": "bsc",
25 | "bsrefmt": "bsrefmt",
26 | "bstracing": "lib/bstracing"
27 | }
28 | },
29 | "node_modules/decco": {
30 | "version": "1.3.0",
31 | "resolved": "https://registry.npmjs.org/decco/-/decco-1.3.0.tgz",
32 | "integrity": "sha512-pednHg+Skby+sw193hbHTRLihZskmXrPsVMlqL9XpuLm+HfwMgS76lFRAkTGAi3435q0TBygTpt8McVTyk4Sfw==",
33 | "dev": true,
34 | "peerDependencies": {
35 | "bs-platform": "6 || 7 || 8"
36 | }
37 | }
38 | },
39 | "dependencies": {
40 | "bs-platform": {
41 | "version": "8.2.0",
42 | "resolved": "https://registry.npmjs.org/bs-platform/-/bs-platform-8.2.0.tgz",
43 | "integrity": "sha512-quvmUac/ZxGDsT7L5+6RNXrLPvLHkWFownacaqlwVoyAm770bPyupTRU49ALPGk3HpjfD5eE+lpGdOSPtuwJiA==",
44 | "dev": true
45 | },
46 | "decco": {
47 | "version": "1.3.0",
48 | "resolved": "https://registry.npmjs.org/decco/-/decco-1.3.0.tgz",
49 | "integrity": "sha512-pednHg+Skby+sw193hbHTRLihZskmXrPsVMlqL9XpuLm+HfwMgS76lFRAkTGAi3435q0TBygTpt8McVTyk4Sfw==",
50 | "dev": true,
51 | "requires": {}
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/packages/web/src/Containers/Containers_AnnotationCollectionHeader/Containers_AnnotationCollectionHeader_GraphQL.re:
--------------------------------------------------------------------------------
1 | module GetAnnotationCollectionFragment = [%graphql
2 | {|
3 | fragment AnnotationCollectionHeader_AnnotationCollection on AnnotationCollection {
4 | label
5 | id
6 | type_: type
7 | }
8 | |}
9 | ];
10 |
11 | let cacheAnnotationCollectionFragment =
12 | ApolloClient.gql(.
13 | {|
14 | fragment Cache_AnnotationCollectionHeader_AnnotationCollection on AnnotationCollection {
15 | label
16 | id
17 | type_: type
18 | }
19 | |},
20 | );
21 |
22 | module GetAnnotationFragment = [%graphql
23 | {|
24 | fragment AnnotationCollectionHeader_Annotation on Annotation {
25 | id
26 | body {
27 | ... on TextualBody {
28 | __typename
29 | id
30 | value
31 | purpose
32 | }
33 | }
34 | target {
35 | ... on ExternalTarget {
36 | __typename
37 | externalTargetId: id
38 | format
39 | }
40 | ... on SpecificTarget {
41 | __typename
42 | specificTargetId: id
43 | source {
44 | ... on ExternalTarget {
45 | externalTargetId: id,
46 | format
47 | __typename
48 | }
49 | }
50 | }
51 | ... on TextualTarget {
52 | value
53 | __typename
54 |
55 | textualTargetId: id
56 | }
57 | }
58 | }
59 | |}
60 | ];
61 |
62 | module DeleteAnnotationMutation = [%graphql
63 | {|
64 | mutation DeleteAnnotation($input: DeleteAnnotationInput!) {
65 | deleteAnnotation(input: $input) {
66 | annotation {
67 | id
68 | }
69 | }
70 | }
71 | |}
72 | ];
73 |
--------------------------------------------------------------------------------
/packages/web/src/components/ExternalTargetCard/ExternalTargetCard.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make =
3 | (
4 | ~externalTargetFragment as externalTarget,
5 | ~textualTargetFragment as textualTarget,
6 | ~onClick,
7 | ) => {
8 | let host =
9 | externalTarget##externalTargetId->Webapi.Url.make->Webapi.Url.host;
10 |
11 |
34 | ()}
36 | disabled=true
37 | value=textualTarget##value
38 | inputClasses={MaterialUi.Input.Classes.make(
39 | ~root=Cn.fromList(["p-4"]),
40 | ~inputMultiline=Cn.fromList(["px-0"]),
41 | (),
42 | )}
43 | />
44 |
53 |
60 | {React.string(host)}
61 |
62 |
63 | ;
64 | };
65 |
--------------------------------------------------------------------------------
/packages/bs-aws-appsync/src/AwsAppSync.re:
--------------------------------------------------------------------------------
1 | module Client = {
2 | [@bs.deriving abstract]
3 | type authOptions = {
4 | [@bs.as "type"]
5 | type_: string,
6 | [@bs.optional]
7 | jwtToken: unit => Js.Promise.t(AmazonCognitoIdentity.JwtToken.t),
8 | [@bs.optional]
9 | credentials: unit => Js.Promise.t(AwsAmplify.Credentials.t),
10 | };
11 |
12 | let authWithCognitoUserPools = (~jwtToken) =>
13 | authOptions(~type_="AMAZON_COGNITO_USER_POOLS", ~jwtToken, ());
14 | let authWithIAM = (~credentials) =>
15 | authOptions(~type_="AWS_IAM", ~credentials, ());
16 |
17 | type appSyncLinkOptions = {
18 | url: string,
19 | region: string,
20 | auth: option(authOptions),
21 | disableOffline: bool,
22 | mandatorySignIn: bool,
23 | complexObjectsCredentials:
24 | unit => Js.Promise.t(AwsAmplify.Credentials.t),
25 | };
26 | [@bs.module "aws-appsync"]
27 | external createAppSyncLink:
28 | appSyncLinkOptions => ReasonApolloTypes.apolloLink =
29 | "createAppSyncLink";
30 |
31 | [@bs.new] [@bs.module "aws-appsync"]
32 | external make: appSyncLinkOptions => ApolloClient.generatedApolloClient =
33 | "default";
34 |
35 | type makeWithApolloOptions = {
36 | link: option(ReasonApolloTypes.apolloLink),
37 | cache: option(ReasonApolloTypes.apolloCache),
38 | };
39 |
40 | [@bs.new] [@bs.module "aws-appsync"]
41 | external makeWithOptions:
42 | (appSyncLinkOptions, makeWithApolloOptions) =>
43 | ApolloClient.generatedApolloClient =
44 | "default";
45 | };
46 |
47 | module Rehydrated = {
48 | type renderProps = {rehydrated: bool};
49 | [@bs.module "aws-appsync-react"] [@react.component]
50 | external make:
51 | (~render: renderProps => React.element=?, ~children: React.element=?) =>
52 | React.element =
53 | "Rehydrated";
54 | };
55 |
--------------------------------------------------------------------------------
/packages/web/src/Providers/Providers_Apollo/Providers_Apollo_AppSync.re:
--------------------------------------------------------------------------------
1 | let getWebviewCredentials = () =>
2 | Timer.thunkP(~label="AUTH_GET_CREDENTIALS", () =>
3 | Webview.postMessageForResult(
4 | Webview.WebEvent.make(~type_="AUTH_GET_CREDENTIALS", ()),
5 | )
6 | )
7 | |> Js.Promise.then_(credentialsJson => {
8 | credentialsJson
9 | ->Belt.Option.flatMap(credentialsJson =>
10 | switch (Providers_Apollo_Credentials.decode(credentialsJson)) {
11 | | Ok(credentials) => Some(credentials)
12 | | Error(e) =>
13 | let _ = Error.(report(DeccoDecodeError(e)));
14 | None;
15 | }
16 | )
17 | ->Js.Promise.resolve
18 | });
19 |
20 | let makeAuthenticatedClientAuthOptions = cognitoUserSession =>
21 | AwsAppSync.Client.authWithCognitoUserPools(~jwtToken=() =>
22 | cognitoUserSession
23 | ->AmazonCognitoIdentity.UserSession.getIdToken
24 | ->AmazonCognitoIdentity.IdToken.getJwtToken
25 | ->Js.Promise.resolve
26 | );
27 |
28 | let makeGuestClientAuthOptions = credentials =>
29 | AwsAppSync.Client.authWithIAM(~credentials=() =>
30 | credentials
31 | ->Providers_Authentication_Credentials.toAmplifyCredentials
32 | ->Js.Promise.resolve
33 | );
34 |
35 | let makeAppSyncLinkOptions = (~auth) =>
36 | AwsAppSync.Client.{
37 | url:
38 | AwsAmplify.(
39 | Constants.awsAmplifyConfig->Config.appSyncGraphqlEndpointGet
40 | ),
41 | region: AwsAmplify.(Constants.awsAmplifyConfig->Config.appSyncRegionGet),
42 | auth,
43 | disableOffline: true,
44 | complexObjectsCredentials: () =>
45 | AwsAmplify.Auth.(inst->currentCredentials),
46 | mandatorySignIn: false,
47 | };
48 |
49 | let makeLink = appSyncLinkOptions =>
50 | AwsAppSync.Client.createAppSyncLink(appSyncLinkOptions);
51 |
--------------------------------------------------------------------------------
/packages/web/src/components/TextInput/TextInput_Annotation.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make =
3 | (
4 | ~onChange,
5 | ~value,
6 | ~onFocus=?,
7 | ~onBlur=?,
8 | ~disabled=?,
9 | ~autoFocus=?,
10 | ~placeholder=?,
11 | ~tagsInputRef=?,
12 | ~textInputRef=?,
13 | ~inputClasses=?
14 | ) => {
15 | /** Reuse the ref prop if one was passed in, otherwise use our own **/
16 | let textInputRef = {
17 | let ownRef = React.useRef(Js.Nullable.null);
18 | switch (textInputRef) {
19 | | Some(textInputRef) => textInputRef
20 | | None => ownRef
21 | };
22 | };
23 | let tagsInputRef = {
24 | let ownRef = React.useRef(Js.Nullable.null);
25 | switch (tagsInputRef) {
26 | | Some(tagsInputRef) => tagsInputRef
27 | | None => ownRef
28 | };
29 | };
30 |
31 | let handleTextKeyDown = ev => {
32 | let handled =
33 | switch (ev->ReactEvent.Keyboard.keyCode) {
34 | | 51 /*** # **/ =>
35 | switch (tagsInputRef.current->Js.Nullable.toOption) {
36 | | Some(inputElem) =>
37 | let _ =
38 | inputElem
39 | ->Webapi.Dom.Element.unsafeAsHtmlElement
40 | ->Webapi.Dom.HtmlElement.focus;
41 | true;
42 | | None => false
43 | }
44 | | _ => false
45 | };
46 | let _ =
47 | if (handled) {
48 | let _ = ev->ReactEvent.Keyboard.preventDefault;
49 | let _ = ev->ReactEvent.Keyboard.stopPropagation;
50 | ();
51 | };
52 | ();
53 | };
54 |
55 | ;
67 | };
68 |
--------------------------------------------------------------------------------
/packages/web/src/components/Svg/Svg.re:
--------------------------------------------------------------------------------
1 | let done_: string = [%raw "require('./done.svg')"];
2 | let close: string = [%raw "require('./close.svg')"];
3 | let back: string = [%raw "require('./back.svg')"];
4 | let removeCircle: string = [%raw "require('./remove-circle.svg')"];
5 | let delete: string = [%raw "require('./delete.svg')"];
6 | let logo: string = [%raw "require('./logo.svg')"];
7 | let arrowRight: string = [%raw "require('./arrow-right.svg')"];
8 | let arrowDown: string = [%raw "require('./arrow-down.svg')"];
9 | let arrowUp: string = [%raw "require('./arrow-up.svg')"];
10 | let add: string = [%raw "require('./add.svg')"];
11 | let addCircle: string = [%raw "require('./add-circle.svg')"];
12 | let textFields: string = [%raw "require('./text-fields.svg')"];
13 | let textSnippet: string = [%raw "require('./text-snippet.svg')"];
14 | let label: string = [%raw "require('./label.svg')"];
15 | let helpOutline: string = [%raw "require('./help-outline.svg')"];
16 | let language: string = [%raw "require('./language.svg')"];
17 | let waves: string = [%raw "require('./waves.svg')"];
18 | let android: string = [%raw "require('./android.svg')"];
19 | let apple: string = [%raw "require('./apple.svg')"];
20 | let errorOutline: string = [%raw "require('./error-outline.svg')"];
21 | let more: string = [%raw "require('./more.svg')"];
22 | let article: string = [%raw "require('./article.svg')"];
23 | let manageAccounts: string = [%raw "require('./manage-accounts.svg')"];
24 | let highlight: string = [%raw "require('./highlight.svg')"];
25 | let source: string = [%raw "require('./source.svg')"];
26 | let shareBlack: string = [%raw "require('./share-black.svg')"];
27 | let deleteBlack: string = [%raw "require('./delete-black.svg')"];
28 |
29 | [@react.component]
30 | let make = (~className=?, ~style=?, ~onClick=?, ~icon) => {
31 |
;
32 | };
33 |
--------------------------------------------------------------------------------