Skip to content

Commit

Permalink
Merge pull request #113 from davideast/firebase-ssr-flaky-chat-network
Browse files Browse the repository at this point in the history
Server-side rendering, custom element-ing, realtiming, flaky network …
  • Loading branch information
surma authored Feb 22, 2018
2 parents 5490755 + 9042749 commit cb21b7c
Show file tree
Hide file tree
Showing 14 changed files with 4,868 additions and 0 deletions.
5 changes: 5 additions & 0 deletions firebase-firestore-comments/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"plugins": [
"transform-es2015-modules-commonjs"
]
}
5 changes: 5 additions & 0 deletions firebase-firestore-comments/.firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "supercharged-comments"
}
}
5 changes: 5 additions & 0 deletions firebase-firestore-comments/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.vscode
functions
node_modules
public
firebase-debug.log
11 changes: 11 additions & 0 deletions firebase-firestore-comments/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"hosting": {
"public": "public",
"rewrites": [
{
"source": "**",
"function": "supercharged"
}
]
}
}
25 changes: 25 additions & 0 deletions firebase-firestore-comments/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "supercharged",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "yarn build:client && yarn build:server && yarn build:components && yarn babel:components",
"build:server": "cpx src/server/**/* functions",
"build:client": "cpx src/client/**/* public",
"build:components": "cpx src/components/**/* public/components",
"babel:components": "babel src/components -d functions/components",
"serve": "firebase serve --only functions,hosting"
},
"dependencies": {
"express": "^4.16.2",
"firebase": "^4.9.0",
"firebase-functions": "^0.8.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"cpx": "^1.5.0",
"firebase-tools": "~3.17.4"
}
}
46 changes: 46 additions & 0 deletions firebase-firestore-comments/src/client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { LoginButton } from './components/sc-login.js';
import { CommentForm } from './components/sc-comment-form.js';
import { CommentList } from './components/sc-comment-list.js';
import { Comment } from './components/sc-comment.js';

customElements.define('sc-login', LoginButton);
customElements.define('sc-comment-form', CommentForm);
customElements.define('sc-comment-list', CommentList);
customElements.define('sc-comment', Comment);

const scLogin = document.querySelector('sc-login');
const scForm = document.querySelector('sc-comment-form');

scForm.addEventListener('comment-sent', e => {
const commentsRef = firebase.firestore().collection('comments');
commentsRef.add({
text: e.detail.text,
photoUrl: scLogin.user.photoURL,
authorName: scLogin.user.displayName,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
});

scLogin.addEventListener('on-auth', e => {
if(e.detail) {
scLogin.classList.add('sc-hidden');
} else {
scLogin.classList.remove('sc-hidden');
}
});
46 changes: 46 additions & 0 deletions firebase-firestore-comments/src/components/sc-comment-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SCElement } from './sc-element.js';

const html = String.raw;

export class CommentForm extends SCElement {
static template() {
return html`
<textarea></textarea>
<button id="btnSend" class="sc-btn">Send</button>
`;
}
static component() {
return html`
<sc-comment-form>
${this.template()}
</sc-comment-form>
`;
}
connectedCallback() {
this.btnSend = this.querySelector('#btnSend');
this.textarea = this.querySelector('textarea');
this.btnSend.addEventListener('click', e => {
const text = this.textarea.value;
const detail = { text };
const event = new CustomEvent('comment-sent', { detail });
this.dispatchEvent(event);
this.textarea.value = '';
});
}
}
55 changes: 55 additions & 0 deletions firebase-firestore-comments/src/components/sc-comment-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SCElement } from './sc-element.js';
import { Comment } from './sc-comment.js';

const html = String.raw;

export class CommentList extends SCElement {
static component(state) {
return html`
<sc-comment-list>
${state}
</sc-comment-list>
`;
}

connectedCallback() {
this.commentsRef = firebase.firestore().collection('comments');
this.commentsRef.orderBy('timestamp').onSnapshot(snap => {
snap.docChanges.forEach(change => {
const elInDOM = this.querySelector(`#_${change.doc.id}`);
switch(change.type) {
case 'added':
if(elInDOM) { return; }
this.addComment(change.doc);
break;
case 'removed':
elInDOM.remove();
break;
}
});
});
}

addComment(doc) {
const element = document.createElement('sc-comment');
element.id = `_${doc.id}`;
element.innerHTML = Comment.template(doc.data());
this.appendChild(element);
}
}
38 changes: 38 additions & 0 deletions firebase-firestore-comments/src/components/sc-comment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SCElement } from './sc-element.js';

const html = String.raw;

export class Comment extends SCElement {
static template(state) {
return html`
<div class="sc-author">
<img class="sc-circle-avatar" src="${state.photoUrl}" alt="Profile Photo">
<div class="sc-author-name">${state.authorName}</div>
</div>
<div class="sc-comment-text">${state.text}</div>
`;
}
static component(state, id) {
return html`
<sc-comment id="_${id}">
${this.template(state)}
</sc-comment>
`;
}
}
34 changes: 34 additions & 0 deletions firebase-firestore-comments/src/components/sc-element.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// are you node?
// yah
// umm... use this HTMLElement class I made
// okay... sure?

// are you browser?
// yah
// umm... use your HTMLElement class
// okay... I was gonna do that anyways? thx?

let _HTMLElement;
if(typeof process !== 'undefined') {
_HTMLElement = class HTMLElement { }
} else {
_HTMLElement = HTMLElement;
}

export class SCElement extends _HTMLElement { }
46 changes: 46 additions & 0 deletions firebase-firestore-comments/src/components/sc-login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const html = String.raw;

export class LoginButton extends HTMLElement {
static template() {
return html`
<button id="btnLogin" class="sc-btn">Login</button>
`;
}
connectedCallback() {
this.appendChild(template.content.cloneNode(true));
this.auth = firebase.auth();
this.btnLogin = this.querySelector('#btnLogin');

this.auth.onAuthStateChanged(user => {
const event = new CustomEvent('on-auth', { detail: user });
this.user = user;
this.dispatchEvent(event);
});

this.btnLogin.addEventListener('click', e => {
const google = new firebase.auth.GoogleAuthProvider();
this.auth.signInWithRedirect(google);
});
}
}

let template = document.createElement('template');
template.innerHTML = LoginButton.template();

Loading

0 comments on commit cb21b7c

Please sign in to comment.