diff options
Diffstat (limited to 'src/client/apis')
-rw-r--r-- | src/client/apis/GoogleAuthenticationManager.scss | 7 | ||||
-rw-r--r-- | src/client/apis/GoogleAuthenticationManager.tsx | 126 | ||||
-rw-r--r-- | src/client/apis/IBM_Recommender.ts | 2 | ||||
-rw-r--r-- | src/client/apis/google_docs/GoogleApiClientUtils.ts | 4 | ||||
-rw-r--r-- | src/client/apis/google_docs/GooglePhotosClientUtils.ts | 35 | ||||
-rw-r--r-- | src/client/apis/youtube/YoutubeBox.tsx | 4 |
6 files changed, 111 insertions, 67 deletions
diff --git a/src/client/apis/GoogleAuthenticationManager.scss b/src/client/apis/GoogleAuthenticationManager.scss index 13bde822d..bd30dd94f 100644 --- a/src/client/apis/GoogleAuthenticationManager.scss +++ b/src/client/apis/GoogleAuthenticationManager.scss @@ -16,4 +16,11 @@ font-style: italic; margin-top: 15px; } + + .disconnect { + font-size: 10px; + margin-top: 20px; + color: red; + cursor: grab; + } }
\ No newline at end of file diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx index 417dc3c3b..bf4469aeb 100644 --- a/src/client/apis/GoogleAuthenticationManager.tsx +++ b/src/client/apis/GoogleAuthenticationManager.tsx @@ -1,10 +1,11 @@ -import { observable, action, reaction, runInAction } from "mobx"; +import { observable, action, reaction, runInAction, IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import MainViewModal from "../views/MainViewModal"; -import { Opt } from "../../new_fields/Doc"; +import { Opt } from "../../fields/Doc"; import { Networking } from "../Network"; import "./GoogleAuthenticationManager.scss"; +import { Scripting } from "../util/Scripting"; const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth"; const prompt = "Paste authorization code here..."; @@ -15,64 +16,88 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { private authenticationLink: Opt<string> = undefined; @observable private openState = false; @observable private authenticationCode: Opt<string> = undefined; - @observable private clickedState = false; + @observable private showPasteTargetState = false; @observable private success: Opt<boolean> = undefined; @observable private displayLauncher = true; - @observable private avatar: Opt<string> = undefined; - @observable private username: Opt<string> = undefined; + @observable private credentials: any; + private disposer: Opt<IReactionDisposer>; private set isOpen(value: boolean) { runInAction(() => this.openState = value); } - private set hasBeenClicked(value: boolean) { - runInAction(() => this.clickedState = value); + private set shouldShowPasteTarget(value: boolean) { + runInAction(() => this.showPasteTargetState = value); } - public fetchOrGenerateAccessToken = async () => { - const response = await Networking.FetchFromServer("/readGoogleAccessToken"); + public cancel() { + this.openState && this.resetState(0, 0); + } + + public fetchOrGenerateAccessToken = async (displayIfFound = false) => { + let response: any = await Networking.FetchFromServer("/readGoogleAccessToken"); // if this is an authentication url, activate the UI to register the new access token if (new RegExp(AuthenticationUrl).test(response)) { this.isOpen = true; this.authenticationLink = response; return new Promise<string>(async resolve => { - const disposer = reaction( + this.disposer?.(); + this.disposer = reaction( () => this.authenticationCode, async authenticationCode => { - if (authenticationCode) { - disposer(); - const { access_token, avatar, name } = await Networking.PostToServer("/writeGoogleAccessToken", { authenticationCode }); + if (authenticationCode && /\d{1}\/[\w-]{55}/.test(authenticationCode)) { + this.disposer?.(); + const response = await Networking.PostToServer("/writeGoogleAccessToken", { authenticationCode }); runInAction(() => { - this.avatar = avatar; - this.username = name; - this.hasBeenClicked = false; - this.success = false; + this.success = true; + this.credentials = response; }); - this.beginFadeout(); - resolve(access_token); + this.resetState(); + resolve(response.access_token); } } ); }); } - // otherwise, we already have a valid, stored access token - return response; + + // otherwise, we already have a valid, stored access token and user info + response = JSON.parse(response); + if (displayIfFound) { + runInAction(() => { + this.success = true; + this.credentials = response; + }); + this.resetState(-1, -1); + this.isOpen = true; + } + return response.access_token; } - beginFadeout = action(() => { - this.success = true; + resetState = action((visibleForMS: number = 3000, fadesOutInMS: number = 500) => { + if (!visibleForMS && !fadesOutInMS) { + runInAction(() => { + this.isOpen = false; + this.success = undefined; + this.displayLauncher = true; + this.credentials = undefined; + this.shouldShowPasteTarget = false; + this.authenticationCode = undefined; + }); + return; + } this.authenticationCode = undefined; this.displayLauncher = false; - this.hasBeenClicked = false; - setTimeout(action(() => { - this.isOpen = false; + this.shouldShowPasteTarget = false; + if (visibleForMS > 0 && fadesOutInMS > 0) { setTimeout(action(() => { - this.success = undefined; - this.displayLauncher = true; - this.avatar = undefined; - this.username = undefined; - }), 500); - }), 3000); + this.isOpen = false; + setTimeout(action(() => { + this.success = undefined; + this.displayLauncher = true; + this.credentials = undefined; + }), fadesOutInMS); + }), visibleForMS); + } }); constructor(props: {}) { @@ -83,27 +108,38 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { private get renderPrompt() { return ( <div className={'authorize-container'}> + {this.displayLauncher ? <button className={"dispatch"} onClick={() => { window.open(this.authenticationLink); - setTimeout(() => this.hasBeenClicked = true, 500); + setTimeout(() => this.shouldShowPasteTarget = true, 500); }} - style={{ marginBottom: this.clickedState ? 15 : 0 }} + style={{ marginBottom: this.showPasteTargetState ? 15 : 0 }} >Authorize a Google account...</button> : (null)} - {this.clickedState ? <input + {this.showPasteTargetState ? <input className={'paste-target'} onChange={action(e => this.authenticationCode = e.currentTarget.value)} placeholder={prompt} /> : (null)} - {this.avatar ? <img - className={'avatar'} - src={this.avatar} - /> : (null)} - {this.username ? <span - className={'welcome'} - >Welcome to Dash, {this.username} - </span> : (null)} + {this.credentials ? + <> + <img + className={'avatar'} + src={this.credentials.userInfo.picture} + /> + <span + className={'welcome'} + >Welcome to Dash, {this.credentials.userInfo.name} + </span> + <div + className={'disconnect'} + onClick={async () => { + await Networking.FetchFromServer("/revokeGoogleAccessToken"); + this.resetState(0, 0); + }} + >Disconnect Account</div> + </> : (null)} </div> ); } @@ -125,4 +161,6 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { ); } -}
\ No newline at end of file +} + +Scripting.addGlobal("GoogleAuthenticationManager", GoogleAuthenticationManager);
\ No newline at end of file diff --git a/src/client/apis/IBM_Recommender.ts b/src/client/apis/IBM_Recommender.ts index 4e1c541c8..480b9cb1c 100644 --- a/src/client/apis/IBM_Recommender.ts +++ b/src/client/apis/IBM_Recommender.ts @@ -1,4 +1,4 @@ -// import { Opt } from "../../new_fields/Doc"; +// import { Opt } from "../../fields/Doc"; // const NaturalLanguageUnderstandingV1 = require('ibm-watson/natural-language-understanding/v1'); // const { IamAuthenticator } = require('ibm-watson/auth'); diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts index fa67ddbef..551dca073 100644 --- a/src/client/apis/google_docs/GoogleApiClientUtils.ts +++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts @@ -1,5 +1,5 @@ import { docs_v1 } from "googleapis"; -import { Opt } from "../../../new_fields/Doc"; +import { Opt } from "../../../fields/Doc"; import { isArray } from "util"; import { EditorState } from "prosemirror-state"; import { Networking } from "../../Network"; @@ -95,7 +95,7 @@ export namespace GoogleApiClientUtils { export type ExtractResult = { text: string, paragraphs: DeconstructedParagraph[] }; export const extractText = (document: docs_v1.Schema$Document, removeNewlines = false): ExtractResult => { const paragraphs = extractParagraphs(document); - let text = paragraphs.map(paragraph => paragraph.contents.filter(content => !("inlineObjectId" in content)).map(run => run as docs_v1.Schema$TextRun).join("")).join(""); + let text = paragraphs.map(paragraph => paragraph.contents.filter(content => !("inlineObjectId" in content)).map(run => (run as docs_v1.Schema$TextRun).content).join("")).join(""); text = text.substring(0, text.length - 1); removeNewlines && text.replace(/\n/g, ""); return { text, paragraphs }; diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts index ff471853a..fef71ffeb 100644 --- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts +++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts @@ -1,11 +1,11 @@ import { AssertionError } from "assert"; import { EditorState } from "prosemirror-state"; -import { Doc, DocListCastAsync, Opt } from "../../../new_fields/Doc"; -import { Id } from "../../../new_fields/FieldSymbols"; -import { RichTextField } from "../../../new_fields/RichTextField"; -import { RichTextUtils } from "../../../new_fields/RichTextUtils"; -import { Cast, StrCast } from "../../../new_fields/Types"; -import { ImageField } from "../../../new_fields/URLField"; +import { Doc, DocListCastAsync, Opt } from "../../../fields/Doc"; +import { Id } from "../../../fields/FieldSymbols"; +import { RichTextField } from "../../../fields/RichTextField"; +import { RichTextUtils } from "../../../fields/RichTextUtils"; +import { Cast, StrCast } from "../../../fields/Types"; +import { ImageField } from "../../../fields/URLField"; import { MediaItem, NewMediaItemResult } from "../../../server/apis/google/SharedTypes"; import { Utils } from "../../../Utils"; import { Docs, DocumentOptions } from "../../documents/Documents"; @@ -153,21 +153,20 @@ export namespace GooglePhotos { } const tagMapping = new Map<string, string>(); const images = (await DocListCastAsync(collection.data))!.map(Doc.GetProto); - images && images.forEach(image => tagMapping.set(image[Id], ContentCategories.NONE)); - const values = Object.values(ContentCategories); + images?.forEach(image => tagMapping.set(image[Id], ContentCategories.NONE)); + const values = Object.values(ContentCategories).filter(value => value !== ContentCategories.NONE); for (const value of values) { - if (value === ContentCategories.NONE) { - continue; - } - for (const id of (await ContentSearch({ included: [value] }))?.mediaItems?.map(({ id }) => id)) { + const searched = (await ContentSearch({ included: [value] }))?.mediaItems?.map(({ id }) => id); + console.log("Searching " + value); + console.log(searched); + searched?.forEach(async id => { const image = await Cast(idMapping[id], Doc); - if (!image) { - continue; + if (image) { + const key = image[Id]; + const tags = tagMapping.get(key); + !tags?.includes(value) && tagMapping.set(key, tags + delimiter + value); } - const key = image[Id]; - const tags = tagMapping.get(key); - !tags?.includes(value) && tagMapping.set(key, tags + delimiter + value); - } + }); } images?.forEach(image => { const concatenated = tagMapping.get(image[Id])!; diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx index 1575e53fc..ce7f49e64 100644 --- a/src/client/apis/youtube/YoutubeBox.tsx +++ b/src/client/apis/youtube/YoutubeBox.tsx @@ -1,7 +1,7 @@ import { action, observable, runInAction } from 'mobx'; import { observer } from "mobx-react"; -import { Doc, DocListCastAsync } from "../../../new_fields/Doc"; -import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; +import { Doc, DocListCastAsync } from "../../../fields/Doc"; +import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; import { Docs } from "../../documents/Documents"; |