diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..56cfb8c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,30 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Future] +- Add a screen to chose the community to see. +- "private" messages add a profile image. +- Add a chat bubble to see users join and leave threads. +- Change the text box with a "join" button for the threads you arn't in. +- Record button in threads, implement record logic. +- Add thread name to the header of threads. +- Add a leave thread, maybe in header? +- Overhaul textbox in threads. +- Display correctly special syntax flavor [B]old [I]talic [C]enter [U]nderline [S]trikeout. +- Migrate chat bubbles from float based to grid. +- Move chat bubble elements to his own components. + +## [Unreleased] + + +## [1.0.6] - 2018-06-21 +### Added +- This CHANGELOG. +- Version bumb to 1.0.0 so it follows semver. + +### Changed +- LICENCE.md +- package.json with repo url. \ No newline at end of file diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..4e3f927 --- /dev/null +++ b/LICENCE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Marc "Fox" Salva Montaner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..604308a --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# Amino Desktop Client + +## Amino in PC!? I want it, as an user how can I have it? + +Go to [this link](https://github.com/SrZorro/AminoPC/releases) and download the version for your operative system. + +| Operative system | Your version is | +| ---------------- | ---------------------------------------------------------------------------------------- | +| Windows 32 bits | AminoPC-win32-ia32.zip | +| Windows 64 bits | AminoPC-win32-x64.zip | +| Linux 64 bits | amino-pc_1.0.0_amd64.deb | +| Linux 32 bits | Sorry, i didn't compiled a version yet | +| Mac | I don't have an Apple product to compile it, im not going to give support for it, sorry. | + +The windows version is a zip containing a bunch of files, betweem them there is one called _AminoPC.exe_, you have to execute that file INSIDE that folder. + +### AminoPC is asking me for a DeviceID, but I don't have one. + +Yes, you need a DeviceID, that is not the average DeviceID that you can get with an app installed in your phone, its a special one generated by the AminoApp. + +So, there are two ways to resolve the "DeviceID" input box. + +#### Easy way + +Use this key I prepared for public use: + +`TODO: Add the device ID` + +And you are set. + +> WARNING! If you want to use that device ID that means that in the future Narvii COULD ban your account. Use at your own risk. + +#### Not so easy + +So, first im going to explain the objective and then the simplest method you can use, but you can do it in a bunch of other ways (My prefered one is with the [Android SDK/AVD](https://developer.android.com/studio/run/managing-avds?hl=en-419) with [mitmproxy](https://mitmproxy.org/)). + +The objective: Do a [man in the middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) to the Amino app so we can intercept the auth request and get our own DeviceID. + +Requisites: +- An Android device. +- Amino app installed. + + +1) Download and install [Packet Capture](https://play.google.com/store/apps/details?id=app.greyshirts.sslcapture) in your android device. +2) Logout from the Amino App. This is located at the "My joined Aminos" screen, at the top right click in the gear, scroll to bottom and "Close session". +3) Open the Packet Capture app. +4) The app will ask you to install a certificate, give them permission for it and follow the steps. +4) When you finished the installation process, click the green play button with an "1" at the top right. +5) Search and select "Amino". +6) Now the Packet Capture is ready to capture packets from Amino. +7) Switch to Amino and login. +8) Switch back to the Packet Capture app and stop the recording (top right, red box). +9) Click the first field (the only one you should have) where should say the current date an underneath "X captures" (X should be more than 1) +10) Click one of the elements where at the right says "SSL" in red. +11) In the first text box, should say at the start "POST /api/v1/g/s/auth/login HTTP/1.1", if it does, go to step 12, if not, go back to 10. If you checked all of them, repeat from step 4. +12) Underneath the first text block, a second one should have your email, your "secret" (aka password) and a field called "deviceID", thats the one you want to login in AminoPC. +13) _Optional:_ Now you can uninstall the Packet Capture app and if you desire it can also remove the pass code for your android phone, but its recomended to have one + +## Im a developer, how can i help? + +ToDo... \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f34d3d7..7d516c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -343,6 +343,15 @@ "string-width": "2.1.1" } }, + "aminoclient": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/aminoclient/-/aminoclient-1.0.6.tgz", + "integrity": "sha512-SID1/OHRyk7z59K6kVcPxrm46uCDS0zMYrv5AKvLKtteifzAGvwhtJ2zXbJ/iToqo1G9OTIm7eg1gzLNnR8Dng==", + "requires": { + "cross-fetch": "^2.2.1", + "uuid": "^3.2.1" + } + }, "ansi-escapes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", @@ -3471,8 +3480,8 @@ "bundled": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { @@ -3483,7 +3492,7 @@ "version": "1.1.11", "bundled": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -3537,7 +3546,7 @@ "bundled": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -3550,14 +3559,14 @@ "bundled": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { @@ -3565,12 +3574,12 @@ "bundled": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -3583,7 +3592,7 @@ "bundled": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "^2.1.0" } }, "ignore-walk": { @@ -3591,7 +3600,7 @@ "bundled": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -3599,8 +3608,8 @@ "bundled": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -3616,7 +3625,7 @@ "version": "1.0.0", "bundled": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -3628,7 +3637,7 @@ "version": "3.0.4", "bundled": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -3639,8 +3648,8 @@ "version": "2.2.4", "bundled": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" } }, "minizlib": { @@ -3648,7 +3657,7 @@ "bundled": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { @@ -3668,9 +3677,9 @@ "bundled": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { @@ -3678,16 +3687,16 @@ "bundled": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -3695,8 +3704,8 @@ "bundled": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { @@ -3709,8 +3718,8 @@ "bundled": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -3718,10 +3727,10 @@ "bundled": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -3737,7 +3746,7 @@ "version": "1.4.0", "bundled": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -3755,8 +3764,8 @@ "bundled": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -3774,10 +3783,10 @@ "bundled": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -3792,13 +3801,13 @@ "bundled": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { @@ -3806,7 +3815,7 @@ "bundled": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -3842,9 +3851,9 @@ "version": "1.0.2", "bundled": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -3852,14 +3861,14 @@ "bundled": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { "version": "3.0.1", "bundled": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -3872,13 +3881,13 @@ "bundled": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -3891,7 +3900,7 @@ "bundled": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { diff --git a/package.json b/package.json index bf5e4e8..33e098a 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,17 @@ "publish": "build -p always", "electron": "electron ./dist/webpack/main.js" }, - "author": "fox@foxdev.io", + "author": "Marc 'Fox' Salva Montaner ", "license": "MIT", + "bugs": { + "url": "https://github.com/SrZorro/AminoPC/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/SrZorro/AminoPC" + }, "dependencies": { + "aminoclient": "^1.0.6", "cross-fetch": "^2.2.1", "electron-updater": "^2.21.10", "inferno": "^4.0.2", diff --git a/src/renderer/Amino/AminoClient.ts b/src/renderer/Amino/AminoClient.ts deleted file mode 100644 index 28283cf..0000000 --- a/src/renderer/Amino/AminoClient.ts +++ /dev/null @@ -1,171 +0,0 @@ -import fetch from "cross-fetch"; -import Endpoints from "./Endpoints"; -import { v4 as UUID } from "uuid"; -import * as AminoTypes from "./AminoTypes"; - -interface Iheaders { [key: string]: string; } - -declare global { - // tslint:disable-next-line - interface String { - format(...replacer: string[]): string; - } -} -String.prototype.format = function() { - let a = this; - for (const k in arguments) { - if (arguments.hasOwnProperty(k)) - a = a.replace(new RegExp("\\{" + k + "\\}", "g"), arguments[k]); - } - return a; -}; - -class AminoClient { - public isLogged: boolean; - public onLogged: Array<() => void>; - public uid: string; - private sid: string; - private deviceId: string; - constructor() { - this.isLogged = false; - this.onLogged = []; - } - - public async login(email: string, password: string, deviceId: string) { - this.deviceId = deviceId; - const body = { - email, - secret: `0 ${password}`, - deviceID: deviceId, - clientType: 100, - action: "normal", - timestamp: Math.round((new Date()).getTime() / 1000) - }; - - const result = await this.post(Endpoints.LOGIN, body, { - "NDCDEVICEID": this.deviceId, - "NDC-MSG-SIG": this.getMessageSignature() - }); - - const statusCode = result["api:statuscode"]; - - switch (statusCode) { - case 0: break; - default: - if (!result["api:statuscode"]) - throw Error("Unknown error"); - const err = new Error(result["api:message"]); - err.name = result["api:statuscode"]; - throw err; - } - - this.sid = result.sid; - this.uid = result.account.uid; - - this.isLogged = true; - this.onLogged.map((onLogged) => { - onLogged(); - }); - return result; - } - - public async getCommunityCollectionSections(languageCode: string, start: number, size: number): Promise { - return await this.get(Endpoints.COMMUNITY_COLLECTION_SECTIONS.format(languageCode, start.toString(), size.toString())); - } - - public async getJoinedCommunities(start: number, size: number): Promise { - return await this.get(Endpoints.JOINED_COMMUNITIES.format(start.toString(), size.toString())); - } - - public async getPublicChats(ndcId: number, start: number, size: number): Promise { - const response = await this.get(Endpoints.LIVE_LAYERS_PUBLIC_CHAT.format(ndcId.toString(), start.toString(), size.toString())); - return response.threadList; - } - - public async getJoinedChats(ndcId: number, start: number, size: number): Promise { - const response = await this.get(Endpoints.COMMUNITY_CHAT_THREAD.format(ndcId.toString(), "joined-me", start.toString(), size.toString())); - return response.threadList; - } - - public async getThreadMessages(ndcId: number, threadId: string, start: number, size: number, startTime?: string): Promise { - let url = ""; - if (startTime === undefined) { - url = Endpoints.COMMUNITY_CHAT_GET_MESSAGES.format(ndcId.toString(), threadId, start.toString(), size.toString()); - } else { - url = Endpoints.COMMUNITY_CHAT_GET_MESSAGES_SINCE.format(ndcId.toString(), threadId, start.toString(), size.toString(), startTime); - } - const result = await this.get(url); - return result.messageList; - } - - public async sendMessageInThread(ndcId: number, threadId: string, content: string): Promise { - const msg = await this.post(Endpoints.COMMUNITY_CHAT_SEND_MESSAGE.format(ndcId.toString(), threadId), { - attachedObject: null, - content, - type: 0, - clientRefId: Math.round((new Date()).getTime() / 1000), - timestamp: Math.round((new Date()).getTime() / 1000) - }, { - "NDCDEVICEID": this.deviceId, - "NDCAUTH": `sid=${this.sid}`, - "NDC-MSG-SIG": this.getMessageSignature() - }); - return msg; - } - public async sendMediaInThread(ndcId: number, threadId: string, mediaB64: string, mediaType: string): Promise { - const body = { - type: mediaType.includes("audio") ? 2 : 0, - clientRefId: Math.round((new Date()).getTime() / 1000), - mediaType: mediaType.includes("audio") ? 110 : 100, - content: null, - mediaUploadValue: mediaB64, - attachedObject: null, - timestamp: Math.round((new Date()).getTime() / 1000) - }; - // Note: PNG support is kinda wroken, its converted to jpg and creates artefacts where transparency was located. - if (mediaType.includes("image")) { - // @ts-ignore - body.mediaUhqEnabled = false; // High quality maybe? - // @ts-ignore - body.mediaUploadValueContentType = mediaType; - } - - const msg = await this.post(Endpoints.COMMUNITY_CHAT_SEND_MESSAGE.format(ndcId.toString(), threadId), body, { - NDCDEVICEID: this.deviceId, - NDCAUTH: `sid=${this.sid}` - }); - return msg; - } - - private async get(url: string) { - const headers: Iheaders = { - "NDCDEVICEID": this.deviceId, - "NDCAUTH": `sid=${this.sid}`, - "NDC-MSG-SIG": this.getMessageSignature(), - "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 7.1.2; MotoG3-TE Build/NJH47F; com.narvii.amino.master/1.8.15305)", - "Upgrade": "websocket", - "Connection": "Upgrade", - "Sec-WebSocket-Key": "86iFBnuI8GWLlgWmSToY6g==", - "Sec-WebSocket-Version": "13", - "Accept-Encoding": "gzip" - }; - const response = await fetch(url, { method: "GET", headers }); - return await response.json(); - } - - private async post(url: string, body: object, headers?: Iheaders) { - const defaultHeaders: Iheaders = { - NDCDEVICEID: this.deviceId, - NDCAUTH: `sid=${this.sid}` - }; - const response = await fetch(url, { method: "POST", headers: headers ? headers : defaultHeaders, body: JSON.stringify(body) }); - const json = await response.json(); - return { ...json, response }; - } - - private getMessageSignature() { - return UUID().replace("-", "").toUpperCase().substring(0, 27); - } -} - -export default AminoClient; \ No newline at end of file diff --git a/src/renderer/Amino/AminoTypes.d.ts b/src/renderer/Amino/AminoTypes.d.ts deleted file mode 100644 index 68ba430..0000000 --- a/src/renderer/Amino/AminoTypes.d.ts +++ /dev/null @@ -1,110 +0,0 @@ - - -export interface JoinedCommunitiesInfo { - communityList: AminoCommunity[], - userInfoInCommunities: { [key: string]: UserProfile } -} - -export interface UserProfile { - status: number, - itemsCount: number, - consecutiveCheckInDays?: string, - uid: string, - modifiedTime: any, - joinedCount: any, - longitude: number, - race?: string, - address: string, - membersCount: number, - nickname: string, - mediaList: any, - icon: string, - mood?: string, - level: number, - gender?: string, - settings: any, - pushEnabled: Boolean, - membershipStatus: number, - content?: string, - reputation: number, - role: number, - latitude: number, - extensions: any, - blogsCount: number -} - -export interface AminoCommunity { - status: number, - launchPage: object, - endpoint: string, - name: string, - modifiedTime: string, - communityHeat: number, - tagline: string, - templateId: number, - agent: object, - joinType: number, - link: string, - listedStatus: number, - themePack: object, - ndcId: number, - createdTime: string, - probationStatus: number, - membersCount: number, - primaryLanguage: string, - promotionalMediaList: any[], - icon: string -} - -export interface AminoThread { - uid: string, - membersQuota: number, - membersSummary: MiniUserProfile[], - threadId: string, - keywords: string, - membersCount: number, - title: string, - membershipStatus: number, - content: string, - latitude?: number, - alertOption: number, - lastReadTime?: Date, - type: number, - status: number, - modifiedTime?: Date, - lastMessageSummary?: any, - condition: number, - icon: string, - latestActivityTime?: Date, - longitude?: number, - extensions?: any, - createdTime?: Date -} - -export interface MiniUserProfile { - status: number, - uid: string, - level: number, - onlineStatus: number, - reputation: number, - role: number, - nickname: string, - icon: string -} - -export interface PublicChats { - threadList: AminoThread[], - recommendedThreadList: AminoThread[] -} - -export interface AminoMessage { - author: MiniUserProfile, - threadId: string, - mediaType: number, - content?: string, - mediaValue?: string, - clientRefId: string, - messageId: string, - createdTime: Date, - type: number -} \ No newline at end of file diff --git a/src/renderer/Amino/Endpoints.ts b/src/renderer/Amino/Endpoints.ts deleted file mode 100644 index 1af0e5b..0000000 --- a/src/renderer/Amino/Endpoints.ts +++ /dev/null @@ -1,55 +0,0 @@ - -function generate_endpoints() { - const PREFIX = "http://service.narvii.com/api/v1"; - const SECURE_WEBSOCKET = "https://ws3.narvii.com/"; - const GET_BLOG_POST = PREFIX + "/{0}/s/blog/{1}"; - return { - // // ===[ AUTH ENDPOINTS ]=== - LOGIN: PREFIX + "/g/s/auth/login", - REGISTER: PREFIX + "/g/s/auth/register", - REGISTER_CHECK: PREFIX + "/g/s/auth/register-check", - - // // ===[ USER ENDPOINTS ]=== - AFFILIATIONS: PREFIX + "/g/s/account/affiliations?type=active", - HEADLINES: PREFIX + "/g/s/feed/headlines?start={0}&size={1}", - DEVICE_INFO: PREFIX + "/g/s/device", - - // // ===[ COMMUNITY ENDPOINTS ]=== - LINK_IDENTIFY: PREFIX + "/g/s/community/link-identify?q={0}", - JOIN_COMMUNITY: PREFIX + "/{0}/s/community/join", - LEAVE_COMMUNITY: PREFIX + "/{0}/s/community/leave", - COMMUNITY_INFO: PREFIX + "/g/s-x{0}/community/info", - SUGGESTED_COMMUNITIES: PREFIX + "/g/s/community/suggested?language={0}", - TRENDING_COMMUNITIES: PREFIX + "/g/s/community/trending?start={0}&size={1}&language={2}", - COMMUNITY_FEED: PREFIX + "/{0}/s/feed/blog-all?start={1}&size={2}", - COMMUNITY_ONLINE_MEMBERS: PREFIX + "/{0}/s/community/online-members-check", - SUGGESTED_KEYWORDS: PREFIX + "/g/s/community/search/suggested-keywords?q={0}&start={1}&size={2}&language={3}", - SEARCH_TAGS: PREFIX + "/g/s/community/search/tags?q={0}", - SEARCH_COMMUNITIES: PREFIX + "/g/s/community/search?q={0}&start={1}&size={2}&language={3}&completeKeyword={4}", - JOINED_COMMUNITIES: PREFIX + "/g/s/community/joined?start={0}&size={1}", - SUPPORTED_LANGUAGES: PREFIX + "/g/s/community-collection/supported-languages?start={0}&size={1}", - COMMUNITY_COLLECTION_SECTIONS: PREFIX + "/g/s/community-collection/view/explore/sections?language={0}&start={1}&size={2}", - COMMUNITY_CHECK_IN: PREFIX + "/x{0}/s/check-in", - - // // ===[ NOTIFICATION ENDPOINTS ]=== - COMMUNITY_NOTIFICATIONS: PREFIX + "/{0}/s/notification?start={1}&size={2}&cv={3}", - REMINDERS: PREFIX + "/g/s/reminder/check?ndcIds={0}&timezone={1}", - - // // ===[ BLOG ENDPOINTS ]=== - GET_BLOG_POST, - POST_VOTE: GET_BLOG_POST + "/vote", - POST_COMMENT: GET_BLOG_POST + "/comment", - - // ===[ CHAT ENDPOINTS ]=== - COMMUNITY_THREAD: PREFIX + "/x{0}/s/chat/thread/{1}", - COMMUNITY_CHAT_THREAD: PREFIX + "/x{0}/s/chat/thread?type={1}&start={2}&size={3}", - COMMUNITY_JOIN_CHAT_THREAD: PREFIX + "/x{0}/s/chat/thread/{1}/member/{2}", - COMMUNITY_CHAT_SEND_MESSAGE: PREFIX + "/x{0}/s/chat/thread/{1}/message", - COMMUNITY_CHAT_GET_MESSAGES: PREFIX + "/x{0}/s/chat/thread/{1}/message?start={2}&size={3}", - COMMUNITY_CHAT_GET_MESSAGES_SINCE: PREFIX + "/x{0}/s/chat/thread/{1}/message?start={2}&size={3}&starttime={4}", - - // ===[ LIVE LAYERS ]=== - LIVE_LAYERS_PUBLIC_CHAT: PREFIX + "/x{0}/s/live-layer/public-chats?start=0&size=25" - }; -} -export default generate_endpoints(); \ No newline at end of file diff --git a/src/renderer/Amino/index.ts b/src/renderer/Amino/index.ts deleted file mode 100644 index 66442a2..0000000 --- a/src/renderer/Amino/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -import AminoClient from "./AminoClient"; -export default new AminoClient(); \ No newline at end of file diff --git a/src/renderer/components/Amino.tsx b/src/renderer/components/Amino.tsx index ce3c8ac..f5297c2 100644 --- a/src/renderer/components/Amino.tsx +++ b/src/renderer/components/Amino.tsx @@ -1,8 +1,9 @@ -import AminoClient from "../Amino"; +import AminoClient from "aminoclient"; import { Component } from "inferno"; import Threads from "./Threads"; import ThreadChat from "./ThreadChat"; import Login from "./Login"; +import Communities from "./Communities"; const style = { width: "100%", @@ -33,11 +34,15 @@ export default class Amino extends Component { let display =
Loading...
; if (this.state.scene === "login") { - display = + display = ; + } + + if (this.state.scene === "CommunityList") { + display = ; } if (this.state.scene === "ThreadList" && this.state.ndcId !== null) { - display = + display = ; } if (this.state.scene === "ThreadChat" && this.state.threadId !== null) { diff --git a/src/renderer/components/ChatBubble.tsx b/src/renderer/components/ChatBubble.tsx index 2fbbfab..08a69db 100644 --- a/src/renderer/components/ChatBubble.tsx +++ b/src/renderer/components/ChatBubble.tsx @@ -1,7 +1,8 @@ -import { AminoMessage } from "../Amino/AminoTypes"; +import { IAminoMessage } from "aminoclient/dist/AminoTypes"; import { Component } from "inferno"; import { style } from "typestyle"; import moment from "moment"; +// import AudioBubble from "./bubbles/AudioBubble"; const classMain = style({ width: "100%", @@ -113,7 +114,7 @@ const classTime = style({ }); interface IChatBubbleProps { - aminoMessage: AminoMessage; + aminoMessage: IAminoMessage; left?: boolean; displayProfile?: boolean; displayName?: boolean; @@ -162,6 +163,8 @@ export default class ChatBubble extends Component { case 110: // ToDo - Add style from https://codepen.io/gregh/pen/NdVvbm ctx.push(); + // Stoped AudioBubble development till grid system is implemented + // ctx.push(); break; } } diff --git a/src/renderer/components/Communities.tsx b/src/renderer/components/Communities.tsx new file mode 100644 index 0000000..1972041 --- /dev/null +++ b/src/renderer/components/Communities.tsx @@ -0,0 +1,20 @@ +import { Component } from "inferno"; +import { style } from "typestyle"; +import AminoClient from "aminoclient"; + +const main = style({ +}); + +export default class Communities extends Component { + constructor(props, context) { + super(props, context); + } + + public render() { + return ( +
+ WIP +
+ ); + } +} \ No newline at end of file diff --git a/src/renderer/components/FileDrop.tsx b/src/renderer/components/FileDrop.tsx index f43efb4..8335453 100644 --- a/src/renderer/components/FileDrop.tsx +++ b/src/renderer/components/FileDrop.tsx @@ -1,4 +1,4 @@ -import AminoClient from "../Amino"; +import AminoClient from "aminoclient"; import * as fs from "fs"; import { Component } from "inferno"; import { style } from "typestyle"; diff --git a/src/renderer/components/Login.tsx b/src/renderer/components/Login.tsx index 3359346..bd923d9 100644 --- a/src/renderer/components/Login.tsx +++ b/src/renderer/components/Login.tsx @@ -1,6 +1,6 @@ import { Component } from "inferno"; import { style } from "typestyle"; -import AminoClient from "../Amino"; +import AminoClient from "aminoclient"; const version = eval(`require("./package.json").version`); const main = style({ diff --git a/src/renderer/components/ThreadChat.tsx b/src/renderer/components/ThreadChat.tsx index 931c76e..92236be 100644 --- a/src/renderer/components/ThreadChat.tsx +++ b/src/renderer/components/ThreadChat.tsx @@ -1,5 +1,5 @@ -import AminoClient from "../Amino"; -import { AminoMessage } from "../Amino/AminoTypes"; +import AminoClient from "aminoclient"; +import { IAminoMessage } from "aminoclient/dist/AminoTypes"; import { Component } from "inferno"; import { style } from "typestyle"; import ChatBubble from "./ChatBubble"; @@ -173,9 +173,9 @@ export default class ThreadChat extends Component { // type: 0 | mediaType: 100 = Picture // type: 3 | mediaType: 113 = Sticker if (this.state.threadMessages !== null) - this.state.threadMessages.forEach((message: AminoMessage, index, messages) => { - const prevMessage: AminoMessage | null = index <= 0 ? null : messages[index - 1]; - const nextMessage: AminoMessage | null = index >= messages.length - 1 ? null : messages[index + 1]; + this.state.threadMessages.forEach((message: IAminoMessage, index, messages) => { + const prevMessage: IAminoMessage | null = index <= 0 ? null : messages[index - 1]; + const nextMessage: IAminoMessage | null = index >= messages.length - 1 ? null : messages[index + 1]; if ((prevMessage !== null && prevMessage.author.uid !== message.author.uid) && (nextMessage === null || message.author.uid !== nextMessage.author.uid)) return chatBubbles.push(); @@ -186,6 +186,8 @@ export default class ThreadChat extends Component { if (prevMessage !== null && prevMessage.author.uid === message.author.uid) return chatBubbles.push(); }); + else + chatBubbles.push(

Loading messages...

); return (
diff --git a/src/renderer/components/Threads.tsx b/src/renderer/components/Threads.tsx index 2d9f844..7eb4e70 100644 --- a/src/renderer/components/Threads.tsx +++ b/src/renderer/components/Threads.tsx @@ -1,7 +1,7 @@ import { Component } from "inferno"; import { style } from "typestyle"; import ThreadElement from "./ThreadElement"; -import AminoClient from "../Amino"; +import AminoClient from "aminoclient"; const main = style({ width: "100%", @@ -100,6 +100,7 @@ export default class Threads extends Component { if (this.state.isHovering) classes += " " + mainHover; return (
{ this.setState({ isHovering: true }); }} onMouseLeave={() => { this.setState({ isHovering: false }); }}> + {this.state.joinedThreadList.length === 0 ?

Loading chats...

: null} {this.state.joinedThreadList.map((thread) => { return ([ diff --git a/src/renderer/components/bubbles/AudioBubble.tsx b/src/renderer/components/bubbles/AudioBubble.tsx new file mode 100644 index 0000000..0f8c2bc --- /dev/null +++ b/src/renderer/components/bubbles/AudioBubble.tsx @@ -0,0 +1,24 @@ +import { Component } from "inferno"; +import { style } from "typestyle"; + +const classMain = style({ + height: 50 +}); + +interface IAudioBubble { + src: string; +} + +export default class ChatBubble extends Component { + constructor(props: IAudioBubble, context) { + super(props, context); + } + + public render() { + return ( +
+ +
+ ); + } +} \ No newline at end of file diff --git a/src/renderer/references.d.ts b/src/renderer/references.d.ts deleted file mode 100644 index a104b2b..0000000 --- a/src/renderer/references.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare const React:any; \ No newline at end of file