├── .babelrc ├── .env.default ├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── node.js.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .storybook ├── main.js └── preview.js ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── android ├── .gitignore ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── boostio │ │ │ └── boostnote │ │ │ └── ExampleInstrumentedTest.kt │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── boostio │ │ │ │ └── boostnote │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ │ ├── layout │ │ │ └── activity_main.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values-night │ │ │ └── themes.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ ├── styles.xml │ │ │ └── themes.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── boostio │ │ └── boostnote │ │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── build-utils └── afterSignHook.js ├── cloud-static ├── editor.css ├── favicon.ico ├── images │ ├── apple-icon-180x180.png │ ├── doc.png │ ├── google-play-store-badge.svg │ ├── img_centralize.png │ ├── img_coauthoring.png │ ├── img_coauthoring_2.png │ ├── img_customblock.png │ ├── img_devtool.png │ ├── img_diagrams.png │ ├── img_embed.png │ ├── img_embedding.png │ ├── img_features.png │ ├── img_folders.png │ ├── img_formula.png │ ├── img_hero.png │ ├── img_import.png │ ├── img_integrations.png │ ├── img_keyboard.png │ ├── img_markdown.png │ ├── img_public-private-sharing.jpg │ ├── img_publicAPI.png │ ├── img_share.png │ ├── img_teams.png │ ├── img_timeline.png │ ├── img_unlimited-cloud-doc.jpg │ ├── img_version-history.jpg │ ├── img_workflow.png │ ├── initial │ │ ├── step1-1.png │ │ ├── step1-2.png │ │ ├── step1-3.png │ │ ├── step1-4.png │ │ ├── step1-5.png │ │ ├── step1-6.png │ │ ├── step1-7.gif │ │ ├── step2-1.png │ │ ├── step2-2.png │ │ ├── step3-1.png │ │ ├── step3-2.png │ │ ├── step3-3.png │ │ ├── step4-1.png │ │ ├── step4-2.png │ │ ├── step4-3.png │ │ ├── step4-4.png │ │ ├── step4-5.png │ │ ├── step5-1.png │ │ ├── step5-2.png │ │ ├── step5-3.png │ │ └── step6.gif │ ├── ios-app-store-badge.svg │ ├── logo.png │ ├── logo_boostnote_forteams.svg │ ├── logo_symbol.svg │ ├── ogp.jpg │ ├── private_folders.png │ ├── realtime.png │ ├── support_profile.jpg │ ├── unlimited_dashboards.png │ └── unlimited_documents.png ├── logos │ ├── airtable.png │ ├── asana.png │ ├── aws.png │ ├── aws_lambda.png │ ├── clickup.png │ ├── confluence.svg │ ├── dropbox.png │ ├── dropboxpaper.svg │ ├── evernote.svg │ ├── github.png │ ├── gmail.png │ ├── google_calendar.png │ ├── google_drive.png │ ├── google_spreadsheet.png │ ├── intercom.png │ ├── jira.png │ ├── mailchimp.png │ ├── miro.png │ ├── notion.svg │ ├── office_365.png │ ├── quip.svg │ ├── slack.png │ ├── stripe.jpeg │ ├── trello.png │ └── zapier.png ├── mixpanel.js └── videos │ └── pro-intro.mp4 ├── cloud.html ├── docs └── development.md ├── index.html ├── ios ├── .gitignore └── BoostNoteMobile │ ├── BoostNoteMobile.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── BoostNoteMobile.xcscheme │ ├── BoostNoteMobile │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── ItunesArtwork@2x.png │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift │ ├── BoostNoteMobileTests │ ├── BoostNoteMobileTests.swift │ └── Info.plist │ └── BoostNoteMobileUITests │ ├── BoostNoteMobileUITests.swift │ └── Info.plist ├── jest.json ├── macOs └── entitlements.mac.plist ├── mobile-static ├── favicon.ico └── images │ ├── initial │ ├── bookmarks1.png │ ├── bookmarks2.png │ ├── bookmarks3.png │ ├── coauthoring.gif │ ├── coauthoring.jpg │ ├── comments1.jpg │ ├── comments2.png │ ├── comments3.png │ ├── comments4.png │ ├── comments5.png │ ├── comments6.png │ ├── comments7.png │ ├── comments8.png │ ├── createTeam1.png │ ├── createTeam2.png │ ├── createTeam3.png │ ├── customizeWorkspace1.png │ ├── customizeWorkspace2.png │ ├── customizeWorkspace3.png │ ├── customizeWorkspace4.png │ ├── customizeWorkspace5.png │ ├── embedContents1.png │ ├── embedContents2.gif │ ├── embedContents3.gif │ ├── embedContents4.gif │ ├── embedContents5.gif │ ├── embedContents6.gif │ ├── embedDocuments1.png │ ├── embedDocuments2.png │ ├── embedDocuments3.png │ ├── idesearch.png │ ├── inviteGuest1.png │ ├── inviteGuest2.png │ ├── inviteGuest3.png │ ├── inviteGuest4.png │ ├── inviteGuest5.png │ ├── inviteGuest6.png │ ├── invitemembers.png │ ├── keymap.jpg │ ├── migration.png │ ├── privateWorkspace1.png │ ├── privateWorkspace2.png │ ├── publicAPI.png │ ├── publicLink1.png │ ├── publicLink2.png │ ├── publicLink3.png │ ├── publicLink4.png │ ├── shareoptions.png │ ├── smartFolder1.png │ ├── smartFolder2.png │ ├── smartFolder3.png │ ├── smartFolder4.png │ ├── smartFolder5.png │ ├── smartFolder6.png │ ├── smartfolderexample.png │ ├── step1-1.png │ ├── step1-2.png │ ├── step1-3.png │ ├── step1-4.png │ ├── step1-5.png │ ├── step1-6.png │ ├── step1-7.gif │ ├── step2-1.png │ ├── step2-2.png │ ├── step3-1.png │ ├── step3-2.png │ ├── step3-3.png │ ├── step4-1.png │ ├── step4-2.png │ ├── step4-3.png │ ├── step4-4.png │ ├── step4-5.png │ ├── step5-1.png │ ├── step5-2.png │ ├── step5-3.png │ ├── step6.gif │ ├── versionHistory1.png │ ├── versionHistory2.png │ └── zapierIntro.gif │ └── logo.png ├── mobile.html ├── package-lock.json ├── package.json ├── readme.md ├── resources └── logo.eps ├── scripts ├── build-electron-main.ts ├── dev-electron.ts └── meta.js ├── src ├── cloud │ ├── api │ │ ├── auth │ │ │ ├── email.ts │ │ │ ├── google.ts │ │ │ └── index.ts │ │ ├── automation │ │ │ ├── automation.ts │ │ │ └── workflow.ts │ │ ├── beta │ │ │ ├── registration.ts │ │ │ └── request.ts │ │ ├── comments │ │ │ ├── comment.ts │ │ │ └── thread.ts │ │ ├── connections │ │ │ └── index.ts │ │ ├── desktop │ │ │ └── login.ts │ │ ├── docs │ │ │ └── token.ts │ │ ├── editRequests │ │ │ └── index.ts │ │ ├── feedback │ │ │ └── index.ts │ │ ├── files │ │ │ └── index.ts │ │ ├── global.ts │ │ ├── integrations │ │ │ └── index.ts │ │ ├── mock │ │ │ ├── db │ │ │ │ ├── init.ts │ │ │ │ ├── mockEntities │ │ │ │ │ ├── docs.ts │ │ │ │ │ ├── folders.ts │ │ │ │ │ ├── permissions.ts │ │ │ │ │ ├── tags.ts │ │ │ │ │ ├── teams.ts │ │ │ │ │ ├── users.ts │ │ │ │ │ └── workspaces.ts │ │ │ │ ├── populate.ts │ │ │ │ └── utils.ts │ │ │ └── mockHandler.ts │ │ ├── notifications │ │ │ └── index.ts │ │ ├── pages │ │ │ ├── oauth.ts │ │ │ ├── settings │ │ │ │ └── index.ts │ │ │ ├── shared │ │ │ │ └── index.ts │ │ │ └── teams │ │ │ │ ├── bookmarks.ts │ │ │ │ ├── dashboards │ │ │ │ └── show.ts │ │ │ │ ├── delete.ts │ │ │ │ ├── deleted.ts │ │ │ │ ├── index.ts │ │ │ │ ├── invite.ts │ │ │ │ ├── requests.ts │ │ │ │ ├── shared.ts │ │ │ │ ├── tags.ts │ │ │ │ ├── timeline.ts │ │ │ │ └── workspaces.ts │ │ ├── rest │ │ │ └── doc.ts │ │ ├── revisions │ │ │ └── index.ts │ │ ├── search │ │ │ └── index.ts │ │ ├── share │ │ │ └── index.ts │ │ ├── status │ │ │ └── index.ts │ │ ├── teams │ │ │ ├── dashboards │ │ │ │ └── index.ts │ │ │ ├── docs │ │ │ │ ├── bookmarks.ts │ │ │ │ ├── exports.ts │ │ │ │ ├── import.ts │ │ │ │ ├── index.ts │ │ │ │ ├── revisions.ts │ │ │ │ ├── tags.ts │ │ │ │ └── templates.ts │ │ │ ├── externalEntities │ │ │ │ └── index.ts │ │ │ ├── files │ │ │ │ └── index.ts │ │ │ ├── folders │ │ │ │ ├── bookmarks.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── invites │ │ │ │ └── index.ts │ │ │ ├── open-invites │ │ │ │ └── index.ts │ │ │ ├── permissions │ │ │ │ ├── emails.ts │ │ │ │ └── index.ts │ │ │ ├── props │ │ │ │ └── index.ts │ │ │ ├── resources │ │ │ │ └── index.ts │ │ │ ├── smartViews │ │ │ │ └── index.ts │ │ │ ├── sources │ │ │ │ └── index.ts │ │ │ ├── subscription │ │ │ │ ├── index.ts │ │ │ │ ├── invoices.ts │ │ │ │ ├── trial.ts │ │ │ │ └── update.ts │ │ │ ├── tags │ │ │ │ └── index.ts │ │ │ ├── views │ │ │ │ └── index.ts │ │ │ └── workspaces │ │ │ │ └── index.ts │ │ ├── tokens │ │ │ └── index.ts │ │ ├── track │ │ │ └── index.ts │ │ ├── uploads │ │ │ └── index.ts │ │ └── users │ │ │ ├── appfeedback.ts │ │ │ ├── index.ts │ │ │ ├── onboarding.ts │ │ │ └── settings.ts │ ├── components │ │ ├── AnnouncementAlert.tsx │ │ ├── App.tsx │ │ ├── AppFeedbackForm │ │ │ └── index.tsx │ │ ├── Application.tsx │ │ ├── ApplicationContent.tsx │ │ ├── ApplicationPage.tsx │ │ ├── ApplicationPageLoader.tsx │ │ ├── ApplicationTopbar.tsx │ │ ├── ApplicationWithoutInfoLoader.tsx │ │ ├── Automations │ │ │ ├── AutomationBuilder.tsx │ │ │ ├── AutomationLogList.tsx │ │ │ ├── EventInfo.tsx │ │ │ ├── FilterBuilder.tsx │ │ │ ├── PipeBuilder.tsx │ │ │ ├── WorkflowBuilder.tsx │ │ │ └── actions │ │ │ │ ├── ActionConfigurationInput.tsx │ │ │ │ ├── CreateDocActionConfigurator.tsx │ │ │ │ ├── FolderSelect.tsx │ │ │ │ ├── PropertySelect.tsx │ │ │ │ ├── UpdateDocActionConfigurator.tsx │ │ │ │ └── index.ts │ │ ├── BottomBarButton.tsx │ │ ├── CloudGlobalSearch.tsx │ │ ├── CloudModal.tsx │ │ ├── CodeMirrorStyle.tsx │ │ ├── CommentEmoji.tsx │ │ ├── Comments │ │ │ ├── CommentInput.tsx │ │ │ ├── CommentList.tsx │ │ │ ├── CommentManager.tsx │ │ │ ├── CommentReactions.tsx │ │ │ ├── EmojiPickHandler.tsx │ │ │ ├── ThreadActionButton.tsx │ │ │ ├── ThreadItem.tsx │ │ │ └── ThreadList.tsx │ │ ├── ContentManager │ │ │ ├── Actions │ │ │ │ ├── DocOnlyContentManagerBulkActions.tsx │ │ │ │ ├── HeaderActionButton.tsx │ │ │ │ └── RowActionButton.tsx │ │ │ ├── ContentManagerCell.tsx │ │ │ ├── ContentManagerStatusFilter.tsx │ │ │ ├── ContentManagerToolbar.tsx │ │ │ ├── ContentManagerToolbarStatusPopup.tsx │ │ │ ├── Rows │ │ │ │ ├── ContentManagerDocRow.tsx │ │ │ │ ├── ContentManagerFolderRow.tsx │ │ │ │ ├── ContentManagerRow.tsx │ │ │ │ └── EmptyRow.tsx │ │ │ ├── SortingOption.tsx │ │ │ ├── index.tsx │ │ │ └── styled.ts │ │ ├── DashboardPage │ │ │ ├── AddSmartViewModal.tsx │ │ │ ├── DashboardContextMenu.tsx │ │ │ ├── DashboardSubscriptionBanner.tsx │ │ │ ├── DashboardView.tsx │ │ │ ├── SmartViewGridItem.tsx │ │ │ ├── UpdateSmartViewModal.tsx │ │ │ └── index.tsx │ │ ├── DocPage │ │ │ ├── BackLinksList.tsx │ │ │ ├── DocContextMenuActions.tsx │ │ │ ├── DocPageHeader.tsx │ │ │ ├── DocShare.tsx │ │ │ ├── DocTagsList │ │ │ │ ├── TagsAutoCompleteInput.tsx │ │ │ │ └── index.tsx │ │ │ ├── EditorLayout.tsx │ │ │ ├── NewDocContextMenu.tsx │ │ │ ├── SharedDocPage.tsx │ │ │ ├── index.tsx │ │ │ └── styles.ts │ │ ├── DocPreview │ │ │ ├── DocPreviewRealtime.tsx │ │ │ └── index.tsx │ │ ├── DocProperties.tsx │ │ ├── DocStatusIcon.tsx │ │ ├── DocTagsListItem.tsx │ │ ├── Editor │ │ │ ├── EditorAdmonitionTool.tsx │ │ │ ├── EditorAdmonitionToolDropdown.tsx │ │ │ ├── EditorHeaderTool.tsx │ │ │ ├── EditorHeaderToolDropdown.tsx │ │ │ ├── EditorIndentationStatus.tsx │ │ │ ├── EditorIntegrationToolButton.tsx │ │ │ ├── EditorKeyMapSelect.tsx │ │ │ ├── EditorSelectionStatus.tsx │ │ │ ├── EditorTemplateButton.tsx │ │ │ ├── EditorThemeSelect.tsx │ │ │ ├── EditorToolButton.tsx │ │ │ ├── EditorToolbar.tsx │ │ │ ├── EditorToolbarUpload.tsx │ │ │ ├── index.tsx │ │ │ ├── styled.ts │ │ │ └── types.ts │ │ ├── EditorsIcons.tsx │ │ ├── EmojiIcon.tsx │ │ ├── ErrorBlock.tsx │ │ ├── EventSource.tsx │ │ ├── FeedbackForm │ │ │ ├── ExpandingRow.tsx │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── FileListItem.tsx │ │ ├── FolderPage │ │ │ ├── NewFolderContextMenu.tsx │ │ │ └── index.tsx │ │ ├── FreeTrialPopup │ │ │ └── index.tsx │ │ ├── HelpLink.tsx │ │ ├── ImportFlow │ │ │ ├── index.tsx │ │ │ └── molecules │ │ │ │ ├── ImportFlowDestination.tsx │ │ │ │ └── ImportFlowSources.tsx │ │ ├── IntroducePlansPopup │ │ │ └── index.tsx │ │ ├── Link │ │ │ ├── AccountLink.tsx │ │ │ ├── CloudLink.tsx │ │ │ ├── DashboardLink.tsx │ │ │ ├── DocLink.tsx │ │ │ ├── FolderLink.tsx │ │ │ ├── RevisionLink.tsx │ │ │ ├── TagLink.tsx │ │ │ ├── TeamLink.tsx │ │ │ └── WorkspaceLink.tsx │ │ ├── MarkdownView │ │ │ ├── CustomizedMarkdownPreviewer.tsx │ │ │ ├── LinkableHeader.tsx │ │ │ ├── MarkdownCheckbox.tsx │ │ │ ├── SelectionTooltip.tsx │ │ │ ├── Shortcode │ │ │ │ ├── github │ │ │ │ │ ├── GithubIssue.tsx │ │ │ │ │ ├── GithubPr.tsx │ │ │ │ │ ├── styles.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── index.tsx │ │ │ ├── TableOfContents │ │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ └── styles.ts │ │ ├── Modal │ │ │ ├── InviteMembers │ │ │ │ ├── InviteMemberModalSection.tsx │ │ │ │ └── InviteMembersModal.tsx │ │ │ └── contents │ │ │ │ ├── DiscountModal.tsx │ │ │ │ ├── Doc │ │ │ │ └── RevisionsModal │ │ │ │ │ ├── RevisionModalDetail.tsx │ │ │ │ │ ├── RevisionModalNavigator.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── FeedbackModal.tsx │ │ │ │ ├── Forms │ │ │ │ └── MoveItemModal.tsx │ │ │ │ ├── LabelsManagementModal │ │ │ │ ├── LabelsManagementModalDetail.tsx │ │ │ │ ├── LabelsManagementModalNavigator.tsx │ │ │ │ └── index.tsx │ │ │ │ ├── SmartView │ │ │ │ ├── ConditionItem.tsx │ │ │ │ ├── ConditionValueControl.tsx │ │ │ │ ├── DateConditionValueTypeSelect.tsx │ │ │ │ ├── DocAssigneeSelect.tsx │ │ │ │ ├── DocDateSelect.tsx │ │ │ │ ├── DocLabelSelect.tsx │ │ │ │ ├── DocStatusSelect.tsx │ │ │ │ ├── FolderSelect.tsx │ │ │ │ ├── SmartViewConditionRows.tsx │ │ │ │ ├── SmartViewForm.tsx │ │ │ │ ├── StatusSelect.tsx │ │ │ │ ├── TimePeriodForm.tsx │ │ │ │ └── interfaces.ts │ │ │ │ ├── Subscription │ │ │ │ ├── UnlockDashboardModal.tsx │ │ │ │ ├── UnlockDocCreationModal.tsx │ │ │ │ └── UnlockPrivateWorkspaceModal.tsx │ │ │ │ ├── TemplatesModal │ │ │ │ └── index.tsx │ │ │ │ └── Workspace │ │ │ │ ├── WorkspaceAccess.tsx │ │ │ │ └── WorkspaceModalForm.tsx │ │ ├── Onboarding │ │ │ ├── BulkInvitesForm.tsx │ │ │ ├── CreateTeamForm.tsx │ │ │ ├── FolderPageInviteSection.tsx │ │ │ ├── OnboardingLayout.tsx │ │ │ └── UsageFormRow.tsx │ │ ├── OpenInviteSection.tsx │ │ ├── Page.tsx │ │ ├── PreferencesContextMenuWrapper.tsx │ │ ├── Props │ │ │ ├── DocPagePropsAddContext.tsx │ │ │ ├── Pickers │ │ │ │ ├── AssigneeSelect.tsx │ │ │ │ ├── CheckboxSelect.tsx │ │ │ │ ├── DatePropPicker.tsx │ │ │ │ ├── DocDependencySelect.tsx │ │ │ │ ├── DocLabelSelectionModal.tsx │ │ │ │ ├── NumberSelect.tsx │ │ │ │ ├── PropertyValueButton.tsx │ │ │ │ ├── StatusSelect.tsx │ │ │ │ ├── TextSelect.tsx │ │ │ │ ├── TimePeriodPicker.tsx │ │ │ │ └── UrlSelect.tsx │ │ │ ├── PropConfig.tsx │ │ │ ├── PropPicker.tsx │ │ │ └── PropRegisterModal │ │ │ │ ├── PropRegisterCreationForm.tsx │ │ │ │ ├── PropRegisterForm.tsx │ │ │ │ ├── PropRegisterSuggestionsList.tsx │ │ │ │ └── index.tsx │ │ ├── Router.tsx │ │ ├── SearchableOptionListPopup.tsx │ │ ├── ServiceConnect.tsx │ │ ├── SettingsTeamForm.tsx │ │ ├── SharePageTopBar │ │ │ └── index.tsx │ │ ├── SidebarToggleButton.tsx │ │ ├── SignInForm │ │ │ ├── EmailForm.tsx │ │ │ └── index.tsx │ │ ├── Subscription │ │ │ ├── PlanTables.tsx │ │ │ ├── SidebarSubscriptionCTA.tsx │ │ │ ├── SubscriptionCostSummary.tsx │ │ │ ├── SubscriptionManagement.tsx │ │ │ ├── SubscriptionPlanHeader.tsx │ │ │ └── SubscriptionPlanTables.tsx │ │ ├── SubscriptionForm │ │ │ ├── UpdateBillingEmailForm.tsx │ │ │ ├── UpdateBillingMethodForm.tsx │ │ │ ├── UpdateBillingPromo.tsx │ │ │ └── index.tsx │ │ ├── TeamIcon.tsx │ │ ├── TeamInvitesSection.tsx │ │ ├── ThreadStatusFilterControl.tsx │ │ ├── TitleComponent.tsx │ │ ├── TokenControl.tsx │ │ ├── Topbar │ │ │ ├── Controls │ │ │ │ └── ControlsContextMenu │ │ │ │ │ ├── ControlsContextMenuBackground.tsx │ │ │ │ │ ├── ControlsContextMenuItem.tsx │ │ │ │ │ ├── FolderContextMenu.tsx │ │ │ │ │ └── styled.ts │ │ │ ├── PresenceIcons.tsx │ │ │ └── SyncStatus.tsx │ │ ├── UpgradeButton.tsx │ │ ├── UpgradeIntroButton.tsx │ │ ├── UserIcon.tsx │ │ ├── ViewerDisclaimer.tsx │ │ ├── ViewerRestrictedWrapper.tsx │ │ ├── Views │ │ │ ├── Calendar │ │ │ │ ├── CalendarEventItem.tsx │ │ │ │ ├── CalendarEventItemContextMenu.tsx │ │ │ │ ├── CalendarNoDateContext.tsx │ │ │ │ ├── CalendarView.tsx │ │ │ │ ├── CalendarViewPropertiesContext.tsx │ │ │ │ └── CalendarWatchedPropContext.tsx │ │ │ ├── EditableDocItemContainer.tsx │ │ │ ├── FolderList.tsx │ │ │ ├── Kanban │ │ │ │ ├── Item.tsx │ │ │ │ ├── KanbanViewPropertiesContext.tsx │ │ │ │ ├── KanbanWatchedPropSetter.tsx │ │ │ │ ├── ListSettings.tsx │ │ │ │ └── index.tsx │ │ │ ├── List │ │ │ │ ├── ListDocProperties.tsx │ │ │ │ ├── ListViewHeader.tsx │ │ │ │ ├── ListViewItem.tsx │ │ │ │ ├── ListViewPropertiesContext.tsx │ │ │ │ └── index.tsx │ │ │ ├── Table │ │ │ │ ├── ColSettingsContext.tsx │ │ │ │ ├── TableAddPropertyContext.tsx │ │ │ │ ├── TableView.tsx │ │ │ │ ├── TableViewPropertiesContext.tsx │ │ │ │ └── TitleColumnSettingsContext.tsx │ │ │ ├── ViewFilters.tsx │ │ │ ├── ViewsSelector │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ │ ├── WorkspaceExplorer │ │ │ ├── ExplorerListItem.tsx │ │ │ ├── FolderExplorer.tsx │ │ │ ├── index.tsx │ │ │ └── styled.ts │ │ ├── WorkspacePage │ │ │ ├── WorkspaceContextMenu.tsx │ │ │ └── index.tsx │ │ ├── buttons │ │ │ ├── InviteCTAButton.tsx │ │ │ ├── NewDocButton.tsx │ │ │ └── login │ │ │ │ ├── GithubLoginButton.tsx │ │ │ │ └── GoogleLoginButton.tsx │ │ ├── error │ │ │ ├── ErrorPage.tsx │ │ │ └── ErrorSection.tsx │ │ ├── homepage │ │ │ ├── IntegrationServiceImage.tsx │ │ │ └── PageContainer.tsx │ │ ├── layouts │ │ │ └── CenteredContainer.tsx │ │ ├── molecules │ │ │ └── PageSearch │ │ │ │ └── InPageSearchPortal.tsx │ │ ├── settings │ │ │ ├── ApiTab.tsx │ │ │ ├── AttachmentsTab.tsx │ │ │ ├── BetaAutomationAndIntegrationTab.tsx │ │ │ ├── GithubIntegration.tsx │ │ │ ├── ImportTab.tsx │ │ │ ├── IntegrationManager.tsx │ │ │ ├── IntegrationsTab.tsx │ │ │ ├── MarkdownTabForm.tsx │ │ │ ├── MembersTab.tsx │ │ │ ├── PersonalInfoTab.tsx │ │ │ ├── PreferencesTab.tsx │ │ │ ├── SettingsComponent.tsx │ │ │ ├── SlackIntegration.tsx │ │ │ ├── SubscriptionTab.tsx │ │ │ ├── TeamInfoTab.tsx │ │ │ ├── TeamSubLimit.tsx │ │ │ ├── UpgradeTab.tsx │ │ │ ├── UserPreferencesForm.tsx │ │ │ └── styled.ts │ │ └── sources │ │ │ └── GithubSourceCallbackPage.tsx │ ├── index.tsx │ ├── interfaces │ │ ├── analytics │ │ │ ├── intercom.ts │ │ │ └── mixpanel.ts │ │ ├── api.ts │ │ ├── components │ │ │ └── ContentManager │ │ │ │ └── types.ts │ │ ├── db │ │ │ ├── accessToken.ts │ │ │ ├── accessTokenRequests.ts │ │ │ ├── apiTokens.ts │ │ │ ├── appEvents.ts │ │ │ ├── automations.ts │ │ │ ├── beta.ts │ │ │ ├── bookmarks.ts │ │ │ ├── commentReaction.ts │ │ │ ├── comments.ts │ │ │ ├── connections.ts │ │ │ ├── dashboard.ts │ │ │ ├── doc.ts │ │ │ ├── editRequest.ts │ │ │ ├── errorReport.ts │ │ │ ├── externalEntity.ts │ │ │ ├── folder.ts │ │ │ ├── folderPositions.ts │ │ │ ├── icon.ts │ │ │ ├── mention.ts │ │ │ ├── notifications.ts │ │ │ ├── openInvite.ts │ │ │ ├── props.ts │ │ │ ├── revision.ts │ │ │ ├── shareLink.ts │ │ │ ├── smartView.ts │ │ │ ├── source.ts │ │ │ ├── status.ts │ │ │ ├── storage.ts │ │ │ ├── subscription.ts │ │ │ ├── tag.ts │ │ │ ├── team.ts │ │ │ ├── teamInvite.ts │ │ │ ├── template.ts │ │ │ ├── user.ts │ │ │ ├── userAccessToken.ts │ │ │ ├── userAppFeedback.ts │ │ │ ├── userFeedback.ts │ │ │ ├── userOnboarding.ts │ │ │ ├── userSettings.ts │ │ │ ├── userTeamPermissions.ts │ │ │ ├── view.ts │ │ │ ├── workspace.ts │ │ │ └── workspacePositions.ts │ │ ├── events.ts │ │ ├── pageStore.ts │ │ ├── pages.ts │ │ ├── presence.ts │ │ └── resources.ts │ ├── lib │ │ ├── HashQueue │ │ │ ├── HashQueue.spec.ts │ │ │ └── index.ts │ │ ├── animations.ts │ │ ├── automations │ │ │ └── events │ │ │ │ └── index.ts │ │ ├── cache.ts │ │ ├── charts │ │ │ ├── charts.tsx │ │ │ ├── flowchart.tsx │ │ │ ├── index.ts │ │ │ ├── plantuml.ts │ │ │ └── remarkCharts.ts │ │ ├── client.ts │ │ ├── comments │ │ │ └── index.ts │ │ ├── consts.ts │ │ ├── date.ts │ │ ├── dnd.ts │ │ ├── docEmbedPlugin.ts │ │ ├── dom.ts │ │ ├── editor │ │ │ ├── CodeMirror.ts │ │ │ ├── components │ │ │ │ └── CodeMirrorEditor.tsx │ │ │ ├── hooks │ │ │ │ └── useRealtime.ts │ │ │ ├── plugins │ │ │ │ ├── fileHandler.ts │ │ │ │ └── pasteFormatPlugin.ts │ │ │ └── scrollSync.ts │ │ ├── export.ts │ │ ├── homepageUrls.ts │ │ ├── hooks │ │ │ ├── dashboards │ │ │ │ └── useDashboard.ts │ │ │ ├── editor │ │ │ │ └── docEditor.ts │ │ │ ├── index.ts │ │ │ ├── props │ │ │ │ └── index.ts │ │ │ ├── sidebar │ │ │ │ ├── useCloudDnd.ts │ │ │ │ ├── useCloudSidebarSpaces.tsx │ │ │ │ └── useCloudSidebarTree.tsx │ │ │ ├── useCloudApi.tsx │ │ │ ├── useCloudDocPreview.tsx │ │ │ ├── useCloudResourceModals.tsx │ │ │ ├── useCommentManagerState.ts │ │ │ ├── useI18n.tsx │ │ │ ├── useThreadMenuActions.tsx │ │ │ ├── useWorkspaceDelete.ts │ │ │ └── views │ │ │ │ ├── calendarView.ts │ │ │ │ ├── kanbanView.ts │ │ │ │ ├── listView.ts │ │ │ │ ├── tableView.ts │ │ │ │ └── viewHandler.ts │ │ ├── href.ts │ │ ├── i18n │ │ │ ├── enUS.ts │ │ │ ├── fr.ts │ │ │ ├── index.ts │ │ │ ├── ja.ts │ │ │ ├── types.ts │ │ │ └── zhCN.ts │ │ ├── intercom │ │ │ └── index.ts │ │ ├── keyboard.ts │ │ ├── localStorageKeys.ts │ │ ├── mappers │ │ │ ├── contentManager.ts │ │ │ ├── fuzzyNavigation.ts │ │ │ ├── topbarBreadcrumbs.ts │ │ │ └── topbarTree.ts │ │ ├── mouse.ts │ │ ├── ordering.ts │ │ ├── props.ts │ │ ├── realtime │ │ │ ├── client │ │ │ │ ├── VirtualConnection.ts │ │ │ │ ├── constructor.ts │ │ │ │ ├── index.ts │ │ │ │ └── multiplexConnection.ts │ │ │ ├── lib │ │ │ │ ├── functional.ts │ │ │ │ └── result.ts │ │ │ └── protocol │ │ │ │ ├── client.ts │ │ │ │ ├── server.ts │ │ │ │ ├── types.ts │ │ │ │ └── version.ts │ │ ├── rehypeCustomBlock.ts │ │ ├── rehypeGutters.ts │ │ ├── rehypeHighlight.ts │ │ ├── rehypePosition.ts │ │ ├── router.ts │ │ ├── selection │ │ │ ├── useSelection.ts │ │ │ └── useSelectionLocation.ts │ │ ├── shortcode │ │ │ └── index.ts │ │ ├── shortcuts.ts │ │ ├── sidebar.ts │ │ ├── smartViews.ts │ │ ├── stores │ │ │ ├── apiTokens │ │ │ │ ├── index.ts │ │ │ │ ├── store.ts │ │ │ │ └── withApiTokens.tsx │ │ │ ├── beta │ │ │ │ ├── index.ts │ │ │ │ ├── store.ts │ │ │ │ └── withBetaRegistration.tsx │ │ │ ├── comments │ │ │ │ ├── helpers.ts │ │ │ │ └── index.ts │ │ │ ├── electron.ts │ │ │ ├── externalEntities │ │ │ │ └── index.ts │ │ │ ├── globalData.ts │ │ │ ├── loaders │ │ │ │ ├── index.ts │ │ │ │ ├── store.ts │ │ │ │ └── withLoaderProps.tsx │ │ │ ├── localSnapshots.ts │ │ │ ├── nav │ │ │ │ ├── index.tsx │ │ │ │ ├── store.tsx │ │ │ │ └── types.ts │ │ │ ├── onboarding │ │ │ │ ├── index.ts │ │ │ │ ├── store.tsx │ │ │ │ └── types.ts │ │ │ ├── openInvites │ │ │ │ ├── index.ts │ │ │ │ ├── store.ts │ │ │ │ └── withOpenInvites.tsx │ │ │ ├── pageStore │ │ │ │ ├── index.tsx │ │ │ │ ├── store.tsx │ │ │ │ └── types.ts │ │ │ ├── preferences │ │ │ │ ├── index.ts │ │ │ │ ├── store.ts │ │ │ │ └── types.ts │ │ │ ├── realtimeConn.ts │ │ │ ├── search │ │ │ │ ├── index.tsx │ │ │ │ ├── store.ts │ │ │ │ └── types.ts │ │ │ ├── serviceConnections │ │ │ │ ├── index.ts │ │ │ │ ├── store.ts │ │ │ │ └── withServiceConnections.tsx │ │ │ ├── settings │ │ │ │ ├── index.tsx │ │ │ │ ├── store.ts │ │ │ │ └── types.ts │ │ │ ├── sidebarCollapse │ │ │ │ ├── index.tsx │ │ │ │ ├── store.tsx │ │ │ │ └── types.ts │ │ │ ├── status │ │ │ │ └── index.ts │ │ │ ├── teamPreferences │ │ │ │ ├── index.tsx │ │ │ │ ├── store.tsx │ │ │ │ └── types.ts │ │ │ └── teamStorage │ │ │ │ ├── index.tsx │ │ │ │ ├── store.tsx │ │ │ │ └── types.ts │ │ ├── stripe.ts │ │ ├── subscription.ts │ │ ├── upload.ts │ │ ├── utils │ │ │ ├── admin.ts │ │ │ ├── array.ts │ │ │ ├── bytes.ts │ │ │ ├── context.tsx │ │ │ ├── events.ts │ │ │ ├── iterator.ts │ │ │ ├── map.ts │ │ │ ├── object.ts │ │ │ ├── patterns.ts │ │ │ ├── platform.ts │ │ │ ├── secret.ts │ │ │ ├── sleep.ts │ │ │ ├── string.ts │ │ │ └── url.ts │ │ └── views │ │ │ ├── calendar.ts │ │ │ ├── index.ts │ │ │ ├── kanban.ts │ │ │ ├── list.ts │ │ │ └── table.ts │ └── pages │ │ ├── [teamId] │ │ ├── [resourceId] │ │ │ └── index.tsx │ │ ├── dashboard.tsx │ │ ├── delete.tsx │ │ ├── index.tsx │ │ ├── invite.tsx │ │ ├── labels │ │ │ └── [labelId] │ │ │ │ └── index.tsx │ │ ├── requests │ │ │ └── deny.tsx │ │ ├── shared.tsx │ │ └── workspaces │ │ │ └── [workspaceId].tsx │ │ ├── _error.tsx │ │ ├── account │ │ └── delete.tsx │ │ ├── automations │ │ ├── [automationId].tsx │ │ ├── create.tsx │ │ └── index.tsx │ │ ├── cooperate.tsx │ │ ├── home │ │ ├── BoostNoteFeatureIntro.tsx │ │ ├── HomeForm.tsx │ │ ├── HomePageSignInForm.tsx │ │ └── index.tsx │ │ ├── oauth │ │ └── [service] │ │ │ └── callback.tsx │ │ ├── oauth2 │ │ └── authorize.tsx │ │ ├── settings │ │ └── index.tsx │ │ ├── shared │ │ └── [link].tsx │ │ └── workflows │ │ ├── [workflowId].tsx │ │ ├── create.tsx │ │ └── index.tsx ├── components │ ├── App.tsx │ ├── BoostHubWebview.tsx │ └── atoms │ │ ├── Alert.tsx │ │ ├── ProgressBar.tsx │ │ └── form.tsx ├── design │ ├── components │ │ ├── atoms │ │ │ ├── AspectRation.tsx │ │ │ ├── Badge.tsx │ │ │ ├── Banner.tsx │ │ │ ├── BorderSeparator.tsx │ │ │ ├── Button.tsx │ │ │ ├── ButtonGroup.tsx │ │ │ ├── Card.tsx │ │ │ ├── ColoredBlock.tsx │ │ │ ├── DoublePane.tsx │ │ │ ├── EditableInput.tsx │ │ │ ├── EllipsisText.tsx │ │ │ ├── Flexbox.tsx │ │ │ ├── FoldingWrapper.tsx │ │ │ ├── GlobalStyle.tsx │ │ │ ├── Icon.tsx │ │ │ ├── Image.tsx │ │ │ ├── Label.tsx │ │ │ ├── LeftRightList.tsx │ │ │ ├── Link.tsx │ │ │ ├── PageHelmet.tsx │ │ │ ├── Pastille.tsx │ │ │ ├── Portal.tsx │ │ │ ├── PromiseWrapper.tsx │ │ │ ├── RoundedImage.tsx │ │ │ ├── Scroller.tsx │ │ │ ├── Spinner.tsx │ │ │ ├── Switch.tsx │ │ │ ├── UpDownList.tsx │ │ │ ├── WidthEnlarger.tsx │ │ │ ├── WithDelayedTooltip.tsx │ │ │ ├── WithPastille.tsx │ │ │ ├── WithTooltip.tsx │ │ │ ├── loaders │ │ │ │ ├── LoaderDocEditor.tsx │ │ │ │ ├── LoaderFolderPage.tsx │ │ │ │ ├── LoaderNavItem.tsx │ │ │ │ ├── LoaderSmartView.tsx │ │ │ │ ├── LoaderTeamPicker.tsx │ │ │ │ ├── LoaderTopbar.tsx │ │ │ │ └── LoaderTopbarBreadcrumb.tsx │ │ │ └── markdown │ │ │ │ └── CodeFence.tsx │ │ ├── molecules │ │ │ ├── ApplicationLayout.tsx │ │ │ ├── BulkActionProgress.tsx │ │ │ ├── CloseButtonWrapper.tsx │ │ │ ├── ContextMenu.tsx │ │ │ ├── EmojiPicker.tsx │ │ │ ├── FlattenedBreadcrumbs.tsx │ │ │ ├── Form │ │ │ │ ├── atoms │ │ │ │ │ ├── FormCheckbox.tsx │ │ │ │ │ ├── FormColorSelect.tsx │ │ │ │ │ ├── FormCopyInput.tsx │ │ │ │ │ ├── FormDatePicker.tsx │ │ │ │ │ ├── FormEmoji.tsx │ │ │ │ │ ├── FormImage.tsx │ │ │ │ │ ├── FormInput.tsx │ │ │ │ │ ├── FormRadio.tsx │ │ │ │ │ ├── FormSelect.tsx │ │ │ │ │ ├── FormStripeInput.tsx │ │ │ │ │ ├── FormTextArea.tsx │ │ │ │ │ └── FormToggableInput.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── templates │ │ │ │ │ ├── FormRow.tsx │ │ │ │ │ └── FormRowItem.tsx │ │ │ ├── Image │ │ │ │ ├── ExpandableImage.tsx │ │ │ │ └── ImagePreview.tsx │ │ │ ├── LabelManager.tsx │ │ │ ├── Navigation │ │ │ │ └── NavigationItem.tsx │ │ │ ├── NotificationList.tsx │ │ │ ├── SearchableOptionList.tsx │ │ │ └── UserIconList.tsx │ │ ├── organisms │ │ │ ├── Calendar │ │ │ │ └── index.tsx │ │ │ ├── ContentManager │ │ │ │ ├── atoms │ │ │ │ │ └── ContentManagerRow.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── molecules │ │ │ │ │ └── ContentManagerSort.tsx │ │ │ ├── Dialog │ │ │ │ ├── Dialog.tsx │ │ │ │ ├── atoms │ │ │ │ │ └── DialogIcon.tsx │ │ │ │ └── molecules │ │ │ │ │ └── MessageBoxDialogBody.tsx │ │ │ ├── EmojiInputForm.tsx │ │ │ ├── FuzzyNavigation │ │ │ │ ├── index.tsx │ │ │ │ └── molecules │ │ │ │ │ └── FuzzyNavigationItem.tsx │ │ │ ├── GridLayout │ │ │ │ └── index.tsx │ │ │ ├── InfoBlock │ │ │ │ └── index.tsx │ │ │ ├── InputForm.tsx │ │ │ ├── Kanban │ │ │ │ ├── Container.tsx │ │ │ │ ├── Sortable.tsx │ │ │ │ ├── SortableContainer.tsx │ │ │ │ ├── hook.ts │ │ │ │ └── index.tsx │ │ │ ├── MetadataContainer │ │ │ │ ├── atoms │ │ │ │ │ └── MetadataContainerBreak.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── molecules │ │ │ │ │ └── MetadataContainerRow.tsx │ │ │ ├── Modal │ │ │ │ ├── atoms │ │ │ │ │ └── ModalLayout.tsx │ │ │ │ └── index.tsx │ │ │ ├── SearchLayout │ │ │ │ ├── atoms │ │ │ │ │ └── SearchItem.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── molecules │ │ │ │ │ └── SearchCategory.tsx │ │ │ ├── Settings │ │ │ │ ├── atoms │ │ │ │ │ ├── SettingNavItem.tsx │ │ │ │ │ └── SettingTabContent.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── molecules │ │ │ │ │ ├── SettingSidenav.tsx │ │ │ │ │ └── SettingSidenavHeader.tsx │ │ │ ├── ShallowTimeline.tsx │ │ │ ├── Sidebar │ │ │ │ ├── atoms │ │ │ │ │ ├── SidebarButton.tsx │ │ │ │ │ ├── SidebarContextList.tsx │ │ │ │ │ ├── SidebarHeader.tsx │ │ │ │ │ ├── SidebarPopOver.tsx │ │ │ │ │ ├── SidebarTreeForm.tsx │ │ │ │ │ └── SidebarTreeItem.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── molecules │ │ │ │ │ ├── SidebarButtonList.tsx │ │ │ │ │ ├── SidebarLink.tsx │ │ │ │ │ ├── SidebarSpaces.tsx │ │ │ │ │ └── SidebarTree.tsx │ │ │ ├── Table │ │ │ │ ├── Table.tsx │ │ │ │ ├── atoms │ │ │ │ │ ├── TableBorderLine.tsx │ │ │ │ │ ├── TableCell.tsx │ │ │ │ │ ├── TableCol.tsx │ │ │ │ │ └── TableSlider.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── molecules │ │ │ │ │ └── TableRow.tsx │ │ │ │ └── tableInterfaces.ts │ │ │ ├── Toast.tsx │ │ │ ├── Toolbar │ │ │ │ └── index.tsx │ │ │ └── Topbar │ │ │ │ ├── atoms │ │ │ │ ├── TopbarActionItem.tsx │ │ │ │ └── TopbarTreeItem.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── molecules │ │ │ │ ├── TopbarBreadcrumb.tsx │ │ │ │ └── TopbarNavigationContext.tsx │ │ └── templates │ │ │ ├── ContentLayout.tsx │ │ │ └── ErrorLayout.tsx │ └── lib │ │ ├── codemirror │ │ ├── rehypeCodeMirror.ts │ │ └── util.ts │ │ ├── date.ts │ │ ├── dnd.ts │ │ ├── dom.ts │ │ ├── hooks │ │ ├── useApi.ts │ │ ├── useBulkApi.ts │ │ ├── useCancellablePromises.ts │ │ ├── useNotificationState.ts │ │ └── useSuggestions.ts │ │ ├── keyboard.ts │ │ ├── mappers │ │ ├── topbarControls.ts │ │ ├── types.ts │ │ └── users.ts │ │ ├── platform.ts │ │ ├── shortcuts.ts │ │ ├── sidebar.ts │ │ ├── stores │ │ ├── contextMenu │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── dialog │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── emoji │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── integrations │ │ │ └── index.ts │ │ ├── modal │ │ │ ├── index.tsx │ │ │ ├── store.ts │ │ │ └── types.ts │ │ ├── notifications │ │ │ └── index.ts │ │ ├── toast │ │ │ └── index.ts │ │ └── window │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── string.ts │ │ ├── styled │ │ ├── common.ts │ │ ├── dark.ts │ │ ├── dracula.ts │ │ ├── index.ts │ │ ├── light.ts │ │ ├── monokai.ts │ │ ├── sepia.ts │ │ ├── solarizedDark.ts │ │ ├── styleFunctions.ts │ │ └── types.ts │ │ ├── types.ts │ │ └── utils │ │ ├── array.ts │ │ ├── comments.ts │ │ ├── context.tsx │ │ └── tree.ts ├── electron │ ├── consts.ts │ ├── index.ts │ ├── ipc.ts │ ├── menu.ts │ ├── updater.ts │ └── windows.ts ├── index.tsx ├── lib │ ├── boosthub.tsx │ ├── context.tsx │ ├── electronOnly.ts │ ├── events.ts │ ├── hooks.ts │ ├── i18n.ts │ ├── platform.ts │ ├── predicates.spec.ts │ ├── predicates.ts │ ├── preview.ts │ ├── routing │ │ └── pagePropCache.ts │ ├── string.ts │ ├── time.ts │ └── url.ts ├── locales │ └── enUS.ts ├── mobile │ ├── components │ │ ├── App.tsx │ │ ├── MobileGlobalStyle.tsx │ │ ├── Router.tsx │ │ ├── atoms │ │ │ ├── MobileFormControl.tsx │ │ │ ├── NavigationBarBackButton.tsx │ │ │ ├── NavigationBarButton.tsx │ │ │ ├── NavigationBarContainer.tsx │ │ │ ├── NavigationBarIconButton.tsx │ │ │ ├── TableHeaderItem.tsx │ │ │ ├── TableItem.tsx │ │ │ └── UpgradeIntroModalButton.tsx │ │ ├── layouts │ │ │ └── AppLayout.tsx │ │ ├── molecules │ │ │ ├── ContentManagerDocRow.tsx │ │ │ ├── ContentManagerFolderRow.tsx │ │ │ ├── ContentManagerRow.tsx │ │ │ ├── ContentManagerRowLinkContent.tsx │ │ │ ├── MobileContentManagerBulkActions.tsx │ │ │ └── MobileContextMenu.tsx │ │ ├── organisms │ │ │ ├── ContentManager.tsx │ │ │ ├── DocOnlyContentManager.tsx │ │ │ ├── NativeMobileAuthForm.tsx │ │ │ ├── Navigator │ │ │ │ ├── Navigator.tsx │ │ │ │ ├── NavigatorCategory.tsx │ │ │ │ ├── NavigatorControlItem.tsx │ │ │ │ ├── NavigatorItem.tsx │ │ │ │ ├── NavigatorNestedTreeRow.tsx │ │ │ │ ├── NavigatorSpaceSelector.tsx │ │ │ │ ├── NavigatorTree.tsx │ │ │ │ ├── SpaceMenuItemLabel.tsx │ │ │ │ └── index.tsx │ │ │ └── modals │ │ │ │ ├── AccountSettingsTab.tsx │ │ │ │ ├── DocCreateModal.tsx │ │ │ │ ├── DocInfoModal.tsx │ │ │ │ ├── MobileDocRevisionsModal.tsx │ │ │ │ ├── MobileResourceModal.tsx │ │ │ │ ├── MobileResourceMoveModal.tsx │ │ │ │ ├── MobileSearchModal.tsx │ │ │ │ ├── MobileWorkspaceModal.tsx │ │ │ │ ├── Modal.tsx │ │ │ │ ├── SettingsModal.tsx │ │ │ │ ├── SpaceBillingsTab.tsx │ │ │ │ ├── SpaceMembersTab.tsx │ │ │ │ ├── SpaceSettingsTab.tsx │ │ │ │ ├── SpaceUpgradeTab.tsx │ │ │ │ ├── UpgradeIntroModal.tsx │ │ │ │ ├── WorkspaceCreateModal.tsx │ │ │ │ ├── atoms │ │ │ │ ├── MobileSearchCategory.tsx │ │ │ │ ├── MobileSearchHeader.tsx │ │ │ │ ├── MobileSearchItem.tsx │ │ │ │ ├── ModalContainer.tsx │ │ │ │ └── ModalFormWrapper.tsx │ │ │ │ ├── organisms │ │ │ │ ├── DocContextMenu │ │ │ │ │ ├── DocAssigneeSelect.tsx │ │ │ │ │ ├── DocPropertyValueButton.tsx │ │ │ │ │ └── DocStatusSelect.tsx │ │ │ │ ├── DocInfoModalShareSection.tsx │ │ │ │ ├── DocTagsList │ │ │ │ │ ├── DocTagsListItem.tsx │ │ │ │ │ ├── TagsAutoCompleteInput.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── styled.ts │ │ │ │ ├── MobileSearchView.tsx │ │ │ │ ├── SettingsTeamForm.tsx │ │ │ │ └── SmartViewForm.tsx │ │ │ │ └── types.ts │ │ └── pages │ │ │ ├── CooperatePage.tsx │ │ │ ├── CreateTeamPage.tsx │ │ │ ├── DeleteAccountPage.tsx │ │ │ ├── DocEditPage.tsx │ │ │ ├── DocPage.tsx │ │ │ ├── DocStatusShowPage.tsx │ │ │ ├── DocViewPage.tsx │ │ │ ├── FolderPage.tsx │ │ │ ├── OpenInvitePage.tsx │ │ │ ├── ResourcesPage.tsx │ │ │ ├── RootPage.tsx │ │ │ ├── SettingsPage.tsx │ │ │ ├── SharedDocsListPage.tsx │ │ │ ├── SmartFolderPage.tsx │ │ │ ├── TagsShowPage.tsx │ │ │ ├── TeamDeletePage.tsx │ │ │ ├── TeamIndex.tsx │ │ │ └── WorkspacePage.tsx │ ├── index.tsx │ └── lib │ │ ├── appStatus.ts │ │ ├── href.ts │ │ ├── nativeMobile.ts │ │ ├── preferences.ts │ │ ├── sidebar │ │ ├── types.ts │ │ └── useNavigatorTree.tsx │ │ ├── signOut.ts │ │ └── useMobileResourceModals.tsx └── stories │ ├── Button.stories.tsx │ ├── Index.mdx │ ├── Table.stories.tsx │ └── utils │ └── themes.tsx ├── static ├── Desktop.svg ├── Mobile.svg ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── boosthub-preload.js ├── boosthub.png ├── boostnote-mac-icon.png ├── boostnote-mac-icon.svg ├── browserconfig.xml ├── cloud-workspace.svg ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── icon.icns ├── icon.ico ├── img_ui.png ├── local-workspace.svg ├── logo.png ├── logo.svg ├── logo_index.svg ├── logo_symbol.svg ├── logo_with_text_teal.svg ├── main-preload.js ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png ├── safari-pinned-tab.svg └── site.webmanifest ├── test └── setup.js ├── tsconfig-webpack.json ├── tsconfig.json ├── typings ├── calendly.d.ts ├── chartjs.d.ts ├── codemirror.d.ts ├── coffeescript.d.ts ├── event-source-polyfill.d.ts ├── flowchart.d.ts ├── markdowns.d.ts ├── mermaid.d.ts ├── styled-components.d.ts ├── unified.d.ts └── yjs.d.ts ├── vercel.json ├── webpack.cloud.config.ts ├── webpack.config.ts └── webpack.mobile.config.ts /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { "targets": "last 2 Chrome versions", "loose": true } 6 | ], 7 | "@babel/preset-typescript", 8 | "@babel/preset-react" 9 | ], 10 | "plugins": [ 11 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 12 | ["@babel/plugin-proposal-private-methods", { "loose": true }], 13 | ["@babel/plugin-proposal-private-property-in-object", { "loose": true }] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.env.default: -------------------------------------------------------------------------------- 1 | NODE_ENV=development 2 | 3 | INTERCOM_APP_ID= 4 | GA_TRACKING_ID= 5 | BOOST_HUB_BASE_URL= 6 | SSE_URL= 7 | REALTIME_URL= 8 | GITHUB_OAUTH_ID= 9 | GOOGLE_CLIENT_ID= 10 | STRIPE_PUBLISHABLE_KEY= 11 | COUPONS_NEW_USER_PRO= 12 | COUPONS_NEW_USER_STANDARD= 13 | COUPONS_NEW_SPACE= 14 | MOBILE_BASE_URL= 15 | BOOST_PDF_EXPORT_BASE_URL= 16 | 17 | # Deployment 18 | 19 | GH_TOKEN= 20 | APPLE_ID= 21 | APPLE_ID_PASSWORD= 22 | 23 | CLOUD_S3_BUCKET= 24 | MOBILE_S3_BUCKET= 25 | 26 | # Optional 27 | 28 | # MOCK_BACKEND=true 29 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /scripts -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [12.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - run: npm ci 29 | - run: npm test 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | .DS_Store 3 | .env 4 | .env.* 5 | !.env.default 6 | Desktop.ini 7 | Thumbs.db 8 | *.log 9 | .idea/ 10 | compiled/* 11 | dist/* 12 | .cache 13 | secrets 14 | compiled-mobile 15 | compiled-cloud 16 | electron/* 17 | !electron/.gitkeep 18 | report*.json 19 | 20 | .now 21 | .vercel 22 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/.prettierignore -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": false, 4 | "jsxSingleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: [ 3 | '../src/stories/**/*.stories.mdx', 4 | '../src/stories/**/*.stories.@(js|jsx|ts|tsx)', 5 | ], 6 | addons: [ 7 | '@storybook/addon-links', 8 | '@storybook/addon-essentials', 9 | '@storybook/addon-postcss', 10 | ], 11 | typescript: { 12 | check: false, 13 | checkOptions: {}, 14 | reactDocgen: 'react-docgen-typescript', 15 | reactDocgenTypescriptOptions: { 16 | shouldExtractLiteralValuesFromEnum: true, 17 | propFilter: (prop) => 18 | prop.parent ? !/node_modules/.test(prop.parent.fileName) : true, 19 | }, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | export const parameters = { 2 | actions: { argTypesRegex: "^on[A-Z].*" }, 3 | controls: { 4 | matchers: { 5 | color: /(background|color)$/i, 6 | date: /Date$/, 7 | }, 8 | }, 9 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Boost Note 2 | Copyright (C) 2016 - 2020 BoostIO 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | -------------------------------------------------------------------------------- /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 | local.properties 16 | /app/release 17 | -------------------------------------------------------------------------------- /android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /android/app/src/androidTest/java/com/boostio/boostnote/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.boostio.boostnote 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.boostio.boostnote", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 17 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Boost Note 3 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /android/app/src/test/java/com/boostio/boostnote/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.boostio.boostnote 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | ext.kotlin_version = "1.5.20" 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath "com.android.tools.build:gradle:4.2.2" 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | 12 | // NOTE: Do not place your application dependencies here; they belong 13 | // in the individual module build.gradle files 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | jcenter() // Warning: this repository is going to shut down soon 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jul 12 06:54:57 JST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "Boost Note" 2 | include ':app' 3 | -------------------------------------------------------------------------------- /cloud-static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/favicon.ico -------------------------------------------------------------------------------- /cloud-static/images/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/apple-icon-180x180.png -------------------------------------------------------------------------------- /cloud-static/images/doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/doc.png -------------------------------------------------------------------------------- /cloud-static/images/img_centralize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_centralize.png -------------------------------------------------------------------------------- /cloud-static/images/img_coauthoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_coauthoring.png -------------------------------------------------------------------------------- /cloud-static/images/img_coauthoring_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_coauthoring_2.png -------------------------------------------------------------------------------- /cloud-static/images/img_customblock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_customblock.png -------------------------------------------------------------------------------- /cloud-static/images/img_devtool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_devtool.png -------------------------------------------------------------------------------- /cloud-static/images/img_diagrams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_diagrams.png -------------------------------------------------------------------------------- /cloud-static/images/img_embed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_embed.png -------------------------------------------------------------------------------- /cloud-static/images/img_embedding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_embedding.png -------------------------------------------------------------------------------- /cloud-static/images/img_features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_features.png -------------------------------------------------------------------------------- /cloud-static/images/img_folders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_folders.png -------------------------------------------------------------------------------- /cloud-static/images/img_formula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_formula.png -------------------------------------------------------------------------------- /cloud-static/images/img_hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_hero.png -------------------------------------------------------------------------------- /cloud-static/images/img_import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_import.png -------------------------------------------------------------------------------- /cloud-static/images/img_integrations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_integrations.png -------------------------------------------------------------------------------- /cloud-static/images/img_keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_keyboard.png -------------------------------------------------------------------------------- /cloud-static/images/img_markdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_markdown.png -------------------------------------------------------------------------------- /cloud-static/images/img_public-private-sharing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_public-private-sharing.jpg -------------------------------------------------------------------------------- /cloud-static/images/img_publicAPI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_publicAPI.png -------------------------------------------------------------------------------- /cloud-static/images/img_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_share.png -------------------------------------------------------------------------------- /cloud-static/images/img_teams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_teams.png -------------------------------------------------------------------------------- /cloud-static/images/img_timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_timeline.png -------------------------------------------------------------------------------- /cloud-static/images/img_unlimited-cloud-doc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_unlimited-cloud-doc.jpg -------------------------------------------------------------------------------- /cloud-static/images/img_version-history.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_version-history.jpg -------------------------------------------------------------------------------- /cloud-static/images/img_workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/img_workflow.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step1-1.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step1-2.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step1-3.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step1-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step1-4.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step1-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step1-5.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step1-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step1-6.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step1-7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step1-7.gif -------------------------------------------------------------------------------- /cloud-static/images/initial/step2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step2-1.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step2-2.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step3-1.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step3-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step3-2.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step3-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step3-3.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step4-1.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step4-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step4-2.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step4-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step4-3.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step4-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step4-4.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step4-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step4-5.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step5-1.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step5-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step5-2.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step5-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step5-3.png -------------------------------------------------------------------------------- /cloud-static/images/initial/step6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/initial/step6.gif -------------------------------------------------------------------------------- /cloud-static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/logo.png -------------------------------------------------------------------------------- /cloud-static/images/ogp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/ogp.jpg -------------------------------------------------------------------------------- /cloud-static/images/private_folders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/private_folders.png -------------------------------------------------------------------------------- /cloud-static/images/realtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/realtime.png -------------------------------------------------------------------------------- /cloud-static/images/support_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/support_profile.jpg -------------------------------------------------------------------------------- /cloud-static/images/unlimited_dashboards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/unlimited_dashboards.png -------------------------------------------------------------------------------- /cloud-static/images/unlimited_documents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/images/unlimited_documents.png -------------------------------------------------------------------------------- /cloud-static/logos/airtable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/airtable.png -------------------------------------------------------------------------------- /cloud-static/logos/asana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/asana.png -------------------------------------------------------------------------------- /cloud-static/logos/aws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/aws.png -------------------------------------------------------------------------------- /cloud-static/logos/aws_lambda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/aws_lambda.png -------------------------------------------------------------------------------- /cloud-static/logos/clickup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/clickup.png -------------------------------------------------------------------------------- /cloud-static/logos/dropbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/dropbox.png -------------------------------------------------------------------------------- /cloud-static/logos/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/github.png -------------------------------------------------------------------------------- /cloud-static/logos/gmail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/gmail.png -------------------------------------------------------------------------------- /cloud-static/logos/google_calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/google_calendar.png -------------------------------------------------------------------------------- /cloud-static/logos/google_drive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/google_drive.png -------------------------------------------------------------------------------- /cloud-static/logos/google_spreadsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/google_spreadsheet.png -------------------------------------------------------------------------------- /cloud-static/logos/intercom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/intercom.png -------------------------------------------------------------------------------- /cloud-static/logos/jira.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/jira.png -------------------------------------------------------------------------------- /cloud-static/logos/mailchimp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/mailchimp.png -------------------------------------------------------------------------------- /cloud-static/logos/miro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/miro.png -------------------------------------------------------------------------------- /cloud-static/logos/office_365.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/office_365.png -------------------------------------------------------------------------------- /cloud-static/logos/slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/slack.png -------------------------------------------------------------------------------- /cloud-static/logos/stripe.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/stripe.jpeg -------------------------------------------------------------------------------- /cloud-static/logos/trello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/trello.png -------------------------------------------------------------------------------- /cloud-static/logos/zapier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/logos/zapier.png -------------------------------------------------------------------------------- /cloud-static/videos/pro-intro.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/cloud-static/videos/pro-intro.mp4 -------------------------------------------------------------------------------- /cloud.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Boost Note 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobileTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ios/BoostNoteMobile/BoostNoteMobileUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.tsx?$": "ts-jest" 4 | }, 5 | "setupFiles": ["/test/setup.js"] 6 | } 7 | -------------------------------------------------------------------------------- /macOs/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-jit 6 | 7 | com.apple.security.cs.allow-unsigned-executable-memory 8 | 9 | com.apple.security.cs.allow-dyld-environment-variables 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /mobile-static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/favicon.ico -------------------------------------------------------------------------------- /mobile-static/images/initial/bookmarks1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/bookmarks1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/bookmarks2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/bookmarks2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/bookmarks3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/bookmarks3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/coauthoring.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/coauthoring.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/coauthoring.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/coauthoring.jpg -------------------------------------------------------------------------------- /mobile-static/images/initial/comments1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments1.jpg -------------------------------------------------------------------------------- /mobile-static/images/initial/comments2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/comments3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/comments4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments4.png -------------------------------------------------------------------------------- /mobile-static/images/initial/comments5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments5.png -------------------------------------------------------------------------------- /mobile-static/images/initial/comments6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments6.png -------------------------------------------------------------------------------- /mobile-static/images/initial/comments7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments7.png -------------------------------------------------------------------------------- /mobile-static/images/initial/comments8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/comments8.png -------------------------------------------------------------------------------- /mobile-static/images/initial/createTeam1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/createTeam1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/createTeam2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/createTeam2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/createTeam3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/createTeam3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/customizeWorkspace1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/customizeWorkspace1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/customizeWorkspace2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/customizeWorkspace2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/customizeWorkspace3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/customizeWorkspace3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/customizeWorkspace4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/customizeWorkspace4.png -------------------------------------------------------------------------------- /mobile-static/images/initial/customizeWorkspace5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/customizeWorkspace5.png -------------------------------------------------------------------------------- /mobile-static/images/initial/embedContents1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedContents1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/embedContents2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedContents2.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/embedContents3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedContents3.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/embedContents4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedContents4.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/embedContents5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedContents5.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/embedContents6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedContents6.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/embedDocuments1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedDocuments1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/embedDocuments2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedDocuments2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/embedDocuments3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/embedDocuments3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/idesearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/idesearch.png -------------------------------------------------------------------------------- /mobile-static/images/initial/inviteGuest1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/inviteGuest1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/inviteGuest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/inviteGuest2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/inviteGuest3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/inviteGuest3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/inviteGuest4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/inviteGuest4.png -------------------------------------------------------------------------------- /mobile-static/images/initial/inviteGuest5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/inviteGuest5.png -------------------------------------------------------------------------------- /mobile-static/images/initial/inviteGuest6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/inviteGuest6.png -------------------------------------------------------------------------------- /mobile-static/images/initial/invitemembers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/invitemembers.png -------------------------------------------------------------------------------- /mobile-static/images/initial/keymap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/keymap.jpg -------------------------------------------------------------------------------- /mobile-static/images/initial/migration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/migration.png -------------------------------------------------------------------------------- /mobile-static/images/initial/privateWorkspace1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/privateWorkspace1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/privateWorkspace2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/privateWorkspace2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/publicAPI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/publicAPI.png -------------------------------------------------------------------------------- /mobile-static/images/initial/publicLink1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/publicLink1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/publicLink2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/publicLink2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/publicLink3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/publicLink3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/publicLink4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/publicLink4.png -------------------------------------------------------------------------------- /mobile-static/images/initial/shareoptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/shareoptions.png -------------------------------------------------------------------------------- /mobile-static/images/initial/smartFolder1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/smartFolder1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/smartFolder2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/smartFolder2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/smartFolder3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/smartFolder3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/smartFolder4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/smartFolder4.png -------------------------------------------------------------------------------- /mobile-static/images/initial/smartFolder5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/smartFolder5.png -------------------------------------------------------------------------------- /mobile-static/images/initial/smartFolder6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/smartFolder6.png -------------------------------------------------------------------------------- /mobile-static/images/initial/smartfolderexample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/smartfolderexample.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step1-1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step1-2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step1-3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step1-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step1-4.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step1-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step1-5.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step1-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step1-6.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step1-7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step1-7.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/step2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step2-1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step2-2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step3-1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step3-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step3-2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step3-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step3-3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step4-1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step4-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step4-2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step4-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step4-3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step4-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step4-4.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step4-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step4-5.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step5-1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step5-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step5-2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step5-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step5-3.png -------------------------------------------------------------------------------- /mobile-static/images/initial/step6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/step6.gif -------------------------------------------------------------------------------- /mobile-static/images/initial/versionHistory1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/versionHistory1.png -------------------------------------------------------------------------------- /mobile-static/images/initial/versionHistory2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/versionHistory2.png -------------------------------------------------------------------------------- /mobile-static/images/initial/zapierIntro.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/initial/zapierIntro.gif -------------------------------------------------------------------------------- /mobile-static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/mobile-static/images/logo.png -------------------------------------------------------------------------------- /mobile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Boost Note 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /scripts/meta.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const { pick } = require('ramda') 4 | 5 | const packageJson = require('../package.json') 6 | 7 | const filteredJson = { 8 | ...pick(['name', 'productName', 'version', 'author'], packageJson), 9 | dependencies: { 10 | 'electron-updater': '^4.2.0', 11 | 'electron-log': '^4.0.0', 12 | 'read-chunk': '^3.2.0', 13 | 'file-type': '^14.6.2', 14 | 'is-svg': '^4.3.1', 15 | got: '^11.8.1', 16 | }, 17 | } 18 | 19 | fs.writeFileSync( 20 | path.join(__dirname, '../electron/package.json'), 21 | JSON.stringify(filteredJson, null, 2) + '\n' 22 | ) 23 | -------------------------------------------------------------------------------- /src/cloud/api/auth/email.ts: -------------------------------------------------------------------------------- 1 | import { AddedOAuthParams } from './index' 2 | import { callApi } from '../../lib/client' 3 | 4 | export type CreateLoginEmailRequestRequestBody = { 5 | email: string 6 | } & AddedOAuthParams 7 | 8 | // eslint-disable-next-line @typescript-eslint/no-empty-interface 9 | export interface CreateLoginEmailRequestResponseBody {} 10 | 11 | export async function createLoginEmailRequest( 12 | body: CreateLoginEmailRequestRequestBody 13 | ) { 14 | const data = await callApi( 15 | `api/oauth/email/requests`, 16 | { 17 | json: body, 18 | method: 'post', 19 | } 20 | ) 21 | return data 22 | } 23 | -------------------------------------------------------------------------------- /src/cloud/api/auth/google.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../lib/client' 2 | import { AddedOAuthParams } from '.' 3 | 4 | export type GoogleLoginCallbackRequestBody = { 5 | accessToken: string 6 | tokenId: string 7 | googleId: string 8 | scope: string 9 | } & AddedOAuthParams 10 | 11 | export interface GoogleLoginCallbackResponseBody { 12 | redirectTo: string 13 | } 14 | 15 | export async function postGoogleLoginCallback( 16 | body: GoogleLoginCallbackRequestBody 17 | ) { 18 | const data = await callApi( 19 | `api/oauth/google/callback`, 20 | { json: body, method: 'post' } 21 | ) 22 | return data 23 | } 24 | -------------------------------------------------------------------------------- /src/cloud/api/auth/index.ts: -------------------------------------------------------------------------------- 1 | export interface AddedOAuthParams { 2 | inviteId?: string 3 | redirectTo?: string 4 | openInviteSlug?: string 5 | } 6 | -------------------------------------------------------------------------------- /src/cloud/api/beta/registration.ts: -------------------------------------------------------------------------------- 1 | import { SerializedBetaRegistration } from '../../interfaces/db/beta' 2 | import { callApi } from '../../lib/client' 3 | 4 | export interface GetTeamBetaRegistrationResponseBody { 5 | data?: SerializedBetaRegistration 6 | } 7 | 8 | export async function getTeamBetaRegistration(teamId: string) { 9 | return callApi( 10 | `api/beta/registrations`, 11 | { 12 | method: 'get', 13 | search: { team: teamId }, 14 | } 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /src/cloud/api/docs/token.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../lib/client' 2 | 3 | interface ListDocTokenResponseBody { 4 | data: string 5 | } 6 | 7 | export async function getDocCollaborationToken(docId: string) { 8 | const result = await callApi( 9 | `api/docs/${docId}/token` 10 | ) 11 | return result 12 | } 13 | -------------------------------------------------------------------------------- /src/cloud/api/feedback/index.ts: -------------------------------------------------------------------------------- 1 | import { UserFeedbackFormData } from '../../components/FeedbackForm/types' 2 | import { callApi } from '../../lib/client' 3 | 4 | export async function sendFeedback(body: UserFeedbackFormData) { 5 | const data = await callApi(`api/feedback`, { 6 | json: body, 7 | method: 'post', 8 | }) 9 | return data 10 | } 11 | -------------------------------------------------------------------------------- /src/cloud/api/files/index.ts: -------------------------------------------------------------------------------- 1 | export function buildIconUrl(filename: string) { 2 | return `/api/files/icons/${filename}` 3 | } 4 | -------------------------------------------------------------------------------- /src/cloud/api/mock/db/mockEntities/tags.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/src/cloud/api/mock/db/mockEntities/tags.ts -------------------------------------------------------------------------------- /src/cloud/api/pages/settings/index.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from '../../../interfaces/db/user' 2 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 3 | import { callApi } from '../../../lib/client' 4 | 5 | export interface SettingsPageResponseBody { 6 | currentUser: SerializedUser 7 | } 8 | 9 | export async function getSettingsPageData({ 10 | search, 11 | signal, 12 | }: GetInitialPropsParameters) { 13 | const data = await callApi('api/pages/settings', { 14 | search, 15 | signal, 16 | }) 17 | 18 | return data 19 | } 20 | -------------------------------------------------------------------------------- /src/cloud/api/pages/shared/index.ts: -------------------------------------------------------------------------------- 1 | import { SerializedDoc } from '../../../interfaces/db/doc' 2 | import { callApi } from '../../../lib/client' 3 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 4 | 5 | export type SharePageDataResponseBody = 6 | | { 7 | link: string 8 | doc: SerializedDoc 9 | auth: string 10 | token: string 11 | } 12 | | { link: string; requireAction: 'password' } 13 | 14 | export async function getSharedPagedData({ 15 | pathname, 16 | search, 17 | }: GetInitialPropsParameters) { 18 | const [, , link] = pathname.split('/') 19 | const data = await callApi('api/pages/shared', { 20 | search: search + `&link=${link}`, 21 | }) 22 | 23 | return data 24 | } 25 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/bookmarks.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../../lib/client' 2 | import { GeneralAppProps } from '../../../interfaces/api' 3 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 4 | 5 | export type BookmarksListPageResponseBody = GeneralAppProps 6 | 7 | export async function getBookmarksListPageData({ 8 | search, 9 | signal, 10 | }: GetInitialPropsParameters) { 11 | const data = await callApi( 12 | 'api/pages/teams/bookmarks/list', 13 | { 14 | search, 15 | signal, 16 | } 17 | ) 18 | 19 | return data 20 | } 21 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/delete.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../../lib/client' 2 | import { SerializedTeam } from '../../../interfaces/db/team' 3 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 4 | 5 | export type DeleteTeamPageResponseBody = { 6 | team: SerializedTeam 7 | } 8 | 9 | export async function getDeleteTeamPageData({ 10 | pathname, 11 | search, 12 | signal, 13 | }: GetInitialPropsParameters) { 14 | const [, teamId] = pathname.split('/') 15 | const data = await callApi( 16 | 'api/pages/teams/delete', 17 | { 18 | search: search + `&teamId=${teamId}`, 19 | signal, 20 | } 21 | ) 22 | 23 | return data 24 | } 25 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/deleted.ts: -------------------------------------------------------------------------------- 1 | import { GeneralAppProps } from '../../../interfaces/api' 2 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 3 | import { callApi } from '../../../lib/client' 4 | 5 | export type ArchivedDocsListResponseBody = GeneralAppProps 6 | 7 | export async function getArchivedDocsListPageData({ 8 | pathname, 9 | search, 10 | signal, 11 | }: GetInitialPropsParameters) { 12 | const [, teamId] = pathname.split('/') 13 | const data = await callApi( 14 | 'api/pages/teams/archived/list', 15 | { 16 | search: search + `&teamId=${teamId}`, 17 | signal, 18 | } 19 | ) 20 | 21 | return data 22 | } 23 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/invite.ts: -------------------------------------------------------------------------------- 1 | import { SerializedOpenInvite } from '../../../interfaces/db/openInvite' 2 | import { callApi } from '../../../lib/client' 3 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 4 | 5 | export interface TeamOpenInvitePageData { 6 | invite: SerializedOpenInvite 7 | } 8 | 9 | export async function getTeamOpenInvitePageData({ 10 | pathname, 11 | search, 12 | signal, 13 | }: GetInitialPropsParameters) { 14 | const [, teamId, , inviteId] = pathname.split('/') 15 | const data = await callApi( 16 | 'api/pages/teams/open-invites/show', 17 | { 18 | search: search + `&teamId=${teamId}&inviteId=${inviteId}`, 19 | signal, 20 | } 21 | ) 22 | 23 | return data 24 | } 25 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/requests.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../../lib/client' 2 | import { GeneralAppProps } from '../../../interfaces/api' 3 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 4 | 5 | export type RequestDeniedResponseBody = GeneralAppProps 6 | 7 | export async function getRequestDeniedPageData({ 8 | pathname, 9 | search, 10 | signal, 11 | }: GetInitialPropsParameters) { 12 | const [, teamId] = pathname.split('/') 13 | 14 | const data = await callApi( 15 | 'api/pages/teams/requests/deny', 16 | { 17 | search: search + `&teamId=${teamId}`, 18 | signal, 19 | } 20 | ) 21 | 22 | return data 23 | } 24 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/shared.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../../lib/client' 2 | import { GeneralAppProps } from '../../../interfaces/api' 3 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 4 | 5 | export type SharedDocsListResponseBody = GeneralAppProps 6 | 7 | export async function getSharedDocsListData({ 8 | pathname, 9 | search, 10 | signal, 11 | }: GetInitialPropsParameters) { 12 | const [, teamId] = pathname.split('/') 13 | const data = await callApi( 14 | 'api/pages/teams/shared/list', 15 | { 16 | search: search + `&teamId=${teamId}`, 17 | signal, 18 | } 19 | ) 20 | 21 | return data 22 | } 23 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/tags.ts: -------------------------------------------------------------------------------- 1 | import { GeneralAppProps } from '../../../interfaces/api' 2 | import { SerializedTag } from '../../../interfaces/db/tag' 3 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 4 | import { callApi } from '../../../lib/client' 5 | 6 | export type TagsShowPageResponseBody = GeneralAppProps & { 7 | pageTag: SerializedTag 8 | } 9 | 10 | export async function getTagsShowPageData({ 11 | pathname, 12 | search, 13 | signal, 14 | }: GetInitialPropsParameters) { 15 | const [, teamId, , labelName] = pathname.split('/') 16 | const data = await callApi( 17 | 'api/pages/teams/labels/show', 18 | { 19 | search: search + `&teamId=${teamId}&labelId=${labelName}`, 20 | signal, 21 | } 22 | ) 23 | 24 | return data 25 | } 26 | -------------------------------------------------------------------------------- /src/cloud/api/pages/teams/timeline.ts: -------------------------------------------------------------------------------- 1 | import { GeneralAppProps } from '../../../interfaces/api' 2 | import { SerializedAppEvent } from '../../../interfaces/db/appEvents' 3 | import { callApi } from '../../../lib/client' 4 | import { GetInitialPropsParameters } from '../../../interfaces/pages' 5 | 6 | export type TimelinePageData = GeneralAppProps & { 7 | events: SerializedAppEvent[] 8 | } 9 | 10 | export async function getTimelinePageData({ 11 | pathname, 12 | search, 13 | signal, 14 | }: GetInitialPropsParameters) { 15 | const [, teamId] = pathname.split('/') 16 | const data = await callApi('api/pages/teams/timeline', { 17 | search: search + `&teamId=${teamId}`, 18 | signal, 19 | }) 20 | 21 | return data 22 | } 23 | -------------------------------------------------------------------------------- /src/cloud/api/rest/doc.ts: -------------------------------------------------------------------------------- 1 | import { SerializedDoc } from '../../interfaces/db/doc' 2 | import { callApi } from '../../lib/client' 3 | 4 | interface DocCreateRequestBody { 5 | content: string 6 | title: string 7 | workspaceId: string 8 | path: string 9 | tags: string[] 10 | teamId: string 11 | generated?: boolean 12 | events?: boolean 13 | } 14 | 15 | interface DocCreateResponseBody { 16 | doc: SerializedDoc 17 | } 18 | 19 | export function createDocREST(body: DocCreateRequestBody) { 20 | return callApi(`api/docs`, { 21 | method: 'post', 22 | json: body, 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /src/cloud/api/revisions/index.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../lib/client' 2 | import { SerializedTeam } from '../../interfaces/db/team' 3 | import { SerializedDoc } from '../../interfaces/db/doc' 4 | import { SerializedRevision } from '../../interfaces/db/revision' 5 | 6 | export interface CreateRevisionRequestBody { 7 | content: string 8 | title: string 9 | message?: string 10 | } 11 | export interface CreateRevisionResponseBody { 12 | revision: SerializedRevision 13 | } 14 | 15 | export async function createDocRevision( 16 | team: SerializedTeam, 17 | doc: SerializedDoc, 18 | body: CreateRevisionRequestBody 19 | ) { 20 | const data = await callApi( 21 | `api/teams/${team.id}/docs/${doc.id}/revisions`, 22 | { method: 'post', json: body } 23 | ) 24 | 25 | return data as CreateRevisionResponseBody 26 | } 27 | -------------------------------------------------------------------------------- /src/cloud/api/teams/docs/bookmarks.ts: -------------------------------------------------------------------------------- 1 | import { SerializedDocWithSupplemental } from '../../../interfaces/db/doc' 2 | import { callApi } from '../../../lib/client' 3 | 4 | export interface CreateDocBookmarkResponseBody { 5 | doc: SerializedDocWithSupplemental 6 | } 7 | 8 | export async function createDocBookmark(teamId: string, docId: string) { 9 | const data = await callApi( 10 | `api/teams/${teamId}/docs/${docId}/bookmarks`, 11 | { method: 'post' } 12 | ) 13 | 14 | return data 15 | } 16 | 17 | export interface DestroyDocBookmarkResponseBody { 18 | doc: SerializedDocWithSupplemental 19 | } 20 | 21 | export async function destroyDocBookmark(teamId: string, docId: string) { 22 | const data = await callApi( 23 | `api/teams/${teamId}/docs/${docId}/bookmarks`, 24 | { 25 | method: 'delete', 26 | } 27 | ) 28 | 29 | return data 30 | } 31 | -------------------------------------------------------------------------------- /src/cloud/api/teams/docs/revisions.ts: -------------------------------------------------------------------------------- 1 | import { SerializedRevision } from '../../../interfaces/db/revision' 2 | import { callApi } from '../../../lib/client' 3 | 4 | export interface GetAllDocRevisionsResponseBody { 5 | revisions: SerializedRevision[] 6 | page: number 7 | totalPages: number 8 | } 9 | 10 | export async function getAllRevisionsFromDoc( 11 | _teamId: string, 12 | docId: string, 13 | page = 1 14 | ) { 15 | return callApi( 16 | `api/docs/${docId}/revisions`, 17 | { 18 | search: { page }, 19 | } 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /src/cloud/api/teams/docs/tags.ts: -------------------------------------------------------------------------------- 1 | import { SerializedDocWithSupplemental } from '../../../interfaces/db/doc' 2 | import { callApi } from '../../../lib/client' 3 | 4 | export interface DeleteTagFromDocResponseBody { 5 | doc: SerializedDocWithSupplemental 6 | } 7 | 8 | export async function deleteTagFromDoc( 9 | _teamId: string, 10 | docId: string, 11 | tagId: string 12 | ) { 13 | return callApi( 14 | `api/docs/${docId}/tags/${tagId}`, 15 | { method: 'delete' } 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/cloud/api/teams/externalEntities/index.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../../lib/client' 2 | 3 | export async function getExternalEntity( 4 | team: string, 5 | type: string, 6 | id: string, 7 | refresh: boolean 8 | ) { 9 | return callApi(`api/teams/${team}/externalEntity`, { 10 | search: { 11 | type, 12 | id, 13 | refresh: refresh ? 'true' : 'false', 14 | }, 15 | headers: { 16 | Accept: 'application/json', 17 | }, 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /src/cloud/api/teams/folders/bookmarks.ts: -------------------------------------------------------------------------------- 1 | import { SerializedFolderWithBookmark } from '../../../interfaces/db/folder' 2 | import { callApi } from '../../../lib/client' 3 | 4 | export interface CreateFolderBookmarkResponseBody { 5 | folder: SerializedFolderWithBookmark 6 | } 7 | 8 | export async function createFolderBookmark(teamId: string, folderId: string) { 9 | const data = await callApi( 10 | `api/teams/${teamId}/folders/${folderId}/bookmarks`, 11 | { method: 'post' } 12 | ) 13 | 14 | return data 15 | } 16 | 17 | export interface DestroyFolderBookmarkResponseBody { 18 | folder: SerializedFolderWithBookmark 19 | } 20 | 21 | export async function destroyFolderBookmark(teamId: string, folderId: string) { 22 | const data = await callApi( 23 | `api/teams/${teamId}/folders/${folderId}/bookmarks`, 24 | { method: 'delete' } 25 | ) 26 | 27 | return data 28 | } 29 | -------------------------------------------------------------------------------- /src/cloud/api/teams/permissions/emails.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../../lib/client' 2 | import querystring from 'querystring' 3 | 4 | export interface GetUserEmailsFromPermissionsResponseBody { 5 | permissionEmails: { id: string; email: string }[] 6 | } 7 | 8 | export async function getUserEmailsFromPermissions( 9 | teamId: string, 10 | ids: string[] 11 | ) { 12 | const data = await callApi( 13 | `api/teams/${teamId}/permissions/emails`, 14 | { 15 | search: querystring.stringify({ 16 | ids, 17 | }), 18 | } 19 | ) 20 | return data 21 | } 22 | -------------------------------------------------------------------------------- /src/cloud/api/teams/props/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PropSubType, 3 | PropType, 4 | StaticPropType, 5 | } from '../../../interfaces/db/props' 6 | import { callApi } from '../../../lib/client' 7 | 8 | export type ListPropertySuggestionsRequestBody = { 9 | team: string 10 | workspace?: string 11 | doc?: string 12 | folder?: string 13 | smartView?: string 14 | propertyType?: string 15 | propertySubType?: string 16 | } 17 | 18 | export interface ListPropertySuggestionsResponseBody { 19 | data: { 20 | name: string 21 | type: StaticPropType | PropType 22 | subType?: PropSubType 23 | }[] 24 | } 25 | 26 | export async function listPropertySuggestions( 27 | body: ListPropertySuggestionsRequestBody 28 | ) { 29 | return callApi( 30 | `/api/props/suggestions`, 31 | { 32 | search: body, 33 | method: 'get', 34 | } 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /src/cloud/api/teams/sources/index.ts: -------------------------------------------------------------------------------- 1 | import { SerializedSource } from '../../../interfaces/db/source' 2 | import { SerializedTeam } from '../../../interfaces/db/team' 3 | import { callApi } from '../../../lib/client' 4 | 5 | export async function listSources( 6 | team: SerializedTeam, 7 | filters?: { type: string } 8 | ) { 9 | const data = await callApi<{ sources: SerializedSource[] }>(`api/sources`, { 10 | method: 'get', 11 | search: { ...filters, teamId: team.id }, 12 | }) 13 | return data 14 | } 15 | 16 | export async function deleteSource(_team: SerializedTeam, sourceId: string) { 17 | const data = await callApi<{}>(`api/sources/${sourceId}`, { 18 | method: 'delete', 19 | }) 20 | return data 21 | } 22 | -------------------------------------------------------------------------------- /src/cloud/api/teams/subscription/invoices.ts: -------------------------------------------------------------------------------- 1 | import { callApi } from '../../../lib/client' 2 | 3 | export interface GetCustomerInvoicePortalResponseBody { 4 | url: string 5 | } 6 | 7 | export async function getTeamPortalUrl(teamId: string) { 8 | const data = await callApi( 9 | `api/teams/${teamId}/subscription/invoices` 10 | ) 11 | return data 12 | } 13 | -------------------------------------------------------------------------------- /src/cloud/api/teams/subscription/trial.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from '../../../interfaces/db/team' 2 | import { callApi } from '../../../lib/client' 3 | import { CreateSubscriptionResponseBody } from '.' 4 | 5 | export async function startTeamFreeTrial(team: SerializedTeam) { 6 | const data = await callApi( 7 | `api/teams/${team.id}/subscription/trial`, 8 | { 9 | method: 'post', 10 | } 11 | ) 12 | return data 13 | } 14 | -------------------------------------------------------------------------------- /src/cloud/api/track/index.ts: -------------------------------------------------------------------------------- 1 | import { MixpanelFrontEvent } from '../../interfaces/analytics/mixpanel' 2 | import { callApi } from '../../lib/client' 3 | import { mockBackend } from '../../lib/consts' 4 | 5 | export async function trackEvent( 6 | eventName: MixpanelFrontEvent, 7 | data?: Record 8 | ) { 9 | if (mockBackend) { 10 | return 11 | } 12 | try { 13 | return callApi('api/track', { 14 | json: { ...data, eventName }, 15 | method: 'post', 16 | }) 17 | } catch (err) {} 18 | } 19 | -------------------------------------------------------------------------------- /src/cloud/api/uploads/index.ts: -------------------------------------------------------------------------------- 1 | import { SerializedFileInfo } from '../../interfaces/db/storage' 2 | import { callApi } from '../../lib/client' 3 | 4 | export type UploadsResponseBody = { 5 | files: SerializedFileInfo[] 6 | sizeInMb: number 7 | } 8 | 9 | export async function getUploadsData(teamId: string) { 10 | const data = await callApi('api/files', { 11 | search: `teamId=${teamId}`, 12 | }) 13 | 14 | return data 15 | } 16 | -------------------------------------------------------------------------------- /src/cloud/api/users/appfeedback.ts: -------------------------------------------------------------------------------- 1 | import { AppFeedbackTypeOption } from '../../interfaces/db/userAppFeedback' 2 | import { callApi } from '../../lib/client' 3 | 4 | export interface CreateUserAppFeedbackRequestBody { 5 | type: AppFeedbackTypeOption 6 | feedback: string 7 | } 8 | 9 | export async function registerAppFeedback( 10 | body: CreateUserAppFeedbackRequestBody 11 | ) { 12 | const result = await callApi(`api/user/feedback`, { 13 | json: body, 14 | method: 'post', 15 | }) 16 | return result 17 | } 18 | -------------------------------------------------------------------------------- /src/cloud/api/users/onboarding.ts: -------------------------------------------------------------------------------- 1 | import { UserOnboardingState } from '../../interfaces/db/user' 2 | import { callApi } from '../../lib/client' 3 | 4 | export interface UpdateUserOnboardingRequestBody { 5 | value: string 6 | } 7 | 8 | export interface UpdateUserOnboardingResponseBody { 9 | onboarding: UserOnboardingState 10 | } 11 | 12 | export async function updateUserOnboardingProgress( 13 | state: Partial 14 | ) { 15 | const body: UpdateUserOnboardingRequestBody = { value: JSON.stringify(state) } 16 | return callApi(`api/user/onboarding`, { 17 | json: body, 18 | method: 'put', 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /src/cloud/api/users/settings.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUserSettings } from '../../interfaces/db/userSettings' 2 | import { callApi } from '../../lib/client' 3 | 4 | export interface SaveUserSettingsRequestBody { 5 | value?: string 6 | notifications?: { 7 | summary?: 'daily' | 'weekly' 8 | } 9 | } 10 | 11 | export interface SaveUserSettingsResponseBody { 12 | settings: SerializedUserSettings 13 | } 14 | 15 | export async function saveUserSettings(body: SaveUserSettingsRequestBody) { 16 | const data = await callApi( 17 | `api/user/settings`, 18 | { 19 | json: body, 20 | method: 'put', 21 | } 22 | ) 23 | return data 24 | } 25 | -------------------------------------------------------------------------------- /src/cloud/components/ApplicationContent.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | ContentWrapper, 4 | ContentWrapperProps, 5 | } from '../../design/components/templates/ContentLayout' 6 | 7 | const ApplicationContent: React.FC = ({ children }) => { 8 | return {children} 9 | } 10 | 11 | export default ApplicationContent 12 | -------------------------------------------------------------------------------- /src/cloud/components/ApplicationPage.tsx: -------------------------------------------------------------------------------- 1 | import React, { PropsWithChildren } from 'react' 2 | import { TopbarPlaceholder } from '../../design/components/organisms/Topbar' 3 | import ContentLayout, { 4 | ContentLayoutProps, 5 | } from '../../design/components/templates/ContentLayout' 6 | 7 | type ApplicationPageProps = { 8 | showingTopbarPlaceholder?: boolean 9 | } & ContentLayoutProps 10 | 11 | const ApplicationPage = ({ 12 | showingTopbarPlaceholder: topbarPlaceholder, 13 | children, 14 | ...props 15 | }: PropsWithChildren) => { 16 | return ( 17 | 18 | {topbarPlaceholder && } 19 | {children} 20 | 21 | ) 22 | } 23 | 24 | export default ApplicationPage 25 | -------------------------------------------------------------------------------- /src/cloud/components/Automations/EventInfo.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { JsonTypeDef } from '../../lib/automations/events' 3 | 4 | interface EventSelectProps { 5 | name: string 6 | typeDef: JsonTypeDef 7 | } 8 | 9 | const EventInfo = ({ typeDef }: EventSelectProps) => { 10 | return ( 11 |
12 |
{JSON.stringify(typeDef, null, 2).replaceAll('"', '')}
13 |
14 | ) 15 | } 16 | 17 | export default EventInfo 18 | -------------------------------------------------------------------------------- /src/cloud/components/Automations/actions/index.ts: -------------------------------------------------------------------------------- 1 | import { SerializedPipe } from '../../../interfaces/db/automations' 2 | import { JsonTypeDef } from '../../../lib/automations/events' 3 | 4 | export interface ActionConfiguratorProps { 5 | onChange: (conf: SerializedPipe['configuration']) => void 6 | configuration: SerializedPipe['configuration'] 7 | eventType: JsonTypeDef 8 | } 9 | -------------------------------------------------------------------------------- /src/cloud/components/CloudModal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Modal from '../../design/components/organisms/Modal' 3 | import { useModal } from '../../design/lib/stores/modal' 4 | import { usePathnameChangeEffect } from '../lib/router' 5 | 6 | const CloudModal = () => { 7 | const { closeAllModals } = useModal() 8 | usePathnameChangeEffect(closeAllModals) 9 | 10 | return 11 | } 12 | 13 | export default CloudModal 14 | -------------------------------------------------------------------------------- /src/cloud/components/ContentManager/styled.ts: -------------------------------------------------------------------------------- 1 | import styled from '../../../design/lib/styled' 2 | 3 | export const StyledContentManager = styled.div` 4 | display: block; 5 | width: 100%; 6 | ` 7 | 8 | export const StyledContentManagerList = styled.div` 9 | display: flex; 10 | flex-direction: column; 11 | width: 100%; 12 | ` 13 | -------------------------------------------------------------------------------- /src/cloud/components/DocPage/styles.ts: -------------------------------------------------------------------------------- 1 | import { rightSideTopBarHeight } from '../../../design/components/organisms/Topbar' 2 | import styled from '../../../design/lib/styled' 3 | import { rightSidePageLayout } from '../../../design/lib/styled/styleFunctions' 4 | 5 | export const StyledDocPage = styled.div` 6 | ${rightSidePageLayout} 7 | margin: 0 auto; 8 | padding-top: calc( 9 | ${rightSideTopBarHeight}px + ${({ theme }) => theme.sizes.spaces.l}px 10 | ); 11 | padding-left: ${({ theme }) => theme.sizes.spaces.l}px; 12 | padding-right: ${({ theme }) => theme.sizes.spaces.l}px; 13 | min-height: calc(100vh - ${rightSideTopBarHeight}px); 14 | height: auto; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | ` 19 | 20 | export const StyledDocPageButtons = styled.div` 21 | display: flex; 22 | align-items: center; 23 | ` 24 | -------------------------------------------------------------------------------- /src/cloud/components/Editor/types.ts: -------------------------------------------------------------------------------- 1 | export type FormattingTool = 2 | | 'header1' 3 | | 'header2' 4 | | 'header3' 5 | | 'header4' 6 | | 'header5' 7 | | 'header6' 8 | | 'admonitionNote' 9 | | 'admonitionTip' 10 | | 'admonitionImportant' 11 | | 'admonitionDanger' 12 | | 'admonitionWarning' 13 | | 'bold' 14 | | 'italic' 15 | | 'quote' 16 | | 'code' 17 | | 'bulletedList' 18 | | 'numberedList' 19 | | 'taskList' 20 | | 'link' 21 | | 'codefence' 22 | | 'math' 23 | | 'brackets' 24 | -------------------------------------------------------------------------------- /src/cloud/components/FeedbackForm/types.ts: -------------------------------------------------------------------------------- 1 | export interface UserFeedbackFormData { 2 | needFeatures: boolean 3 | needIntegrations: boolean 4 | needCheaper: boolean 5 | features?: string 6 | integrations?: string 7 | price?: string 8 | } 9 | -------------------------------------------------------------------------------- /src/cloud/components/MarkdownView/Shortcode/github/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from '../../../../../design/lib/styled' 2 | 3 | export const StyledGithubEmbed = styled.span` 4 | padding: 10px; 5 | display: inline-flex; 6 | background-color: white; 7 | 8 | & > svg { 9 | margin-right: 5px; 10 | } 11 | ` 12 | 13 | export const SpanBlock = styled.span` 14 | display: block; 15 | ` 16 | 17 | export const Title = styled.a` 18 | text-decoration: none; 19 | font-size: 24; 20 | ` 21 | 22 | export const InfoBlock = styled.span` 23 | display: block; 24 | color: black; 25 | font-size: 14px; 26 | opacity: 0.7; 27 | ` 28 | 29 | export const Label = styled.span` 30 | display: inline-block; 31 | padding: 0 7px; 32 | margin: 2px 2px 2px 0; 33 | margin-left: 10px; 34 | border-radius: 2em; 35 | font-size: 12px; 36 | font-weight: 500; 37 | line-height: 18px; 38 | text-decoration: none; 39 | ` 40 | -------------------------------------------------------------------------------- /src/cloud/components/Modal/contents/FeedbackModal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import AppFeedbackForm from '../../AppFeedbackForm' 3 | 4 | const FeedbackModal = () => { 5 | return 6 | } 7 | 8 | export default FeedbackModal 9 | -------------------------------------------------------------------------------- /src/cloud/components/Modal/contents/SmartView/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { Condition, ConditionType } from '../../../../interfaces/db/smartView' 2 | 3 | export type EditableQuery = EditableCondition[] 4 | 5 | export type EditableCondition = 6 | | ConditionType<'query', EditableQuery> 7 | | Exclude 8 | | { type: 'null'; rule: 'and' | 'or' } 9 | 10 | export type Kind = Extract< 11 | T, 12 | { type: K } 13 | > 14 | -------------------------------------------------------------------------------- /src/cloud/components/SearchableOptionListPopup.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from 'react' 2 | import { useEffectOnce } from 'react-use' 3 | import SearchableOptionList, { 4 | SearchableOptionListProps, 5 | } from '../../design/components/molecules/SearchableOptionList' 6 | import { AppComponent } from '../../design/lib/types' 7 | 8 | const SearchableOptionListPopup: AppComponent = ({ 9 | children, 10 | ...props 11 | }) => { 12 | const inputRef = useRef(null) 13 | 14 | useEffectOnce(() => { 15 | if (inputRef.current != null) { 16 | inputRef.current.focus() 17 | } 18 | }) 19 | 20 | return 21 | } 22 | 23 | export default SearchableOptionListPopup 24 | -------------------------------------------------------------------------------- /src/cloud/components/TitleComponent.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../design/lib/styled' 3 | 4 | const TitleComponent = () => ( 5 | 6 | 7 | Boost Note 8 | 9 | 10 | ) 11 | 12 | export default TitleComponent 13 | 14 | const StyledTitle = styled.div` 15 | padding-top: ${({ theme }) => theme.sizes.spaces.sm}px; 16 | 17 | img { 18 | height: 50px; 19 | vertical-align: middle; 20 | } 21 | ` 22 | -------------------------------------------------------------------------------- /src/cloud/components/Topbar/Controls/ControlsContextMenu/ControlsContextMenuBackground.tsx: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react' 2 | import { StyledContextMenuBackground } from './styled' 3 | 4 | interface ControlsContextMenuBackgroundProps { 5 | closeContextMenu: () => void 6 | } 7 | 8 | const ControlsContextMenuBackground = ({ 9 | closeContextMenu, 10 | }: ControlsContextMenuBackgroundProps) => { 11 | const backgroundClickHandler = useMemo(() => { 12 | return (event: MouseEvent) => { 13 | event.preventDefault() 14 | closeContextMenu() 15 | } 16 | }, [closeContextMenu]) 17 | 18 | return 19 | } 20 | 21 | export default ControlsContextMenuBackground 22 | -------------------------------------------------------------------------------- /src/cloud/components/ViewerRestrictedWrapper.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Banner from '../../design/components/atoms/Banner' 3 | import { AppComponent } from '../../design/lib/types' 4 | import { usePage } from '../lib/stores/pageStore' 5 | 6 | interface ViewerRestrictedWrapperProps { 7 | showBanner?: boolean 8 | } 9 | 10 | const ViewerRestrictedWrapper: AppComponent = ({ 11 | children, 12 | showBanner = true, 13 | }) => { 14 | const { currentUserIsCoreMember } = usePage() 15 | 16 | if (!currentUserIsCoreMember) { 17 | return showBanner ? ( 18 | 19 | This feature is restricted to members only. Consider asking your team 20 | members to promote you to a member role. 21 | 22 | ) : null 23 | } 24 | 25 | return <>{children} 26 | } 27 | 28 | export default ViewerRestrictedWrapper 29 | -------------------------------------------------------------------------------- /src/cloud/components/homepage/IntegrationServiceImage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../../design/lib/styled' 3 | 4 | interface IntegrationServiceImageProps { 5 | src: string 6 | } 7 | 8 | const IntegrationServiceImage = ({ src }: IntegrationServiceImageProps) => { 9 | return ( 10 | 11 | 12 | 13 | ) 14 | } 15 | 16 | export default IntegrationServiceImage 17 | 18 | const StyledContainer = styled.div` 19 | width: 200px; 20 | height: 200px; 21 | padding: 15px; 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | border-radius: 10px; 26 | background-color: white; 27 | margin-bottom: 15px; 28 | & > .image { 29 | width: 100%; 30 | } 31 | ` 32 | -------------------------------------------------------------------------------- /src/cloud/components/homepage/PageContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../../design/lib/styled' 3 | 4 | const PageContainer: React.FC = ({ children }) => { 5 | return {children} 6 | } 7 | 8 | export default PageContainer 9 | 10 | const Container = styled.div` 11 | background: linear-gradient(#302642, #292b36); 12 | color: #c0bfc5; 13 | min-height: 100%; 14 | width: 100%; 15 | overflow-x: hidden; 16 | overflow-y: auto; 17 | position: absolute; 18 | top: 0; 19 | left: 0; 20 | bottom: 0; 21 | right: 0; 22 | ` 23 | -------------------------------------------------------------------------------- /src/cloud/components/layouts/CenteredContainer.tsx: -------------------------------------------------------------------------------- 1 | import styled from '../../../design/lib/styled' 2 | 3 | const Container = styled.div` 4 | position: relative; 5 | width: 1085px; 6 | max-width: 96%; 7 | margin: 0 auto; 8 | ` 9 | 10 | export default Container 11 | -------------------------------------------------------------------------------- /src/cloud/components/settings/PreferencesTab.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useTranslation } from 'react-i18next' 3 | import SettingTabContent from '../../../design/components/organisms/Settings/atoms/SettingTabContent' 4 | import { lngKeys } from '../../lib/i18n/types' 5 | import UserPreferencesForm from './UserPreferencesForm' 6 | 7 | const PreferencesTab = () => { 8 | const { t } = useTranslation() 9 | 10 | return ( 11 | } 15 | /> 16 | ) 17 | } 18 | 19 | export default PreferencesTab 20 | -------------------------------------------------------------------------------- /src/cloud/components/settings/SlackIntegration.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import SettingTabContent from '../../../design/components/organisms/Settings/atoms/SettingTabContent' 3 | import IntegrationManager from './IntegrationManager' 4 | 5 | const SlackIntegration = () => { 6 | return ( 7 | 15 |

How does it work?

16 |

Show Boost Note document preview in Slack

17 | 18 | } 19 | /> 20 | ) 21 | } 22 | 23 | export default SlackIntegration 24 | -------------------------------------------------------------------------------- /src/cloud/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './components/App' 4 | import './lib/i18n' 5 | import { RouterProvider } from './lib/router' 6 | import { ElectronProvider } from './lib/stores/electron' 7 | 8 | function render(Component: typeof App) { 9 | let rootDiv = document.getElementById('root') 10 | if (rootDiv == null) { 11 | rootDiv = document.createElement('div', {}) 12 | rootDiv.setAttribute('id', 'root') 13 | document.body.appendChild(rootDiv) 14 | } 15 | ReactDOM.render( 16 | 17 | 18 | 19 | 20 | , 21 | 22 | document.getElementById('root') 23 | ) 24 | } 25 | 26 | if (module.hot != null) { 27 | module.hot.accept('./components/App', () => { 28 | render(App) 29 | }) 30 | } 31 | render(App) 32 | -------------------------------------------------------------------------------- /src/cloud/interfaces/analytics/intercom.ts: -------------------------------------------------------------------------------- 1 | // intercom replaces periods with hyphens and is case insensitive 2 | 3 | export enum IntercomDataEvent { 4 | DocCreate = 'doc-create', 5 | InviteCreate = 'invite-create', 6 | MemberCreate = 'member-create', 7 | ViewerCreate = 'viewer-create', 8 | TrialStart = 'trial-create', 9 | SubscriptionStart = 'sub-create', 10 | TeamCreate = 'team-create', 11 | PersonalTeamCreate = 'personal-create', 12 | } 13 | -------------------------------------------------------------------------------- /src/cloud/interfaces/api.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from './db/team' 2 | import { SerializedFolderWithBookmark } from './db/folder' 3 | import { SerializedDocWithSupplemental } from './db/doc' 4 | import { SerializedUserTeamPermissions } from './db/userTeamPermissions' 5 | import { SerializedSubscription } from './db/subscription' 6 | import { SerializedTag } from './db/tag' 7 | import { SerializedWorkspace } from './db/workspace' 8 | 9 | export interface GeneralAppProps { 10 | team: SerializedTeam 11 | folders: SerializedFolderWithBookmark[] 12 | docs: SerializedDocWithSupplemental[] 13 | permissions: SerializedUserTeamPermissions[] 14 | subscription?: SerializedSubscription 15 | workspaces: SerializedWorkspace[] 16 | tags: SerializedTag[] 17 | } 18 | 19 | export interface TrgmProperty { 20 | sml: number 21 | context?: string 22 | } 23 | -------------------------------------------------------------------------------- /src/cloud/interfaces/components/ContentManager/types.ts: -------------------------------------------------------------------------------- 1 | import { SerializedDocWithSupplemental } from '../../db/doc' 2 | import { SerializedFolderWithBookmark } from '../../db/folder' 3 | 4 | export type UnsignedItem = 5 | | SerializedDocWithSupplemental 6 | | SerializedFolderWithBookmark 7 | 8 | export type ContentManagerRowAction = { 9 | iconPath: string 10 | tooltip?: string 11 | id: number 12 | onClick: (item: T) => void 13 | } 14 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/accessToken.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | import { SerializedAccessTokenRequest } from './accessTokenRequests' 3 | 4 | export interface SerializableAccessTokenProps { 5 | id: string 6 | accessToken: string 7 | active: boolean 8 | } 9 | 10 | export interface SerializedUnserializableAccessTokenProps { 11 | user?: SerializedUser | string 12 | accessTokenRequest?: SerializedAccessTokenRequest | string 13 | } 14 | 15 | export type SerializedAccessToken = SerializedUnserializableAccessTokenProps & 16 | SerializableAccessTokenProps 17 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/accessTokenRequests.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | 3 | export interface SerializableAccessTokenRequestProps { 4 | id: string 5 | code: string 6 | secret: string 7 | active: boolean 8 | } 9 | 10 | export interface SerializedUnserializableAccessTokenRequestProps { 11 | createdAt: string 12 | updatedAt: string 13 | user?: SerializedUser | string 14 | } 15 | 16 | export type SerializedAccessTokenRequest = 17 | SerializedUnserializableAccessTokenRequestProps & 18 | SerializableAccessTokenRequestProps 19 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/apiTokens.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedApiToken { 2 | id: string 3 | name: string 4 | token: string 5 | userId: string 6 | teamId: string 7 | } 8 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/automations.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedPipe { 2 | name: string 3 | action: string 4 | event: string 5 | filter?: any 6 | configuration: any 7 | } 8 | 9 | export interface SerializedWorkflow { 10 | id: number 11 | name: string 12 | description: string 13 | pipes: SerializedPipe[] 14 | teamId?: string 15 | createdById?: string 16 | createdAt: string 17 | updatedAt: string 18 | } 19 | 20 | export interface SerializedAutomation { 21 | id: number 22 | name: string 23 | description: string 24 | workflowId: number 25 | teamId: string 26 | env: any 27 | createdById: string 28 | createdAt: string 29 | updatedAt: string 30 | } 31 | 32 | export interface SerializedAutomationLog { 33 | type: string 34 | info: string 35 | isError: boolean 36 | createdAt: string 37 | } 38 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/bookmarks.ts: -------------------------------------------------------------------------------- 1 | import { SerializedDoc } from './doc' 2 | import { SerializedFolder } from './folder' 3 | 4 | export interface SerializedDocBookmark { 5 | id: string 6 | docId: string 7 | doc?: SerializedDoc 8 | } 9 | 10 | export interface SerializedFolderBookmark { 11 | id: string 12 | folderId: string 13 | folder?: SerializedFolder 14 | } 15 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/commentReaction.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUserTeamPermissions } from './userTeamPermissions' 2 | 3 | export interface CommentReaction { 4 | id: string 5 | emoji: string 6 | teamMember: SerializedUserTeamPermissions 7 | createdAt: string 8 | } 9 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/connections.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedServiceConnection { 2 | id: string 3 | service: string 4 | token: string 5 | identifier: string 6 | } 7 | 8 | export interface SerializedTeamIntegration { 9 | id: string 10 | service: string 11 | name: string 12 | identifier: string 13 | teamId: string 14 | } 15 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/dashboard.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUserTeamPermissions } from './userTeamPermissions' 2 | import { SerializedSmartView } from './smartView' 3 | import { Layout } from 'react-grid-layout' 4 | 5 | interface SerializableDashboardProps { 6 | id: string 7 | name: string 8 | ownerId: string 9 | data: DashboardData 10 | } 11 | 12 | interface SerializedUnserializableDashboardProps { 13 | owner?: SerializedUserTeamPermissions 14 | smartViews?: SerializedSmartView[] 15 | createdAt: string 16 | } 17 | 18 | export type SerializedDashboard = SerializableDashboardProps & 19 | SerializedUnserializableDashboardProps 20 | 21 | export type DashboardData = { 22 | itemsLayouts: Layout[] 23 | } 24 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/editRequest.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUserTeamPermissions } from './userTeamPermissions' 2 | 3 | export interface SerializableEditRequestProps { 4 | id: string 5 | userPermissionId: string 6 | } 7 | 8 | export interface SerializedUnserializableEditRequestProps { 9 | createdAt: string 10 | userPermission?: SerializedUserTeamPermissions 11 | } 12 | 13 | export type SerializedEditRequest = SerializedUnserializableEditRequestProps & 14 | SerializableEditRequestProps 15 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/errorReport.ts: -------------------------------------------------------------------------------- 1 | export interface SerializableErrorReportProps { 2 | id: number 3 | name: string 4 | message?: string 5 | stack?: string 6 | from?: string 7 | } 8 | 9 | export interface UnserializableErrorReportProps { 10 | createdAt: Date 11 | updatedAt: Date 12 | } 13 | 14 | export interface SerializedUnserializableErrorReportProps { 15 | createdAt: string 16 | updatedAt: string 17 | } 18 | 19 | export type SerializedErrorReport = SerializedUnserializableErrorReportProps & 20 | SerializableErrorReportProps 21 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/externalEntity.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedExternalEntity { 2 | id: string 3 | type: string 4 | externalId: string 5 | data: string 6 | searchable: string 7 | } 8 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/folderPositions.ts: -------------------------------------------------------------------------------- 1 | import { SerializedFolder } from './folder' 2 | import { SerializedTeam } from './team' 3 | 4 | export interface SerializableFolderPositionsProps { 5 | id: string 6 | orderedIds: string[] 7 | } 8 | 9 | export interface SerializedUnserializableFolderPositionsProps { 10 | parentFolder?: SerializedFolder | string 11 | team?: SerializedTeam | string 12 | updatedAt: string 13 | } 14 | 15 | export type SerializedFolderPositions = 16 | SerializedUnserializableFolderPositionsProps & 17 | SerializableFolderPositionsProps 18 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/icon.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedIcon { 2 | id: number 3 | location: string 4 | createdAt: string 5 | updatedAt: string 6 | } 7 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/mention.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from './team' 2 | import { SerializedDoc } from './doc' 3 | import { SerializedUser } from './user' 4 | 5 | export interface SerializedMention { 6 | id: string 7 | team: string | SerializedTeam 8 | doc: string | SerializedDoc 9 | target: string | SerializedUser 10 | source: string | SerializedUser 11 | createdAt: string 12 | seenAt?: string 13 | } 14 | 15 | export interface ExpandedSerializedMention extends SerializedMention { 16 | doc: SerializedDoc 17 | target: SerializedUser 18 | source: SerializedUser 19 | } 20 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/notifications.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | 3 | export interface Notification { 4 | id: string 5 | title: string 6 | contextType: string 7 | context: string 8 | content: string 9 | link: string 10 | target: SerializedUser 11 | source?: SerializedUser 12 | createdAt: Date 13 | viewedAt?: Date 14 | team: string 15 | } 16 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/openInvite.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from './team' 2 | import { TeamPermissionType } from './userTeamPermissions' 3 | 4 | export interface SerializableOpenInviteProps { 5 | id: string 6 | role: TeamPermissionType 7 | slug: string 8 | teamId: string 9 | } 10 | 11 | export interface SerializedUnserializableOpenInviteProps { 12 | createdAt: string 13 | updatedAt: string 14 | team?: SerializedTeam 15 | } 16 | 17 | export type SerializedOpenInvite = SerializedUnserializableOpenInviteProps & 18 | SerializableOpenInviteProps 19 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/revision.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | import { SerializedDoc } from './doc' 3 | 4 | export interface SerializedRevision { 5 | id: number 6 | content: string 7 | message: string 8 | created: string 9 | creators: SerializedUser[] 10 | docId: string 11 | doc?: SerializedDoc 12 | } 13 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/shareLink.ts: -------------------------------------------------------------------------------- 1 | import { SerializedDoc } from './doc' 2 | 3 | export interface SerializedShareLink { 4 | id: string 5 | password?: string 6 | expireAt?: string 7 | doc?: SerializedDoc 8 | } 9 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/source.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedSource { 2 | id: string 3 | identifier: string 4 | inputStreamId: string 5 | createdAt: string 6 | invalidated: boolean 7 | name: string 8 | } 9 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/status.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedStatus { 2 | id: number 3 | teamId: string 4 | name: string 5 | backgroundColor?: string 6 | } 7 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/storage.ts: -------------------------------------------------------------------------------- 1 | export interface SerializedFileInfo { 2 | id: string 3 | url: string 4 | name: string 5 | size: number 6 | storageId: string 7 | createdAt: string 8 | } 9 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/subscription.ts: -------------------------------------------------------------------------------- 1 | import { SubscriptionPeriod, UpgradePlans } from '../../lib/stripe' 2 | 3 | export interface SerializeableSubscriptionProps { 4 | id: string 5 | plan: UpgradePlans 6 | customerId: string 7 | subscriptionId: string 8 | couponId?: string 9 | seats: number 10 | period: SubscriptionPeriod 11 | status: 12 | | 'active' 13 | | 'past_due' 14 | | 'incomplete' 15 | | 'canceled' 16 | | 'inactive' 17 | | 'trialing' 18 | cardBrand?: string 19 | last4?: string 20 | trialEnd: number 21 | currentPeriodEnd: number 22 | email: string 23 | teamId: string 24 | team: string 25 | } 26 | 27 | export interface SerializedUnserializableSubscriptionsProps { 28 | createdAt: string 29 | updatedAt: string 30 | } 31 | 32 | export type SerializedSubscription = SerializeableSubscriptionProps & 33 | SerializeableSubscriptionProps 34 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/tag.ts: -------------------------------------------------------------------------------- 1 | import type { SerializedTeam } from './team' 2 | import type { SerializedDoc } from './doc' 3 | 4 | export interface SerializableTagProps { 5 | id: string 6 | text: string 7 | teamId: string 8 | backgroundColor?: string 9 | } 10 | 11 | export interface SerializedUnserializableTagProps { 12 | docs?: SerializedDoc[] 13 | team: SerializedTeam 14 | createdAt: string 15 | } 16 | 17 | export type SerializedTag = SerializedUnserializableTagProps & 18 | SerializableTagProps 19 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/teamInvite.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from './team' 2 | import { SerializedUser } from './user' 3 | 4 | export interface SerializableTeamInviteProps { 5 | id: string 6 | role: string 7 | email: string 8 | pending: boolean 9 | accepted: boolean 10 | } 11 | 12 | export interface SerializedUnserializableTeamInviteProps { 13 | createdAt: string 14 | updatedAt: string 15 | inviter: SerializedUser 16 | user?: SerializedUser 17 | canceller?: SerializedUser 18 | team: SerializedTeam 19 | } 20 | 21 | export type SerializedTeamInvite = SerializedUnserializableTeamInviteProps & 22 | SerializableTeamInviteProps 23 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/template.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from './team' 2 | import { SerializedUser } from './user' 3 | 4 | export interface SerializableTemplateProps { 5 | id: string 6 | emoji?: string 7 | title: string 8 | content: string 9 | editorId?: string 10 | teamId: string 11 | } 12 | 13 | export interface SerializedUnserializableTemplateProps { 14 | team: SerializedTeam 15 | editor: SerializedUser 16 | createdAt: string 17 | updatedAt: string 18 | } 19 | 20 | export type SerializedTemplate = SerializedUnserializableTemplateProps & 21 | SerializableTemplateProps 22 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/user.ts: -------------------------------------------------------------------------------- 1 | import { SerializedIcon } from './icon' 2 | import { SerializedUserTeamPermissions } from './userTeamPermissions' 3 | 4 | export interface SerializableUserProps { 5 | id: string 6 | uniqueName: string 7 | displayName: string 8 | icon?: SerializedIcon 9 | } 10 | 11 | export interface SerializedUnserializableUserProps { 12 | permissions?: SerializedUserTeamPermissions[] 13 | createdAt: string 14 | updatedAt: string 15 | } 16 | 17 | export type SerializedUser = SerializedUnserializableUserProps & 18 | SerializableUserProps 19 | 20 | export interface UserOnboardingState { 21 | trialAnnouncement?: boolean 22 | } 23 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/userAccessToken.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | 3 | export interface SerializableUserAccessTokenProps { 4 | id: string 5 | accessToken: string 6 | } 7 | 8 | export interface SerializedUnserializableUserAccessTokenProps { 9 | createdAt: string 10 | updatedAt: string 11 | user: SerializedUser 12 | } 13 | 14 | export type SerializedUserAccessToken = 15 | SerializedUnserializableUserAccessTokenProps & 16 | SerializableUserAccessTokenProps 17 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/userAppFeedback.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | 3 | export interface SerializableUserAppFeedbackProps { 4 | id: string 5 | type: string 6 | feedback: string 7 | } 8 | 9 | export interface SerializedUnserializableUserAppFeedbackProps { 10 | createdAt: string 11 | user: SerializedUser 12 | } 13 | 14 | export type SerializedUserAppFeedback = 15 | SerializedUnserializableUserAppFeedbackProps & 16 | SerializableUserAppFeedbackProps 17 | 18 | export type AppFeedbackTypeOption = 'Feature Request' | 'Bug Report' 19 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/userFeedback.ts: -------------------------------------------------------------------------------- 1 | export interface SerializableUserFeedbackProps { 2 | id: string 3 | feedback: any 4 | uniqueName: string 5 | } 6 | 7 | export interface UnserializableUserFeedbackProps { 8 | createdAt: Date 9 | } 10 | 11 | export interface SerializedUnserializableUserFeedbackProps { 12 | createdAt: string 13 | } 14 | 15 | export type SerializedUserFeedback = SerializedUnserializableUserFeedbackProps & 16 | SerializableUserFeedbackProps 17 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/userOnboarding.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser, UserOnboardingState } from './user' 2 | 3 | export interface SerializableUserOnboardingProps { 4 | id: string 5 | state: UserOnboardingState 6 | version: number 7 | } 8 | 9 | export interface SerializedUnserializableUserOnboardingProps { 10 | user: SerializedUser 11 | } 12 | 13 | export type SerializedUserOnboarding = 14 | SerializedUnserializableUserOnboardingProps & SerializableUserOnboardingProps 15 | 16 | export const userOnboardingBasicStepsStateKeys = [ 17 | 'createdFolder', 18 | 'createdDocument', 19 | 'invitedColleague', 20 | 'changedPreferences', 21 | ] 22 | 23 | export const userOnboardingNewFeaturesStateKeys = ['checkedShortKeyCheatsheet'] 24 | 25 | export const userOnboardingStateKeys = [ 26 | ...userOnboardingBasicStepsStateKeys, 27 | ...userOnboardingNewFeaturesStateKeys, 28 | ] 29 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/userSettings.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | import { UserSettings } from '../../lib/stores/settings/types' 3 | 4 | export type UserEmailNotificationType = 'daily' | 'weekly' 5 | 6 | export interface SerializableUserSettingsProps { 7 | id: string 8 | value: UserSettings 9 | version: number 10 | notifications?: { 11 | summary?: UserEmailNotificationType 12 | } 13 | } 14 | 15 | export interface SerializedUnserializableUserSettingsProps { 16 | updatedAt: string 17 | user: SerializedUser 18 | } 19 | 20 | export type SerializedUserSettings = SerializedUnserializableUserSettingsProps & 21 | SerializableUserSettingsProps 22 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/userTeamPermissions.ts: -------------------------------------------------------------------------------- 1 | import { SerializedUser } from './user' 2 | import { SerializedTeam } from './team' 3 | 4 | export type TeamPermissionType = 'admin' | 'member' | 'viewer' 5 | 6 | export interface SerializableUserTeamPermissionsProps { 7 | id: string 8 | role: TeamPermissionType 9 | userId: string 10 | teamId: string 11 | } 12 | 13 | export interface SerializedUnserializableUserTeamPermissionsProps { 14 | createdAt: string 15 | updatedAt: string 16 | user: SerializedUser 17 | team: SerializedTeam 18 | } 19 | 20 | export type SerializedUserTeamPermissions = 21 | SerializedUnserializableUserTeamPermissionsProps & 22 | SerializableUserTeamPermissionsProps 23 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/workspace.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from './team' 2 | import { SerializedUserTeamPermissions } from './userTeamPermissions' 3 | import { SerializedWorkspacePositions } from './workspacePositions' 4 | 5 | export interface SerializableWorkspaceProps { 6 | id: string 7 | name: string 8 | teamId: string 9 | personal: boolean 10 | default: boolean 11 | public: boolean 12 | ownerId?: string 13 | } 14 | 15 | export interface SerializedUnserializableWorkspaceProps { 16 | team?: SerializedTeam 17 | owner?: SerializedUserTeamPermissions 18 | permissions?: SerializedUserTeamPermissions[] 19 | positions?: SerializedWorkspacePositions 20 | createdAt: string 21 | updatedAt: string 22 | } 23 | 24 | export type SerializedWorkspace = SerializedUnserializableWorkspaceProps & 25 | SerializableWorkspaceProps 26 | -------------------------------------------------------------------------------- /src/cloud/interfaces/db/workspacePositions.ts: -------------------------------------------------------------------------------- 1 | import { SerializedWorkspace } from './workspace' 2 | import { SerializedTeam } from './team' 3 | 4 | export interface SerializableWorkspacePositionsProps { 5 | id: string 6 | orderedIds: string[] 7 | } 8 | 9 | export interface SerializedUnserializableWorkspacePositionsProps { 10 | workspace?: SerializedWorkspace 11 | team: SerializedTeam | string 12 | updatedAt: string 13 | } 14 | 15 | export type SerializedWorkspacePositions = 16 | SerializedUnserializableWorkspacePositionsProps & 17 | SerializableWorkspacePositionsProps 18 | -------------------------------------------------------------------------------- /src/cloud/interfaces/events.ts: -------------------------------------------------------------------------------- 1 | interface Event { 2 | id: string 3 | type: T 4 | time: string 5 | data: U 6 | } 7 | 8 | interface DocEventData { 9 | id: string 10 | emoji?: string | null 11 | title: string 12 | content: string 13 | teamId: string 14 | parentFolderId?: string 15 | folderPathname: string 16 | updatedAt: string 17 | createdAt: string 18 | pathname: string 19 | workspaceId: string 20 | version: number 21 | } 22 | 23 | export type DocCreateEvent = Event< 24 | 'doc.create', 25 | DocEventData & { creator?: string } 26 | > 27 | export type DocUpdateEvent = Event< 28 | 'doc.update', 29 | DocEventData & { editors: string[] } 30 | > 31 | 32 | export type HookEvent = DocCreateEvent | DocUpdateEvent 33 | 34 | export type HookEventType = HookEvent['type'] 35 | -------------------------------------------------------------------------------- /src/cloud/interfaces/pageStore.ts: -------------------------------------------------------------------------------- 1 | import { SerializedTeam } from './db/team' 2 | 3 | export interface PageStoreWithTeam { 4 | team?: SerializedTeam 5 | } 6 | -------------------------------------------------------------------------------- /src/cloud/interfaces/pages.ts: -------------------------------------------------------------------------------- 1 | export interface RedirectToPageResponseBody { 2 | redirectTo: string 3 | } 4 | 5 | export interface GetInitialPropsParameters { 6 | pathname: string 7 | search: string 8 | signal: AbortSignal 9 | } 10 | -------------------------------------------------------------------------------- /src/cloud/interfaces/presence.ts: -------------------------------------------------------------------------------- 1 | export interface UserPresenceInfo { 2 | id: string 3 | name: string 4 | color: string 5 | icon?: string 6 | } 7 | -------------------------------------------------------------------------------- /src/cloud/lib/charts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './remarkCharts' 2 | export * from './flowchart' 3 | export * from './charts' 4 | export * from './plantuml' 5 | -------------------------------------------------------------------------------- /src/cloud/lib/dnd.ts: -------------------------------------------------------------------------------- 1 | import { DragEvent } from 'react' 2 | 3 | export enum DraggedTo { 4 | insideFolder = 0, 5 | beforeItem = -1, 6 | afterItem = 1, 7 | } 8 | 9 | export type SidebarDragState = undefined | -1 | 0 | 1 10 | 11 | export const onDragLeaveCb = ( 12 | event: DragEvent, 13 | dropzone: React.RefObject, 14 | cb: () => void 15 | ) => { 16 | event.stopPropagation() 17 | const relatedTarget = event.relatedTarget 18 | let targetIsChildElement = false 19 | if ( 20 | relatedTarget != null && 21 | dropzone.current != null && 22 | relatedTarget instanceof Node 23 | ) { 24 | if (dropzone.current.contains(relatedTarget)) { 25 | targetIsChildElement = true 26 | } 27 | } 28 | 29 | if (!targetIsChildElement) { 30 | cb() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/cloud/lib/homepageUrls.ts: -------------------------------------------------------------------------------- 1 | export const macOsDmgUrl = 2 | 'https://github.com/BoostIO/BoostNote-App/releases/latest/download/boost-note-mac.dmg' 3 | export const macOsZipUrl = 4 | 'https://github.com/BoostIO/BoostNote-App/releases/latest/download/boost-note-mac.zip' 5 | export const windowsNsisUrl = 6 | 'https://github.com/BoostIO/BoostNote-App/releases/latest/download/boost-note-win.exe' 7 | export const linuxAppImageUrl = 8 | 'https://github.com/BoostIO/BoostNote-App/releases/latest/download/boost-note-linux.AppImage' 9 | export const linuxDebUrl = 10 | 'https://github.com/BoostIO/BoostNote-App/releases/latest/download/boost-note-linux.deb' 11 | export const linuxRpmUrl = 12 | 'https://github.com/BoostIO/BoostNote-App/releases/latest/download/boost-note-linux.rpm' 13 | 14 | export const intercomFaqUrl = 'https://intercom.help/boostnote-for-teams/en' 15 | export const mediumBlogUrl = 'https://medium.com/boostnote' 16 | -------------------------------------------------------------------------------- /src/cloud/lib/hooks/index.ts: -------------------------------------------------------------------------------- 1 | import { useState, useRef, useEffect } from 'react' 2 | 3 | export function useRefState(initialValue: S) { 4 | const [state, setState] = useState(initialValue) 5 | const stateRef = useRefEffect(state) 6 | 7 | return [state, stateRef, setState] as [ 8 | S, 9 | React.MutableRefObject, 10 | React.Dispatch> 11 | ] 12 | } 13 | 14 | export function useRefEffect(value: S) { 15 | const valueRef = useRef(value) 16 | 17 | useEffect(() => { 18 | valueRef.current = value 19 | }, [value]) 20 | 21 | return valueRef 22 | } 23 | 24 | export function useCommittedRef(value: T): React.MutableRefObject { 25 | const ref = useRef(value) 26 | useEffect(() => { 27 | ref.current = value 28 | }, [value]) 29 | return ref 30 | } 31 | -------------------------------------------------------------------------------- /src/cloud/lib/href.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/src/cloud/lib/href.ts -------------------------------------------------------------------------------- /src/cloud/lib/i18n/index.ts: -------------------------------------------------------------------------------- 1 | import i18n from 'i18next' 2 | import { initReactI18next } from 'react-i18next' 3 | import enUS from './enUS' 4 | import fr from './fr' 5 | import ja from './ja' 6 | import zhCN from './zhCN' 7 | 8 | const resources = { 9 | 'en-US': enUS, 10 | fr: fr, 11 | ja: ja, 12 | kr: enUS, 13 | 'zh-CN': zhCN, 14 | } 15 | 16 | i18n 17 | .use(initReactI18next) // passes i18n down to react-i18next 18 | .init({ 19 | resources, 20 | lng: 'en-US', 21 | fallbackLng: 'en-US', 22 | keySeparator: false, // we do not use keys in form messages.welcome 23 | interpolation: { 24 | escapeValue: false, // react already safes from xss 25 | }, 26 | }) 27 | 28 | export default i18n 29 | -------------------------------------------------------------------------------- /src/cloud/lib/localStorageKeys.ts: -------------------------------------------------------------------------------- 1 | export const preferencesKey = 'boosthub:preferences' 2 | export const searchKey = 'boosthub:search' 3 | export const searchHistoryKey = 'boosthub:search:history' 4 | export const sidebarCollapseKey = 'boosthub:sidebar' 5 | export const mobilePreferencesKey = 'boosthub:mobile:preferences' 6 | export const teamStorageKey = 'boosthub:teamPreferences' 7 | export const teamPreferenceskey = 'boosthub:team:preferences' 8 | -------------------------------------------------------------------------------- /src/cloud/lib/mouse.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react' 2 | 3 | export const useGlobalMouseMoveHandler = ( 4 | handler: (event: MouseEvent) => void 5 | ) => { 6 | return useEffect(() => { 7 | window.addEventListener('mousemove', handler) 8 | return () => { 9 | window.removeEventListener('mousemove', handler) 10 | } 11 | }, [handler]) 12 | } 13 | -------------------------------------------------------------------------------- /src/cloud/lib/realtime/client/constructor.ts: -------------------------------------------------------------------------------- 1 | export function makeConstructor( 2 | multiplex: (token: string) => WebSocket 3 | ): typeof WebSocket { 4 | return function (url = '') { 5 | const token = url.split('/')[1] 6 | return multiplex(token) 7 | } as any 8 | } 9 | -------------------------------------------------------------------------------- /src/cloud/lib/realtime/client/index.ts: -------------------------------------------------------------------------------- 1 | export { MultiplexConnection } from './multiplexConnection' 2 | export { makeConstructor } from './constructor' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/realtime/lib/functional.ts: -------------------------------------------------------------------------------- 1 | export function pipe( 2 | fn1: (...args: T) => R, 3 | ...fns: Array<(a: R) => R> 4 | ) { 5 | const piped = fns.reduce( 6 | (prevFn, nextFn) => (value: R) => nextFn(prevFn(value)), 7 | (value) => value 8 | ) 9 | return (...args: T) => piped(fn1(...args)) 10 | } 11 | 12 | export function prop(key: K) { 13 | return (obj: U): U[K] => { 14 | return obj[key] 15 | } 16 | } 17 | 18 | export function eq(x: any) { 19 | return (y: any) => x === y 20 | } 21 | 22 | export function unity(x: T) { 23 | return x 24 | } 25 | -------------------------------------------------------------------------------- /src/cloud/lib/realtime/protocol/version.ts: -------------------------------------------------------------------------------- 1 | export const V1 = 'io.boostnote.realtime.v1' 2 | export const LATEST = V1 3 | -------------------------------------------------------------------------------- /src/cloud/lib/rehypeGutters.ts: -------------------------------------------------------------------------------- 1 | import { Node } from 'unist' 2 | 3 | function rehypeGutters(contentFactory: (node: Node) => Node | null) { 4 | return (tree: Node) => { 5 | tree.children = (tree.children as Node[]).map((node) => { 6 | const content = contentFactory(node) 7 | if (content == null) { 8 | return node 9 | } 10 | return { 11 | type: 'element', 12 | tagName: 'div', 13 | properties: { 14 | class: 'with__gutter', 15 | }, 16 | children: [ 17 | node, 18 | { 19 | type: 'element', 20 | tagName: 'div', 21 | children: [content], 22 | properties: { class: 'block__gutter', position: node.position }, 23 | }, 24 | ], 25 | } 26 | }) 27 | } 28 | } 29 | 30 | export default rehypeGutters 31 | -------------------------------------------------------------------------------- /src/cloud/lib/rehypePosition.ts: -------------------------------------------------------------------------------- 1 | import unified from 'unified' 2 | import visit from 'unist-util-visit' 3 | 4 | export const rehypePosition: unified.Plugin = function () { 5 | return (tree) => { 6 | visit(tree, 'element', (node) => { 7 | if (node.position != null) { 8 | if (node.properties == null) { 9 | node.properties = {} 10 | } 11 | ;(node.properties as any)['data-line'] = node.position.start.line 12 | if (node.position.start.offset != null) { 13 | ;(node.properties as any)['data-offset'] = node.position.start.offset 14 | } 15 | } 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/cloud/lib/shortcode/index.ts: -------------------------------------------------------------------------------- 1 | import { Node } from 'unist' 2 | 3 | export function shortcodeRehypeHandler(h: Function, node: Node) { 4 | const attrs = typeof node.attributes === 'object' ? node.attributes : {} 5 | return h(node.position, 'shortcode', { 6 | identifier: node.identifier, 7 | entityId: (attrs as any).id, 8 | ...attrs, 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /src/cloud/lib/sidebar.ts: -------------------------------------------------------------------------------- 1 | export const cloudSidebaCategoryLabels = [ 2 | 'Bookmarks', 3 | 'Smart Folders', 4 | 'Folders', 5 | 'Private', 6 | 'Labels', 7 | 'More', 8 | 'Status', 9 | 'Beta', 10 | ] 11 | 12 | export const cloudSidebarOrderedCategoriesDelimiter = '|' 13 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/apiTokens/index.ts: -------------------------------------------------------------------------------- 1 | import { createStoreContext } from '../../utils/context' 2 | import { useApiTokensStore } from './store' 3 | 4 | export const { StoreProvider: ApiTokensProvider, useStore: useApiTokens } = 5 | createStoreContext(useApiTokensStore, 'API Tokens') 6 | 7 | export { default as withApiTokens } from './withApiTokens' 8 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/apiTokens/withApiTokens.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ApiTokensProvider } from '.' 3 | 4 | function withApiTokens( 5 | Component: React.ComponentType 6 | ): React.ComponentType { 7 | return (props: React.PropsWithChildren) => { 8 | return ( 9 | 10 | 11 | 12 | ) 13 | } 14 | } 15 | 16 | export default withApiTokens 17 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/beta/index.ts: -------------------------------------------------------------------------------- 1 | import { createStoreContext } from '../../utils/context' 2 | import { useBetaRegistrationStore } from './store' 3 | 4 | export const { 5 | StoreProvider: BetaRegistrationProvider, 6 | useStore: useBetaRegistration, 7 | } = createStoreContext(useBetaRegistrationStore, 'Beta Registration') 8 | 9 | export { default as withBetaRegistration } from './withBetaRegistration' 10 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/beta/withBetaRegistration.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { BetaRegistrationProvider } from '.' 3 | 4 | function withBetaRegistration( 5 | Component: React.ComponentType 6 | ): React.ComponentType { 7 | return (props: React.PropsWithChildren) => { 8 | return ( 9 | 10 | 11 | 12 | ) 13 | } 14 | } 15 | 16 | export default withBetaRegistration 17 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/comments/helpers.ts: -------------------------------------------------------------------------------- 1 | import { useComments } from '.' 2 | import { useState, useEffect } from 'react' 3 | import { Thread, Comment } from '../../../interfaces/db/comments' 4 | 5 | export function useDocThreads(docId: string) { 6 | const { observeDocThreads } = useComments() 7 | const [threads, setThreads] = useState(null) 8 | 9 | useEffect(() => { 10 | return observeDocThreads(docId, setThreads) 11 | }, [observeDocThreads, docId]) 12 | 13 | return threads 14 | } 15 | 16 | export function useThreadComments(thread: Thread) { 17 | const { observeComments: observeThread } = useComments() 18 | const [comments, setComments] = useState(null) 19 | 20 | useEffect(() => { 21 | return observeThread(thread, setComments) 22 | }, [observeThread, thread]) 23 | 24 | return comments 25 | } 26 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/loaders/index.ts: -------------------------------------------------------------------------------- 1 | import { createStoreContext } from '../../utils/context' 2 | import { useLoaderStore } from './store' 3 | 4 | export const { StoreProvider: LoaderPropsProvider, useStore: useLoaderProps } = 5 | createStoreContext(useLoaderStore, 'Loader props') 6 | 7 | export { default as withLoaderProps } from './withLoaderProps' 8 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/loaders/store.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react' 2 | import { selectV2Theme } from '../../../../design/lib/styled/styleFunctions' 3 | import { useSettings } from '../settings' 4 | 5 | export function useLoaderStore(): { 6 | backgroundColor: string 7 | foregroundColor: string 8 | speed: number 9 | rx: number 10 | ry: number 11 | } { 12 | const { settings } = useSettings() 13 | 14 | const colors = useMemo(() => { 15 | const theme = selectV2Theme(settings['general.theme'] || 'dark') 16 | 17 | return { 18 | backgroundColor: theme.colors.background.tertiary, 19 | foregroundColor: theme.colors.text.subtle, 20 | } 21 | }, [settings]) 22 | 23 | return { 24 | backgroundColor: colors.backgroundColor, 25 | foregroundColor: colors.foregroundColor, 26 | speed: 6, 27 | rx: 6, 28 | ry: 6, 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/loaders/withLoaderProps.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { LoaderPropsProvider } from '.' 3 | 4 | function withLoaderProps( 5 | Component: React.ComponentType 6 | ): React.ComponentType { 7 | return (props: React.PropsWithChildren) => { 8 | return ( 9 | 10 | 11 | 12 | ) 13 | } 14 | } 15 | 16 | export default withLoaderProps 17 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/nav/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/onboarding/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/onboarding/types.ts: -------------------------------------------------------------------------------- 1 | import { UserOnboardingState } from '../../../interfaces/db/user' 2 | 3 | export interface OnboardingContext { 4 | currentOnboardingState?: UserOnboardingState 5 | setOnboarding: (val: Partial) => void 6 | } 7 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/openInvites/index.ts: -------------------------------------------------------------------------------- 1 | import { createStoreContext } from '../../utils/context' 2 | import { useOpenInvitesStore } from './store' 3 | 4 | export const { StoreProvider: OpenInvitesProvider, useStore: useOpenInvites } = 5 | createStoreContext(useOpenInvitesStore, 'Beta Registration') 6 | 7 | export { default as withOpenInvites } from './withOpenInvites' 8 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/openInvites/withOpenInvites.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { OpenInvitesProvider } from '.' 3 | 4 | function withOpenInvites( 5 | Component: React.ComponentType 6 | ): React.ComponentType { 7 | return (props: React.PropsWithChildren) => { 8 | return ( 9 | 10 | 11 | 12 | ) 13 | } 14 | } 15 | 16 | export default withOpenInvites 17 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/pageStore/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/preferences/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/preferences/types.ts: -------------------------------------------------------------------------------- 1 | import { SidebarState } from '../../../../design/lib/sidebar' 2 | import { SidebarTreeSortingOrder } from '../../../../design/lib/sidebar' 3 | import { DocStatus } from '../../../interfaces/db/doc' 4 | 5 | export type LayoutMode = 'split' | 'preview' | 'editor' 6 | 7 | export interface Preferences { 8 | docContextMode: 'hidden' | 'comment' 9 | sidebarIsHidden: boolean 10 | sidebarIsHovered: boolean 11 | sideBarWidth: number 12 | lastEditorMode: 'edit' | 'preview' 13 | lastEditorEditLayout: LayoutMode 14 | workspaceManagerIsOpen: boolean 15 | lastSidebarState: SidebarState | undefined 16 | sidebarTreeSortingOrder: SidebarTreeSortingOrder 17 | sidebarOrderedCategories: string 18 | folderSortingOrder: 'Latest Updated' | 'Title A-Z' | 'Title Z-A' 19 | version?: number 20 | docStatusDisplayed: DocStatus[] 21 | docPropertiesAreHidden: boolean 22 | } 23 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/search/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/search/types.ts: -------------------------------------------------------------------------------- 1 | import { Dispatch, SetStateAction } from 'react' 2 | import { HistoryItem } from '../../../api/search' 3 | 4 | export interface SearchContext { 5 | showSearchScreen: boolean 6 | setShowSearchScreen: Dispatch> 7 | history: HistoryItem[] 8 | searchHistory: string[] 9 | addToSearchHistory: (val: string) => void 10 | } 11 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/serviceConnections/index.ts: -------------------------------------------------------------------------------- 1 | import { createStoreContext } from '../../utils/context' 2 | import { useServiceConnectionsStore } from './store' 3 | 4 | export const { 5 | StoreProvider: ServiceConnectionProvider, 6 | useStore: useServiceConnections, 7 | } = createStoreContext(useServiceConnectionsStore, 'Service Connections') 8 | 9 | export { default as withServiceConnections } from './withServiceConnections' 10 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/serviceConnections/withServiceConnections.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ServiceConnectionProvider } from '.' 3 | 4 | function withServiceConnections( 5 | Component: React.ComponentType 6 | ): React.ComponentType { 7 | return (props: React.PropsWithChildren) => { 8 | return ( 9 | 10 | 11 | 12 | ) 13 | } 14 | } 15 | 16 | export default withServiceConnections 17 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/settings/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/sidebarCollapse/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/sidebarCollapse/types.ts: -------------------------------------------------------------------------------- 1 | export type CollapsableType = 'folders' | 'workspaces' | 'links' | 'blocks' 2 | export type CollapsableContent = { 3 | [type in CollapsableType]: string[] 4 | } 5 | export type LocallyStoredSidebarCollapse = { 6 | [teamId: string]: CollapsableContent 7 | } 8 | 9 | export interface SidebarCollapseContext { 10 | sideBarOpenedFolderIdsSet: Set 11 | sideBarOpenedWorkspaceIdsSet: Set 12 | sideBarOpenedLinksIdsSet: Set 13 | sideBarOpenedBlocksIdsSet: Set 14 | setToLocalStorage: (teamId: string, content: CollapsableContent) => void 15 | toggleItem: (type: CollapsableType, id: string) => void 16 | foldItem: (type: CollapsableType, id: string) => void 17 | unfoldItem: (type: CollapsableType, id: string) => void 18 | } 19 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/teamPreferences/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/teamPreferences/types.ts: -------------------------------------------------------------------------------- 1 | export type TeamPreferencesType = 'hide-onboarding-invite' 2 | export type TeamPreferencesContent = { 3 | [type in TeamPreferencesType]?: boolean 4 | } 5 | export type LocallyStoredTeamPreferences = { 6 | [teamId: string]: TeamPreferencesContent 7 | } 8 | 9 | export interface TeamPreferencesContext { 10 | teamPreferences: TeamPreferencesContent 11 | setToLocalStorage: (teamId: string, content: TeamPreferencesContent) => void 12 | toggleItem: (type: TeamPreferencesType) => void 13 | } 14 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/teamStorage/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/cloud/lib/stores/teamStorage/types.ts: -------------------------------------------------------------------------------- 1 | export type TeamStorage = { 2 | showTrialAlert?: boolean 3 | hideFreePlanLimitReachedAlert?: boolean 4 | } 5 | export type LocallyStoredTeamPreferences = { 6 | [teamId: string]: TeamStorage 7 | } 8 | 9 | export interface TeamStorageContext { 10 | teamPreferences: TeamStorage 11 | setToLocalStorage: (teamId: string, content: TeamStorage) => void 12 | } 13 | -------------------------------------------------------------------------------- /src/cloud/lib/upload.ts: -------------------------------------------------------------------------------- 1 | export const allowedUploadSizeInMb = 5 2 | export const nginxSizeLimitInMb = 248 3 | -------------------------------------------------------------------------------- /src/cloud/lib/utils/admin.ts: -------------------------------------------------------------------------------- 1 | export function getAdminAnalyticsStatsPropertyFromIndex(index: number) { 2 | switch (index) { 3 | case 0: 4 | return 'newUsers' 5 | case 1: 6 | return 'deletedUsers' 7 | case 2: 8 | return 'newTeams' 9 | case 3: 10 | return 'deletedTeams' 11 | case 4: 12 | return 'newTeamInvites' 13 | case 5: 14 | return 'deletedTeamInvites' 15 | case 6: 16 | return 'newSubs' 17 | case 7: 18 | return 'deletedSubs' 19 | case 8: 20 | return 'newDocs' 21 | case 9: 22 | return 'deletedDocs' 23 | case 10: 24 | return 'newFolders' 25 | case 11: 26 | return 'deletedFolders' 27 | case 12: 28 | return 'newPersonalTeams' 29 | default: 30 | return 'misc' 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/cloud/lib/utils/bytes.ts: -------------------------------------------------------------------------------- 1 | export function bytesToGigaBytes(n: number) { 2 | return roundUpSecondDecimal(n / Math.pow(1024, 3)) 3 | } 4 | 5 | export function bytesToMegaBytes(n: number) { 6 | return roundUpSecondDecimal(n / Math.pow(1024, 2)) 7 | } 8 | 9 | export function gigaBytesToMegaBytes(n: number) { 10 | return roundUpSecondDecimal(n * 1024) 11 | } 12 | 13 | function roundUpSecondDecimal(n: number) { 14 | return Math.round(n * 100 + Number.EPSILON) / 100 15 | } 16 | -------------------------------------------------------------------------------- /src/cloud/lib/utils/iterator.ts: -------------------------------------------------------------------------------- 1 | export function filterIter( 2 | predicate: (value: T) => boolean, 3 | iter: Iterable 4 | ) { 5 | const result = [] 6 | for (const item of iter) { 7 | if (predicate(item)) { 8 | result.push(item) 9 | } 10 | } 11 | return result 12 | } 13 | 14 | export function mapIter(map: (value: T) => U, iter: Iterable): U[] { 15 | const result = [] 16 | for (const item of iter) { 17 | result.push(map(item)) 18 | } 19 | return result 20 | } 21 | -------------------------------------------------------------------------------- /src/cloud/lib/utils/map.ts: -------------------------------------------------------------------------------- 1 | export function getMapEntries(map: Map): [string, T][] { 2 | return [...map.entries()] 3 | } 4 | -------------------------------------------------------------------------------- /src/cloud/lib/utils/object.ts: -------------------------------------------------------------------------------- 1 | export function flattenObj(obj: Record): Record { 2 | const result: any = {} 3 | for (const key in obj) { 4 | if (isRecord(obj[key])) { 5 | const flattened = flattenObj(obj[key]) 6 | for (const childKey in flattened) { 7 | result[`${key}.${childKey}`] = flattened[childKey] 8 | } 9 | } else { 10 | result[key] = obj[key] 11 | } 12 | } 13 | return result 14 | } 15 | 16 | export function isRecord(x: unknown): x is Record { 17 | return x != null && typeof x === 'object' && !Array.isArray(x) 18 | } 19 | -------------------------------------------------------------------------------- /src/cloud/lib/utils/secret.ts: -------------------------------------------------------------------------------- 1 | import { randomBytes } from 'crypto' 2 | 3 | export const generateSecret = () => randomBytes(32).toString('hex') 4 | -------------------------------------------------------------------------------- /src/cloud/lib/utils/url.ts: -------------------------------------------------------------------------------- 1 | export function parseURL(url: string) { 2 | try { 3 | return new URL(url) 4 | } catch { 5 | return null 6 | } 7 | } 8 | 9 | export function appendQueryParams(params: Record, url: URL) { 10 | const clone = new URL(url.toString()) 11 | for (const [key, value] of Object.entries(params)) { 12 | clone.searchParams.set(key, value) 13 | } 14 | return clone 15 | } 16 | -------------------------------------------------------------------------------- /src/cloud/pages/[teamId]/dashboard.tsx: -------------------------------------------------------------------------------- 1 | import DashboardPage from '../../components/DashboardPage' 2 | 3 | export default DashboardPage 4 | -------------------------------------------------------------------------------- /src/cloud/pages/[teamId]/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { GetInitialPropsParameters } from '../../interfaces/pages' 3 | import WorkspacePage from '../../components/WorkspacePage' 4 | import { getTeamIndexPageData } from '../../api/pages/teams' 5 | 6 | const TeamIndexPage = ({ pageWorkspace }: any) => { 7 | return 8 | } 9 | 10 | TeamIndexPage.getInitialProps = async (params: GetInitialPropsParameters) => { 11 | const result = await getTeamIndexPageData(params) 12 | return result 13 | } 14 | 15 | export default TeamIndexPage 16 | -------------------------------------------------------------------------------- /src/cloud/pages/_error.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | interface ErrorInitialProps { 4 | res: any 5 | err: any 6 | } 7 | 8 | const Error = () => { 9 | return <> 10 | } 11 | 12 | Error.getInitialProps = ({ res, err }: ErrorInitialProps) => { 13 | const statusCode = res ? res.statusCode : err ? err.statusCode : 404 14 | const message = 15 | statusCode === 404 16 | ? 'The page could not be found.' 17 | : res 18 | ? res.message 19 | : err 20 | ? err.message 21 | : 'Error' 22 | return { error: { statusCode, message } } 23 | } 24 | 25 | export default Error 26 | -------------------------------------------------------------------------------- /src/cloud/pages/home/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useGlobalData } from '../../lib/stores/globalData' 3 | import HomeForm from './HomeForm' 4 | import HomePageSignInForm from './HomePageSignInForm' 5 | 6 | const HomePage = () => { 7 | const { 8 | globalData: { currentUser, teams }, 9 | } = useGlobalData() 10 | if (currentUser) { 11 | return 12 | } 13 | 14 | return 15 | } 16 | 17 | HomePage.getInitialProps = async () => { 18 | return {} 19 | } 20 | 21 | export default HomePage 22 | -------------------------------------------------------------------------------- /src/components/atoms/ProgressBar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../design/lib/styled' 3 | 4 | interface ProgressBarProps { 5 | progress: number 6 | className?: string 7 | } 8 | 9 | const ProgressBar = ({ progress, className }: ProgressBarProps) => { 10 | return 11 | } 12 | 13 | const ProgressBarStyled = styled.div` 14 | border: 2px solid ${({ theme }) => theme.colors.border.main}; 15 | height: 30px; 16 | position: relative; 17 | width: 100%; 18 | margin: 30px 0; 19 | 20 | &:after { 21 | content: ''; 22 | transition: width 0.5s linear; 23 | position: absolute; 24 | top: 0; 25 | height: 100%; 26 | background-color: ${({ theme }) => theme.colors.variants.primary.base}; 27 | width: ${({ progress }) => progress}%; 28 | } 29 | ` 30 | 31 | export default ProgressBar 32 | -------------------------------------------------------------------------------- /src/design/components/atoms/AspectRation.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../lib/styled' 3 | 4 | interface AspectRationProps { 5 | height: number 6 | width: number 7 | } 8 | 9 | const AspectRatio = ({ 10 | height, 11 | width, 12 | children, 13 | }: React.PropsWithChildren) => { 14 | return ( 15 | 16 |
{children}
17 |
18 | ) 19 | } 20 | 21 | const Container = styled.div` 22 | width: 100%; 23 | position: relative; 24 | 25 | & > div { 26 | position: absolute; 27 | top: 0; 28 | left: 0; 29 | height: 100%; 30 | width: 100%; 31 | } 32 | ` 33 | 34 | export default AspectRatio 35 | -------------------------------------------------------------------------------- /src/design/components/atoms/BorderSeparator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../lib/styled' 3 | import cc from 'classcat' 4 | 5 | interface BorderSeparatorProps { 6 | variant?: 'main' | 'second' 7 | } 8 | 9 | const BorderSeparator = ({ variant = 'main' }: BorderSeparatorProps) => ( 10 | 13 | ) 14 | 15 | const Container = styled.div` 16 | height: 1px; 17 | margin: 10px 0; 18 | width: 100%; 19 | 20 | &.border__separator--main { 21 | background-color: ${({ theme }) => theme.colors.border.main}; 22 | } 23 | 24 | &.border__separator--second { 25 | background-color: ${({ theme }) => theme.colors.border.second}; 26 | } 27 | ` 28 | 29 | export default BorderSeparator 30 | -------------------------------------------------------------------------------- /src/design/components/atoms/EllipsisText.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import cc from 'classcat' 3 | import styled from '../../lib/styled' 4 | import { overflowEllipsis } from '../../lib/styled/styleFunctions' 5 | import { AppComponent } from '../../lib/types' 6 | 7 | const EllipsisText: AppComponent<{}> = ({ children, className }) => { 8 | return {children} 9 | } 10 | 11 | const Container = styled.span` 12 | ${overflowEllipsis()} 13 | ` 14 | 15 | export default EllipsisText 16 | -------------------------------------------------------------------------------- /src/design/components/atoms/Image.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties } from 'react' 2 | import isElectron from 'is-electron' 3 | 4 | interface ImageProps { 5 | src: string 6 | className?: string 7 | style?: CSSProperties 8 | alt?: string 9 | } 10 | 11 | const Image = ({ src, className, style, alt }: ImageProps) => { 12 | if (isElectron() && src.startsWith('/app')) { 13 | src = src.slice(1) 14 | } 15 | 16 | return {alt} 17 | } 18 | 19 | export default Image 20 | -------------------------------------------------------------------------------- /src/design/components/atoms/Label.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../lib/styled' 3 | 4 | export const Label = ({ 5 | name, 6 | backgroundColor, 7 | }: { 8 | name: string 9 | backgroundColor?: string 10 | }) => { 11 | return {name} 12 | } 13 | 14 | const StyledLabel = styled.span` 15 | display: inline-block; 16 | padding: 0.25em 0.5em; 17 | border-radius: 4px; 18 | color: white; 19 | background-color: #353940; 20 | ` 21 | -------------------------------------------------------------------------------- /src/design/components/atoms/PageHelmet.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | 4 | interface PageHelmetProps { 5 | title?: string 6 | indexing?: boolean 7 | } 8 | 9 | const PageHelmet: React.FC = ({ 10 | title = 'Boost Note', 11 | indexing, 12 | }) => ( 13 | 14 | {title} 15 | 16 | {!indexing && } 17 | 18 | ) 19 | 20 | export default PageHelmet 21 | -------------------------------------------------------------------------------- /src/design/components/atoms/Portal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | export interface PortalProps { 5 | domTarget: Element | null 6 | } 7 | 8 | const Portal: React.FC = ({ domTarget, children }) => { 9 | if (domTarget == null) { 10 | return null 11 | } 12 | 13 | return ReactDOM.createPortal(children, domTarget) 14 | } 15 | 16 | export default Portal 17 | -------------------------------------------------------------------------------- /src/design/components/atoms/WithPastille.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../lib/styled' 3 | 4 | export const WithPastille = ({ children }: React.PropsWithChildren<{}>) => ( 5 | {children} 6 | ) 7 | 8 | export default WithPastille 9 | 10 | const Container = styled.div` 11 | position: relative; 12 | &:after { 13 | position: absolute; 14 | content: ''; 15 | width: 12px; 16 | height: 12px; 17 | background-color: #cd4400; 18 | top: 1px; 19 | right: -2px; 20 | border-radius: 50%; 21 | transform: translate3d(25%, -25%, 0); 22 | } 23 | ` 24 | -------------------------------------------------------------------------------- /src/design/components/atoms/loaders/LoaderDocEditor.tsx: -------------------------------------------------------------------------------- 1 | import ContentLoader from 'react-content-loader' 2 | import React from 'react' 3 | import { generate } from 'shortid' 4 | import { 5 | useLoaderProps, 6 | withLoaderProps, 7 | } from '../../../../cloud/lib/stores/loaders' 8 | 9 | const DocEditorLoader = () => { 10 | const { backgroundColor, foregroundColor, speed, rx, ry } = useLoaderProps() 11 | return ( 12 | 20 | 21 | 22 | 23 | ) 24 | } 25 | 26 | export default withLoaderProps(DocEditorLoader) 27 | -------------------------------------------------------------------------------- /src/design/components/atoms/loaders/LoaderFolderPage.tsx: -------------------------------------------------------------------------------- 1 | import ContentLoader from 'react-content-loader' 2 | import React from 'react' 3 | import { generate } from 'shortid' 4 | import { 5 | withLoaderProps, 6 | useLoaderProps, 7 | } from '../../../../cloud/lib/stores/loaders' 8 | 9 | const LoaderFolderPage = () => { 10 | const { backgroundColor, foregroundColor, speed, rx, ry } = useLoaderProps() 11 | return ( 12 | 20 | 21 | 22 | 23 | ) 24 | } 25 | 26 | export default withLoaderProps(LoaderFolderPage) 27 | -------------------------------------------------------------------------------- /src/design/components/atoms/loaders/LoaderSmartView.tsx: -------------------------------------------------------------------------------- 1 | import ContentLoader from 'react-content-loader' 2 | import React from 'react' 3 | import { generate } from 'shortid' 4 | import { 5 | withLoaderProps, 6 | useLoaderProps, 7 | } from '../../../../cloud/lib/stores/loaders' 8 | 9 | const LoaderSmartView = () => { 10 | const { backgroundColor, foregroundColor, speed, rx, ry } = useLoaderProps() 11 | return ( 12 | 20 | 21 | 22 | 23 | ) 24 | } 25 | 26 | export default withLoaderProps(LoaderSmartView) 27 | -------------------------------------------------------------------------------- /src/design/components/atoms/loaders/LoaderTeamPicker.tsx: -------------------------------------------------------------------------------- 1 | import ContentLoader from 'react-content-loader' 2 | import React from 'react' 3 | import { generate } from 'shortid' 4 | import { 5 | withLoaderProps, 6 | useLoaderProps, 7 | } from '../../../../cloud/lib/stores/loaders' 8 | 9 | const LoaderTeamPicker = () => { 10 | const { backgroundColor, foregroundColor, speed, rx, ry } = useLoaderProps() 11 | return ( 12 | 20 | 21 | 22 | 23 | ) 24 | } 25 | 26 | export default withLoaderProps(LoaderTeamPicker) 27 | -------------------------------------------------------------------------------- /src/design/components/molecules/Form/atoms/FormDatePicker.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDatePicker, { ReactDatePickerProps } from 'react-datepicker' 3 | import FormInput from './FormInput' 4 | 5 | export type FormDatePickerProps = ReactDatePickerProps 6 | 7 | const FormDatePicker = React.forwardRef( 8 | ({ className, id, onChange, ...datePickerProps }, ref) => { 9 | return ( 10 | 21 | } 22 | /> 23 | ) 24 | } 25 | ) 26 | 27 | export default FormDatePicker 28 | -------------------------------------------------------------------------------- /src/design/components/molecules/Image/ImagePreview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../../lib/styled' 3 | import Image from '../../atoms/Image' 4 | 5 | interface ImagePreviewProps { 6 | src: string 7 | } 8 | 9 | const ImagePreview = ({ src }: ImagePreviewProps) => { 10 | return ( 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | const Container = styled.div` 18 | padding: 20px 25px; 19 | display: flex; 20 | justify-content: center; 21 | align-items: center; 22 | .image__preview_width { 23 | max-width: 100%; 24 | } 25 | ` 26 | 27 | export default ImagePreview 28 | -------------------------------------------------------------------------------- /src/design/components/organisms/Dialog/atoms/DialogIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { DialogIconTypes } from '../../../../lib/stores/dialog' 3 | import cc from 'classcat' 4 | 5 | type DialogIconProps = { 6 | icon: DialogIconTypes 7 | className?: string 8 | } 9 | 10 | const DialogIcon = ({ className, icon }: DialogIconProps) => ( 11 |
{getEmoji(icon)}
12 | ) 13 | 14 | export default DialogIcon 15 | 16 | function getEmoji(icon: DialogIconTypes): string { 17 | switch (icon) { 18 | case DialogIconTypes.Question: 19 | return '❓' 20 | case DialogIconTypes.Warning: 21 | default: 22 | return '⚠️' 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/design/components/organisms/MetadataContainer/atoms/MetadataContainerBreak.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from '../../../../lib/styled' 3 | 4 | const MetadataContainerBreak = () => 5 | 6 | const Container = styled.div` 7 | &.metadata__break { 8 | display: block; 9 | height: 1px; 10 | margin: 0px ${({ theme }) => theme.sizes.spaces.sm}px; 11 | background-color: ${({ theme }) => theme.colors.background.quaternary}; 12 | } 13 | ` 14 | 15 | export default MetadataContainerBreak 16 | -------------------------------------------------------------------------------- /src/design/components/organisms/Table/index.tsx: -------------------------------------------------------------------------------- 1 | import Table from './Table' 2 | 3 | export default Table 4 | -------------------------------------------------------------------------------- /src/design/components/templates/ErrorLayout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ContentLayout from './ContentLayout' 3 | 4 | interface ErrorLayoutProps { 5 | message: string 6 | } 7 | 8 | const ErrorLayout = ({ message }: ErrorLayoutProps) => ( 9 | {message} 10 | ) 11 | 12 | export default ErrorLayout 13 | -------------------------------------------------------------------------------- /src/design/lib/dnd.ts: -------------------------------------------------------------------------------- 1 | import { DragEvent } from 'react' 2 | 3 | export enum DraggedTo { 4 | insideFolder = 0, 5 | beforeItem = -1, 6 | afterItem = 1, 7 | } 8 | 9 | export type SidebarDragState = undefined | DraggedTo 10 | 11 | export const onDragLeaveCb = ( 12 | event: DragEvent, 13 | dropzone: React.RefObject, 14 | cb: () => void 15 | ) => { 16 | event.preventDefault() 17 | event.stopPropagation() 18 | const relatedTarget = event.relatedTarget 19 | let ignoreCb = false 20 | if ( 21 | relatedTarget != null && 22 | dropzone.current != null && 23 | relatedTarget instanceof Node && 24 | dropzone.current.isSameNode(relatedTarget) 25 | ) { 26 | ignoreCb = true 27 | } 28 | 29 | if (!ignoreCb) { 30 | cb() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/design/lib/mappers/topbarControls.ts: -------------------------------------------------------------------------------- 1 | import { mdiChevronLeft, mdiChevronRight } from '@mdi/js' 2 | import { ControlButtonProps } from '../types' 3 | 4 | // Map void 8 | ) { 9 | const controls: ControlButtonProps[] = [] 10 | controls.push({ 11 | icon: hideMetadata ? mdiChevronLeft : mdiChevronRight, 12 | onClick: toggleHideMetadata, 13 | }) 14 | return controls 15 | } 16 | -------------------------------------------------------------------------------- /src/design/lib/mappers/types.ts: -------------------------------------------------------------------------------- 1 | export interface BreadCrumbTreeItem { 2 | id: string 3 | parentId?: string 4 | label: string 5 | defaultIcon?: string 6 | emoji?: string 7 | active?: boolean 8 | link: { 9 | href: string 10 | navigateTo: () => void 11 | } 12 | } 13 | 14 | export interface ContentManagerItemProps { 15 | id: string 16 | label: string 17 | href: string 18 | category: T 19 | lastUpdated: string 20 | controls: [] 21 | lastUpdatedBy?: string[] 22 | badges?: string[] 23 | } 24 | -------------------------------------------------------------------------------- /src/design/lib/platform.ts: -------------------------------------------------------------------------------- 1 | export type OsNameOptions = 2 | | 'windows' 3 | | 'macos' 4 | | 'unix' 5 | | 'linux' 6 | | 'unknown' 7 | | 'ios' 8 | | 'android' 9 | 10 | function getOsName(): OsNameOptions { 11 | if (navigator.userAgent.indexOf('Android') != -1) return 'android' 12 | if (navigator.userAgent.indexOf('iPhone') != -1) return 'ios' 13 | if (navigator.userAgent.indexOf('Win') != -1) return 'windows' 14 | if (navigator.userAgent.indexOf('Mac') != -1) return 'macos' 15 | if (navigator.userAgent.indexOf('X11') != -1) return 'unix' 16 | if (navigator.userAgent.indexOf('Linux') != -1) return 'linux' 17 | 18 | return 'unknown' 19 | } 20 | 21 | export const osName = getOsName() 22 | -------------------------------------------------------------------------------- /src/design/lib/shortcuts.ts: -------------------------------------------------------------------------------- 1 | import { isWithGeneralCtrlKey } from './keyboard' 2 | import { isActiveElementAnInput } from './dom' 3 | 4 | /** GLOBAL **/ 5 | 6 | export function isFocusLeftSideShortcut(event: KeyboardEvent) { 7 | // cmd + shift + arrowRight 8 | return ( 9 | event.key.toLowerCase() === 'arrowleft' && 10 | event.shiftKey && 11 | isWithGeneralCtrlKey(event) && 12 | !isActiveElementAnInput() 13 | ) 14 | } 15 | export function isFocusRightSideShortcut(event: KeyboardEvent) { 16 | // cmd + shift + arrowRight 17 | return ( 18 | event.key.toLowerCase() === 'arrowright' && 19 | event.shiftKey && 20 | isWithGeneralCtrlKey(event) && 21 | !isActiveElementAnInput() 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /src/design/lib/stores/emoji/types.ts: -------------------------------------------------------------------------------- 1 | export type Position = { x: number; y: number } 2 | 3 | export interface EmojiPickerContext { 4 | callback?: (x?: string) => void 5 | closed: boolean 6 | position: Position 7 | openEmojiPicker( 8 | event: React.MouseEvent, 9 | cb: (val?: string) => void | ((val?: string) => Promise) 10 | ): void 11 | closeEmojiPicker(): void 12 | } 13 | 14 | export const EmojiPickerWidth = 350 15 | export const EmojiPickerHeight = 380 16 | -------------------------------------------------------------------------------- /src/design/lib/stores/modal/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './store' 3 | -------------------------------------------------------------------------------- /src/design/lib/stores/window/types.ts: -------------------------------------------------------------------------------- 1 | export interface WindowContext { 2 | windowSize: { width: number; height: number } 3 | } 4 | -------------------------------------------------------------------------------- /src/design/lib/string.ts: -------------------------------------------------------------------------------- 1 | export function getColorFromString(key: string) { 2 | let hash = 0 3 | for (let i = 0; i < key.length; i++) { 4 | hash = key.charCodeAt(i) + ((hash << 5) - hash) 5 | } 6 | let colour = '#' 7 | for (let i = 0; i < 3; i++) { 8 | const value = (hash >> (i * 8)) & 0xff 9 | colour += ('00' + value.toString(16)).substr(-2) 10 | } 11 | return colour 12 | } 13 | -------------------------------------------------------------------------------- /src/design/lib/styled/index.ts: -------------------------------------------------------------------------------- 1 | import styled, { ThemedBaseStyledInterface } from 'styled-components' 2 | import { BaseTheme } from './types' 3 | 4 | export default styled as unknown as ThemedBaseStyledInterface 5 | -------------------------------------------------------------------------------- /src/design/lib/types.ts: -------------------------------------------------------------------------------- 1 | export type AppComponent

= React.FC

2 | 3 | export type ControlButtonProps = { 4 | disabled?: boolean 5 | active?: boolean 6 | spinning?: boolean 7 | icon: string 8 | onClick: (event: React.MouseEvent) => void 9 | onContextMenu?: (event: React.MouseEvent) => void 10 | tooltip?: string 11 | } 12 | 13 | export type SubmissionWrappers = { 14 | beforeSubmitting?: () => void 15 | afterSubmitting?: () => void 16 | } 17 | -------------------------------------------------------------------------------- /src/design/lib/utils/tree.ts: -------------------------------------------------------------------------------- 1 | type Node = T & { children: Node[] } 2 | 3 | export function find>( 4 | node: Node, 5 | cmp: (node: Node) => boolean 6 | ): Node | null { 7 | if (cmp(node)) { 8 | return node 9 | } 10 | 11 | for (const child of node.children) { 12 | const found = find(child, cmp) 13 | if (found != null) { 14 | return found 15 | } 16 | } 17 | 18 | return null 19 | } 20 | -------------------------------------------------------------------------------- /src/electron/consts.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import url from 'url' 3 | import { app } from 'electron' 4 | 5 | export const dev = process.env.NODE_ENV !== 'production' 6 | 7 | export const electronFrontendUrl = dev 8 | ? 'http://localhost:3000/app' 9 | : url.format({ 10 | pathname: path.join(app.getAppPath(), './compiled/index.html'), 11 | protocol: 'file', 12 | slashes: true, 13 | }) 14 | -------------------------------------------------------------------------------- /src/electron/ipc.ts: -------------------------------------------------------------------------------- 1 | import { MenuItem, BrowserWindow } from 'electron' 2 | 3 | export function createEmitIpcMenuItemHandler(eventName: string) { 4 | return function (_menuItem: MenuItem, browserWindow?: BrowserWindow) { 5 | if (browserWindow == null) { 6 | console.warn( 7 | `Failed to emit \`${eventName}\` ipc event because the browser window for menu item is missing` 8 | ) 9 | return 10 | } 11 | browserWindow.webContents.send(eventName) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './components/App' 4 | import { removeCookie } from './lib/electronOnly' 5 | 6 | removeCookie(process.env.BOOST_HUB_BASE_URL!, 'desktop_access_token') 7 | 8 | function render(Component: typeof App) { 9 | let rootDiv = document.getElementById('root') 10 | if (rootDiv == null) { 11 | rootDiv = document.createElement('div', {}) 12 | rootDiv.setAttribute('id', 'root') 13 | document.body.appendChild(rootDiv) 14 | } 15 | ReactDOM.render(, document.getElementById('root')) 16 | } 17 | 18 | if (module.hot != null) { 19 | module.hot.accept('./components/App', () => { 20 | render(App) 21 | }) 22 | } 23 | render(App) 24 | -------------------------------------------------------------------------------- /src/lib/i18n.ts: -------------------------------------------------------------------------------- 1 | import i18n from 'i18next' 2 | import { initReactI18next } from 'react-i18next' 3 | import enUS from '../locales/enUS' 4 | 5 | const resources = { 6 | 'en-US': enUS, 7 | } 8 | 9 | i18n 10 | .use(initReactI18next) // passes i18n down to react-i18next 11 | .init({ 12 | resources, 13 | fallbackLng: 'en-US', 14 | 15 | keySeparator: false, // we do not use keys in form messages.welcome 16 | 17 | interpolation: { 18 | escapeValue: false, // react already safes from xss 19 | }, 20 | }) 21 | 22 | export default i18n 23 | -------------------------------------------------------------------------------- /src/lib/platform.ts: -------------------------------------------------------------------------------- 1 | import isElectron from 'is-electron' 2 | import { openExternal } from './electronOnly' 3 | export { osName } from '../design/lib/platform' 4 | 5 | export const appIsElectron = isElectron() 6 | 7 | const isInternalLink = (link: string) => link[0] === '#' 8 | 9 | const openInternalLink = (link: string) => { 10 | const extractedId = link.slice(1) 11 | const targetId = `user-content-${extractedId}` 12 | const targetElement = window.document.getElementById(targetId) 13 | if (targetElement != null) { 14 | targetElement.scrollIntoView() 15 | } 16 | } 17 | 18 | export const openNew = (url: string) => { 19 | if (url.length === 0) { 20 | return 21 | } 22 | 23 | if (isInternalLink(url)) { 24 | openInternalLink(url) 25 | return 26 | } 27 | 28 | if (appIsElectron) { 29 | openExternal(url) 30 | } else { 31 | window.open(url, '_blank') 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/lib/predicates.spec.ts: -------------------------------------------------------------------------------- 1 | import { schema } from './predicates' 2 | import ow from 'ow' 3 | 4 | describe('schema(ow predicate)', () => { 5 | it('validates object with schema', () => { 6 | const predicate = schema({ 7 | stringProp: ow.string, 8 | }) 9 | 10 | const result = ow.isValid({} as unknown, predicate) 11 | 12 | expect(result).toBe(false) 13 | }) 14 | it('validates with nested schema', () => { 15 | const predicate = schema({ 16 | parent: schema({ 17 | stringProp: ow.string, 18 | }), 19 | }) 20 | 21 | const result = ow.isValid({ parent: {} } as unknown, predicate) 22 | 23 | expect(result).toBe(false) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /src/mobile/components/MobileGlobalStyle.tsx: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components' 2 | 3 | const MobileGlobalStyle = createGlobalStyle` 4 | input[type='text'] { 5 | font-size: 16px !important; 6 | } 7 | body { 8 | overscroll-behavior: none; 9 | overflow: hidden; 10 | } 11 | ` 12 | 13 | export default MobileGlobalStyle 14 | -------------------------------------------------------------------------------- /src/mobile/components/atoms/NavigationBarBackButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { MouseEventHandler } from 'react' 2 | import NavigationBarButton from './NavigationBarButton' 3 | import Icon from '../../../design/components/atoms/Icon' 4 | import { mdiArrowLeft } from '@mdi/js' 5 | 6 | interface NavigationBarBackButtonProps { 7 | onClick: MouseEventHandler 8 | } 9 | 10 | const NavigationBarBackButton = ({ onClick }: NavigationBarBackButtonProps) => { 11 | return ( 12 | 13 | Back 14 | 15 | ) 16 | } 17 | 18 | export default NavigationBarBackButton 19 | -------------------------------------------------------------------------------- /src/mobile/components/atoms/NavigationBarButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { MouseEventHandler } from 'react' 2 | import styled from '../../../design/lib/styled' 3 | 4 | interface NavigationBarButtonProps { 5 | onClick: MouseEventHandler 6 | } 7 | 8 | const NavigationBarButton: React.FC = ({ 9 | onClick, 10 | children, 11 | }) => { 12 | return {children} 13 | } 14 | 15 | export default NavigationBarButton 16 | 17 | const Container = styled.button` 18 | height: 47px; 19 | background-color: transparent; 20 | border: none; 21 | color: ${({ theme }) => theme.colors.text.subtle}; 22 | padding: 0 ${({ theme }) => theme.sizes.spaces.sm}px; 23 | display: flex; 24 | align-items: center; 25 | font-size: ${({ theme }) => theme.sizes.fonts.md}px; 26 | ` 27 | -------------------------------------------------------------------------------- /src/mobile/components/atoms/NavigationBarIconButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { MouseEventHandler } from 'react' 2 | import styled from '../../../design/lib/styled' 3 | import Icon from '../../../design/components/atoms/Icon' 4 | 5 | interface NavigationBarIconButtonProps { 6 | onClick: MouseEventHandler 7 | iconPath: string 8 | } 9 | 10 | const NavigationBarIconButton = ({ 11 | onClick, 12 | iconPath, 13 | }: NavigationBarIconButtonProps) => { 14 | return ( 15 | 16 | 17 | 18 | ) 19 | } 20 | 21 | export default NavigationBarIconButton 22 | 23 | const Container = styled.button` 24 | height: 47px; 25 | width: 47px; 26 | background-color: transparent; 27 | border: none; 28 | color: ${({ theme }) => theme.colors.text.subtle}; 29 | font-size: ${({ theme }) => theme.sizes.fonts.md}px; 30 | ` 31 | -------------------------------------------------------------------------------- /src/mobile/components/organisms/Navigator/index.tsx: -------------------------------------------------------------------------------- 1 | import Navigator from './Navigator' 2 | 3 | export default Navigator 4 | -------------------------------------------------------------------------------- /src/mobile/components/organisms/modals/Modal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useModal } from '../../../../design/lib/stores/modal' 3 | import { usePathnameChangeEffect } from '../../../../cloud/lib/router' 4 | 5 | const Modal = () => { 6 | const { modals, closeAllModals } = useModal() 7 | usePathnameChangeEffect(closeAllModals) 8 | 9 | if (modals.length === 0) return null 10 | 11 | return ( 12 | <> 13 | {modals.map((modal, i) => ( 14 | {modal.content} 15 | ))} 16 | 17 | ) 18 | } 19 | 20 | export default Modal 21 | -------------------------------------------------------------------------------- /src/mobile/components/organisms/modals/atoms/ModalFormWrapper.tsx: -------------------------------------------------------------------------------- 1 | import styled from '../../../../../design/lib/styled' 2 | 3 | const ModalFormWrapper = styled.div` 4 | padding: ${({ theme }) => theme.sizes.spaces.md}px; 5 | ` 6 | 7 | export default ModalFormWrapper 8 | -------------------------------------------------------------------------------- /src/mobile/components/organisms/modals/types.ts: -------------------------------------------------------------------------------- 1 | export type SettingsTabTypes = 2 | | 'account-settings' 3 | | 'space-settings' 4 | | 'space-members' 5 | | 'space-upgrade' 6 | | 'space-upgrade-confirm-free' 7 | | 'space-upgrade-confirm-standard' 8 | | 'space-upgrade-confirm-pro' 9 | | 'space-billings' 10 | -------------------------------------------------------------------------------- /src/mobile/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './components/App' 4 | import '../cloud/lib/i18n' 5 | 6 | function render(Component: typeof App) { 7 | let rootDiv = document.getElementById('root') 8 | if (rootDiv == null) { 9 | rootDiv = document.createElement('div', {}) 10 | rootDiv.setAttribute('id', 'root') 11 | document.body.appendChild(rootDiv) 12 | } 13 | ReactDOM.render(, document.getElementById('root')) 14 | } 15 | 16 | if (module.hot != null) { 17 | module.hot.accept('./components/App', () => { 18 | render(App) 19 | }) 20 | } 21 | render(App) 22 | -------------------------------------------------------------------------------- /src/mobile/lib/appStatus.ts: -------------------------------------------------------------------------------- 1 | import { useState, useCallback } from 'react' 2 | import { createStoreContext } from '../../cloud/lib/utils/context' 3 | 4 | function useAppStatusStore() { 5 | const [showingNavigator, setShowingNavigator] = useState(false) 6 | 7 | const toggleShowingNavigator = useCallback(() => { 8 | setShowingNavigator((previousValue) => { 9 | return !previousValue 10 | }) 11 | }, []) 12 | 13 | return { 14 | showingNavigator, 15 | setShowingNavigator, 16 | toggleShowingNavigator, 17 | } 18 | } 19 | 20 | export const { StoreProvider: AppStatusProvider, useStore: useAppStatus } = 21 | createStoreContext(useAppStatusStore, 'appStatus') 22 | -------------------------------------------------------------------------------- /src/mobile/lib/sidebar/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/src/mobile/lib/sidebar/types.ts -------------------------------------------------------------------------------- /src/mobile/lib/signOut.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react' 2 | import { boostHubBaseUrl, mobileBaseUrl } from '../../cloud/lib/consts' 3 | 4 | function useSignOut() { 5 | return useCallback(() => { 6 | window.location.href = `${boostHubBaseUrl}/api/user/signout?redirectTo=${mobileBaseUrl}` 7 | }, []) 8 | } 9 | 10 | export default useSignOut 11 | -------------------------------------------------------------------------------- /src/stories/Button.stories.tsx: -------------------------------------------------------------------------------- 1 | import { Meta } from '@storybook/react/types-6-0' 2 | import Button from '../design/components/atoms/Button' 3 | import { createThemedTemplate } from './utils/themes' 4 | 5 | const { Template, themeArgType } = createThemedTemplate(Button) 6 | 7 | export default { 8 | title: 'Legacy/Atoms/Button', 9 | component: Button, 10 | argTypes: { 11 | theme: themeArgType, 12 | }, 13 | } as Meta 14 | 15 | export const Primary = Template.bind({}) 16 | Primary.args = { 17 | children: 'Label', 18 | variant: 'primary', 19 | } 20 | -------------------------------------------------------------------------------- /src/stories/Index.mdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/src/stories/Index.mdx -------------------------------------------------------------------------------- /static/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/android-chrome-192x192.png -------------------------------------------------------------------------------- /static/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/android-chrome-512x512.png -------------------------------------------------------------------------------- /static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/apple-touch-icon.png -------------------------------------------------------------------------------- /static/boosthub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/boosthub.png -------------------------------------------------------------------------------- /static/boostnote-mac-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/boostnote-mac-icon.png -------------------------------------------------------------------------------- /static/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/favicon.ico -------------------------------------------------------------------------------- /static/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/icon.icns -------------------------------------------------------------------------------- /static/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/icon.ico -------------------------------------------------------------------------------- /static/img_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/img_ui.png -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/logo.png -------------------------------------------------------------------------------- /static/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/mstile-144x144.png -------------------------------------------------------------------------------- /static/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/mstile-150x150.png -------------------------------------------------------------------------------- /static/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/mstile-310x150.png -------------------------------------------------------------------------------- /static/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/mstile-310x310.png -------------------------------------------------------------------------------- /static/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BoostIO/BoostNote-App/bab4d8fed2a5d50f855fbac31873b8d3802fba09/static/mstile-70x70.png -------------------------------------------------------------------------------- /static/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/app/static/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/app/static/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | function dummy() { 2 | // Don't do anything 3 | } 4 | 5 | window.__ELECTRON_ONLY__ = { 6 | readFile: dummy, 7 | readdir: dummy, 8 | writeFile: dummy, 9 | unlinkFile: dummy, 10 | stat: dummy, 11 | mkdir: dummy, 12 | readFileType: dummy, 13 | readFileTypeFromBuffer: dummy, 14 | showOpenDialog: dummy, 15 | showSaveDialog: dummy, 16 | openExternal: dummy, 17 | openNewWindow: dummy, 18 | openContextMenu: dummy, 19 | getPathByName: dummy, 20 | addIpcListener: dummy, 21 | sendIpcMessage: dummy, 22 | removeIpcListener: dummy, 23 | removeAllIpcListeners: dummy, 24 | setAsDefaultProtocolClient: dummy, 25 | removeAsDefaultProtocolClient: dummy, 26 | isDefaultProtocolClient: dummy, 27 | getWebContentsById: dummy, 28 | setTrafficLightPosition: dummy, 29 | convertHtmlStringToPdfBuffer: dummy, 30 | setCookie: dummy, 31 | getCookie: dummy, 32 | removeCookie: dummy, 33 | got: dummy, 34 | } 35 | -------------------------------------------------------------------------------- /tsconfig-webpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "esModuleInterop": true, 6 | "allowJs": true, 7 | "resolveJsonModule": true 8 | }, 9 | "include": ["src/**/*.ts", "src/**/*.tsx", "typings/**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*.ts", "src/**/*.tsx", "typings/**/*.d.ts"], 3 | "exclude": ["dist", "node_modules"], 4 | "compilerOptions": { 5 | "allowSyntheticDefaultImports": true, 6 | "target": "es2019", 7 | "downlevelIteration": true, 8 | "importHelpers": true, 9 | "sourceMap": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "jsx": "react", 13 | "allowJs": true, 14 | "checkJs": false, 15 | "lib": ["dom", "esnext"], 16 | "forceConsistentCasingInFileNames": true, 17 | "experimentalDecorators": true, 18 | "noUnusedParameters": true, 19 | "noImplicitReturns": true, 20 | "noUnusedLocals": true, 21 | "skipLibCheck": true, 22 | "suppressImplicitAnyIndexErrors": true, 23 | "strict": true, 24 | "esModuleInterop": true, 25 | "resolveJsonModule": true 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /typings/calendly.d.ts: -------------------------------------------------------------------------------- 1 | declare const Calendly: any 2 | -------------------------------------------------------------------------------- /typings/chartjs.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'chart.js' 2 | -------------------------------------------------------------------------------- /typings/codemirror.d.ts: -------------------------------------------------------------------------------- 1 | import CodeMirror from 'codemirror' 2 | 3 | declare module 'codemirror/mode/*' 4 | 5 | declare module 'codemirror' { 6 | function autoLoadMode(instance: CodeMirror.Editor, mode: string): void 7 | 8 | interface ModeInfo { 9 | name: string 10 | mime?: string 11 | mimes?: string[] 12 | mode: string 13 | ext: string[] 14 | alias?: string[] 15 | } 16 | const modeInfo: ModeInfo[] 17 | 18 | interface Editor { 19 | options: CodeMirror.EditorConfiguration 20 | } 21 | 22 | function findModeByMIME(mime: string): ModeInfo | undefined 23 | function findModeByName(name: string): ModeInfo | undefined 24 | 25 | function runMode( 26 | text: string, 27 | modespec: any, 28 | callback: HTMLElement | ((text: string, style: string | null) => void), 29 | options?: { tabSize?: number; state?: any } 30 | ): void 31 | } 32 | -------------------------------------------------------------------------------- /typings/coffeescript.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'coffeescript' { 2 | export function nodes(input: any): any 3 | } 4 | -------------------------------------------------------------------------------- /typings/event-source-polyfill.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'event-source-polyfill' 2 | // import { OutgoingHttpHeaders } from 'http' 3 | 4 | // declare module 'event-source-polyfill' { 5 | // interface EventSourceInitPolyfill extends EventSourceInit { 6 | // headers?: OutgoingHttpHeaders 7 | // } 8 | // export const EventSourcePolyfill: { 9 | // prototype: EventSource 10 | // new ( 11 | // url: string, 12 | // eventSourceInitDict?: EventSourceInitPolyfill 13 | // ): EventSource 14 | // readonly CLOSED: number 15 | // readonly CONNECTING: number 16 | // readonly OPEN: number 17 | // } 18 | // } 19 | -------------------------------------------------------------------------------- /typings/flowchart.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'flowchart.js' 2 | -------------------------------------------------------------------------------- /typings/markdowns.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.md' 2 | -------------------------------------------------------------------------------- /typings/mermaid.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'mermaid' 2 | -------------------------------------------------------------------------------- /typings/unified.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'hastscript' 2 | declare module 'hast-util-sanitize' 3 | declare module 'rehype-document' 4 | declare module 'rehype-katex' 5 | declare module 'rehype-raw' 6 | declare module 'rehype-react' 7 | declare module 'rehype-remark' 8 | declare module 'rehype-sanitize' 9 | declare module 'rehype-slug' 10 | declare module 'rehype-stringify' 11 | declare module 'remark-admonitions' 12 | declare module 'remark-emoji' 13 | declare module 'remark-math' 14 | declare module 'remark-parse' 15 | declare module 'remark-rehype' 16 | declare module 'remark-shortcodes' 17 | declare module 'remark-slug' 18 | declare module 'remark-stringify' 19 | declare module 'xast-util-from-xml' 20 | -------------------------------------------------------------------------------- /typings/yjs.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'y-protocols/dist/awareness.cjs' { 2 | export * from 'y-protocols/awareness' 3 | } 4 | 5 | declare module 'lib0/dist/index.cjs' { 6 | export * from 'lib0' 7 | } 8 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] 3 | } 4 | --------------------------------------------------------------------------------