aboutsummaryrefslogtreecommitdiff
path: root/src/client/apis
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/apis')
-rw-r--r--src/client/apis/GoogleAuthenticationManager.scss7
-rw-r--r--src/client/apis/GoogleAuthenticationManager.tsx126
-rw-r--r--src/client/apis/IBM_Recommender.ts2
-rw-r--r--src/client/apis/google_docs/GoogleApiClientUtils.ts4
-rw-r--r--src/client/apis/google_docs/GooglePhotosClientUtils.ts35
-rw-r--r--src/client/apis/youtube/YoutubeBox.tsx4
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";