mirror of https://github.com/shuang854/Turtle
implemented cloud functions and created chat UI mockup
parent
f3efebc1dc
commit
f4905e4d36
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"projects": {
|
||||||
|
"default": "turtle-95153"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"functions": {
|
||||||
|
"predeploy": [
|
||||||
|
"npm --prefix \"$RESOURCE_DIR\" run lint",
|
||||||
|
"npm --prefix \"$RESOURCE_DIR\" run build"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
## Compiled JavaScript files
|
||||||
|
**/*.js
|
||||||
|
**/*.js.map
|
||||||
|
|
||||||
|
# Typescript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
lib/
|
||||||
|
|
||||||
|
firebase-debug.log
|
||||||
|
ui-debug.log
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "functions",
|
||||||
|
"scripts": {
|
||||||
|
"lint": "tslint --project tsconfig.json",
|
||||||
|
"build": "tsc",
|
||||||
|
"serve": "npm run build && firebase emulators:start --only functions",
|
||||||
|
"shell": "npm run build && firebase functions:shell",
|
||||||
|
"start": "npm run shell",
|
||||||
|
"deploy": "firebase deploy --only functions",
|
||||||
|
"logs": "firebase functions:log"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "10"
|
||||||
|
},
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"firebase-admin": "^8.10.0",
|
||||||
|
"firebase-functions": "^3.6.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"tslint": "^5.12.0",
|
||||||
|
"typescript": "^3.8.0",
|
||||||
|
"firebase-functions-test": "^0.2.0"
|
||||||
|
},
|
||||||
|
"private": true
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import functions = require('firebase-functions');
|
||||||
|
|
||||||
|
import admin = require('firebase-admin');
|
||||||
|
admin.initializeApp();
|
||||||
|
|
||||||
|
const firestore = admin.firestore();
|
||||||
|
|
||||||
|
// Start writing Firebase Functions
|
||||||
|
// https://firebase.google.com/docs/functions/typescript
|
||||||
|
|
||||||
|
export const helloWorld = functions.https.onRequest((request, response) => {
|
||||||
|
functions.logger.info('Hello logs!', { structuredData: true });
|
||||||
|
response.send('Hello from Firebase!');
|
||||||
|
});
|
||||||
|
|
||||||
|
export const deleteRoom = functions.database.ref('/available/{roomId}').onDelete(async (snapshot, context) => {
|
||||||
|
const firestoreRef = firestore.doc(`rooms/${context.params.roomId}`);
|
||||||
|
|
||||||
|
// // Consider fast changes to realtime database
|
||||||
|
// const currSnapshot = snapshot.val();
|
||||||
|
// const newSnapshot = await snapshot.ref.once('value');
|
||||||
|
// if (newSnapshot.val().last_changed > currSnapshot.last_changed) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return firestoreRef.delete();
|
||||||
|
});
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"target": "es2017"
|
||||||
|
},
|
||||||
|
"compileOnSave": true,
|
||||||
|
"include": [
|
||||||
|
"src"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"rules": {
|
||||||
|
// -- Strict errors --
|
||||||
|
// These lint rules are likely always a good idea.
|
||||||
|
|
||||||
|
// Force function overloads to be declared together. This ensures readers understand APIs.
|
||||||
|
"adjacent-overload-signatures": true,
|
||||||
|
|
||||||
|
// Do not allow the subtle/obscure comma operator.
|
||||||
|
"ban-comma-operator": true,
|
||||||
|
|
||||||
|
// Do not allow internal modules or namespaces . These are deprecated in favor of ES6 modules.
|
||||||
|
"no-namespace": true,
|
||||||
|
|
||||||
|
// Do not allow parameters to be reassigned. To avoid bugs, developers should instead assign new values to new vars.
|
||||||
|
"no-parameter-reassignment": true,
|
||||||
|
|
||||||
|
// Force the use of ES6-style imports instead of /// <reference path=> imports.
|
||||||
|
"no-reference": true,
|
||||||
|
|
||||||
|
// Do not allow type assertions that do nothing. This is a big warning that the developer may not understand the
|
||||||
|
// code currently being edited (they may be incorrectly handling a different type case that does not exist).
|
||||||
|
"no-unnecessary-type-assertion": true,
|
||||||
|
|
||||||
|
// Disallow nonsensical label usage.
|
||||||
|
"label-position": true,
|
||||||
|
|
||||||
|
// Disallows the (often typo) syntax if (var1 = var2). Replace with if (var2) { var1 = var2 }.
|
||||||
|
"no-conditional-assignment": true,
|
||||||
|
|
||||||
|
// Disallows constructors for primitive types (e.g. new Number('123'), though Number('123') is still allowed).
|
||||||
|
"no-construct": true,
|
||||||
|
|
||||||
|
// Do not allow super() to be called twice in a constructor.
|
||||||
|
"no-duplicate-super": true,
|
||||||
|
|
||||||
|
// Do not allow the same case to appear more than once in a switch block.
|
||||||
|
"no-duplicate-switch-case": true,
|
||||||
|
|
||||||
|
// Do not allow a variable to be declared more than once in the same block. Consider function parameters in this
|
||||||
|
// rule.
|
||||||
|
"no-duplicate-variable": [true, "check-parameters"],
|
||||||
|
|
||||||
|
// Disallows a variable definition in an inner scope from shadowing a variable in an outer scope. Developers should
|
||||||
|
// instead use a separate variable name.
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
|
||||||
|
// Empty blocks are almost never needed. Allow the one general exception: empty catch blocks.
|
||||||
|
"no-empty": [true, "allow-empty-catch"],
|
||||||
|
|
||||||
|
// Functions must either be handled directly (e.g. with a catch() handler) or returned to another function.
|
||||||
|
// This is a major source of errors in Cloud Functions and the team strongly recommends leaving this rule on.
|
||||||
|
"no-floating-promises": true,
|
||||||
|
|
||||||
|
// Do not allow any imports for modules that are not in package.json. These will almost certainly fail when
|
||||||
|
// deployed.
|
||||||
|
"no-implicit-dependencies": true,
|
||||||
|
|
||||||
|
// The 'this' keyword can only be used inside of classes.
|
||||||
|
"no-invalid-this": true,
|
||||||
|
|
||||||
|
// Do not allow strings to be thrown because they will not include stack traces. Throw Errors instead.
|
||||||
|
"no-string-throw": true,
|
||||||
|
|
||||||
|
// Disallow control flow statements, such as return, continue, break, and throw in finally blocks.
|
||||||
|
"no-unsafe-finally": true,
|
||||||
|
|
||||||
|
// Expressions must always return a value. Avoids common errors like const myValue = functionReturningVoid();
|
||||||
|
"no-void-expression": [true, "ignore-arrow-function-shorthand"],
|
||||||
|
|
||||||
|
// Disallow duplicate imports in the same file.
|
||||||
|
"no-duplicate-imports": true,
|
||||||
|
|
||||||
|
|
||||||
|
// -- Strong Warnings --
|
||||||
|
// These rules should almost never be needed, but may be included due to legacy code.
|
||||||
|
// They are left as a warning to avoid frustration with blocked deploys when the developer
|
||||||
|
// understand the warning and wants to deploy anyway.
|
||||||
|
|
||||||
|
// Warn when an empty interface is defined. These are generally not useful.
|
||||||
|
"no-empty-interface": {"severity": "warning"},
|
||||||
|
|
||||||
|
// Warn when an import will have side effects.
|
||||||
|
"no-import-side-effect": {"severity": "warning"},
|
||||||
|
|
||||||
|
// Warn when variables are defined with var. Var has subtle meaning that can lead to bugs. Strongly prefer const for
|
||||||
|
// most values and let for values that will change.
|
||||||
|
"no-var-keyword": {"severity": "warning"},
|
||||||
|
|
||||||
|
// Prefer === and !== over == and !=. The latter operators support overloads that are often accidental.
|
||||||
|
"triple-equals": {"severity": "warning"},
|
||||||
|
|
||||||
|
// Warn when using deprecated APIs.
|
||||||
|
"deprecation": {"severity": "warning"},
|
||||||
|
|
||||||
|
// -- Light Warnings --
|
||||||
|
// These rules are intended to help developers use better style. Simpler code has fewer bugs. These would be "info"
|
||||||
|
// if TSLint supported such a level.
|
||||||
|
|
||||||
|
// prefer for( ... of ... ) to an index loop when the index is only used to fetch an object from an array.
|
||||||
|
// (Even better: check out utils like .map if transforming an array!)
|
||||||
|
"prefer-for-of": {"severity": "warning"},
|
||||||
|
|
||||||
|
// Warns if function overloads could be unified into a single function with optional or rest parameters.
|
||||||
|
"unified-signatures": {"severity": "warning"},
|
||||||
|
|
||||||
|
// Prefer const for values that will not change. This better documents code.
|
||||||
|
"prefer-const": {"severity": "warning"},
|
||||||
|
|
||||||
|
// Multi-line object literals and function calls should have a trailing comma. This helps avoid merge conflicts.
|
||||||
|
"trailing-comma": {"severity": "warning"}
|
||||||
|
},
|
||||||
|
|
||||||
|
"defaultSeverity": "error"
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
// Database schema
|
||||||
|
|
||||||
|
// Firestore
|
||||||
|
const collection = {
|
||||||
|
rooms: {
|
||||||
|
roomId: {
|
||||||
|
createdAt: 'timestamp',
|
||||||
|
ownerId: 'userId',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Realtime Database - needed for tracking user presence
|
||||||
|
const turtle = {
|
||||||
|
// Needed for database triggers updating Firestore
|
||||||
|
available: {
|
||||||
|
roomId: {
|
||||||
|
createdAt: '2020-08-12T00:13:16.273Z',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Keeping track of which users are present in a room
|
||||||
|
rooms: {
|
||||||
|
roomId: {
|
||||||
|
userId: {
|
||||||
|
name: 'Username',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
ion-grid {
|
||||||
|
border-left: solid 1px #bbb;
|
||||||
|
border-right: solid 1px #bbb;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-col {
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
max-width: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-textarea {
|
||||||
|
border: solid 1px #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-align {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-msg {
|
||||||
|
text-align: right;
|
||||||
|
background: var(--ion-color-primary);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.other-msg {
|
||||||
|
background: var(--ion-color-secondary);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-msg {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
import { IonButton, IonCol, IonContent, IonFooter, IonGrid, IonRow, IonTextarea } from '@ionic/react';
|
||||||
|
import React from 'react';
|
||||||
|
import './Chat.css';
|
||||||
|
|
||||||
|
const Chat: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<IonContent>
|
||||||
|
<IonGrid>
|
||||||
|
<IonRow class="right-align">
|
||||||
|
<IonCol size="auto" class="my-msg">
|
||||||
|
<b>Simon: </b>
|
||||||
|
<span>Hello!</span>
|
||||||
|
</IonCol>
|
||||||
|
</IonRow>
|
||||||
|
<IonRow>
|
||||||
|
<IonCol size="auto" class="other-msg">
|
||||||
|
<b>Manuel: </b>
|
||||||
|
<span>They are all asking me about what I'm going to do next</span>
|
||||||
|
</IonCol>
|
||||||
|
</IonRow>
|
||||||
|
<IonRow>
|
||||||
|
<IonCol size="auto" class="other-msg">
|
||||||
|
<b>Amaria: </b>
|
||||||
|
<span>Probably riding on</span>
|
||||||
|
</IonCol>
|
||||||
|
</IonRow>
|
||||||
|
<IonRow class="right-align">
|
||||||
|
<IonCol size="auto" class="my-msg">
|
||||||
|
<b>Simon: </b>
|
||||||
|
<span>my photo jet</span>
|
||||||
|
</IonCol>
|
||||||
|
</IonRow>
|
||||||
|
</IonGrid>
|
||||||
|
</IonContent>
|
||||||
|
<IonFooter class="ion-no-border">
|
||||||
|
<IonGrid>
|
||||||
|
<IonRow>
|
||||||
|
<IonCol size="9">
|
||||||
|
<IonTextarea></IonTextarea>
|
||||||
|
</IonCol>
|
||||||
|
<IonCol size="3" class="send-msg">
|
||||||
|
<IonButton expand="block" color="primary" class="send-button">
|
||||||
|
Send
|
||||||
|
</IonButton>
|
||||||
|
</IonCol>
|
||||||
|
</IonRow>
|
||||||
|
</IonGrid>
|
||||||
|
</IonFooter>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Chat;
|
||||||
Loading…
Reference in New Issue