Skip to content

Instantly share code, notes, and snippets.

@davideast
Last active February 8, 2019 18:08
Show Gist options
  • Select an option

  • Save davideast/fe9cf78ce9ef741d13178d085c45cad3 to your computer and use it in GitHub Desktop.

Select an option

Save davideast/fe9cf78ce9ef741d13178d085c45cad3 to your computer and use it in GitHub Desktop.

Revisions

  1. davideast revised this gist Feb 8, 2019. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions sync.ts
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    // https://stackblitz.com/edit/typescript-h68plq?file=sync.ts

    import { sortedChanges, snapToData, collectionChanges } from 'rxfire/firestore';
    import { map } from 'rxjs/operators';

    @@ -27,6 +29,7 @@ export function syncWithElements(app, { collectionName, parent, classList, confi
    records.forEach(record => {
    switch (record.type) {
    case 'added': {
    // TODO: Find a way to template the element
    const element = document.createElement('div');
    element.classList.add(...classList);
    syncDOM(element, config, record)
  2. davideast revised this gist Feb 8, 2019. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions index.ts
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    // Import stylesheets
    import './style.css';
    // https://stackblitz.com/edit/typescript-h68plq?file=index.ts

    import firebase from 'firebase/app';
    import 'firebase/firestore';
    import { syncWithElements } from './sync';
  3. davideast revised this gist Feb 8, 2019. 2 changed files with 6 additions and 3 deletions.
    4 changes: 3 additions & 1 deletion index.ts
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,12 @@
    // Import stylesheets
    import './style.css';
    import firebase from 'firebase/app';
    import 'firebase/firestore';
    import { syncWithElements } from './sync';

    const app = firebase.initializeApp({ projectId: "alwaysbecaching" });

    syncWithElements(app, {
    const unsub = syncWithElements(app, {
    parent: document.querySelector('.container'),
    collectionName: 'boxes',
    classList: ['box'],
    5 changes: 3 additions & 2 deletions sync.ts
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@ export function syncWithElements(app, { collectionName, parent, classList, confi

    const ref = app.firestore().collection(collectionName);
    const idMap = config.id || 'id';
    return collectionChanges(ref, events).pipe(
    const sub = collectionChanges(ref, events).pipe(
    map(changes => changes.map(c => ({ type: c.type, ...snapToData(c.doc, idMap) })) as any[])
    ).subscribe(records => {
    records.forEach(record => {
    @@ -45,5 +45,6 @@ export function syncWithElements(app, { collectionName, parent, classList, confi
    }
    }
    });
    })
    });
    return sub.unsubscribe;
    }
  4. davideast revised this gist Feb 8, 2019. 1 changed file with 18 additions and 0 deletions.
    18 changes: 18 additions & 0 deletions index.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    import firebase from 'firebase/app';
    import 'firebase/firestore';
    import { syncWithElements } from './sync';

    const app = firebase.initializeApp({ projectId: "alwaysbecaching" });

    syncWithElements(app, {
    parent: document.querySelector('.container'),
    collectionName: 'boxes',
    classList: ['box'],
    config: {
    id: 'id',
    text: 'innerText',
    bg: 'style.backgroundColor',
    color: 'style.color'
    },
    events: ['added', 'modified']
    });
  5. davideast created this gist Feb 8, 2019.
    49 changes: 49 additions & 0 deletions sync.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    import { sortedChanges, snapToData, collectionChanges } from 'rxfire/firestore';
    import { map } from 'rxjs/operators';

    export function syncDOM(element, config, values) {
    for (let key in values) {
    if (values.hasOwnProperty(key)) {
    const mapped = config[key];
    if (mapped) {
    if (mapped.indexOf('style.') !== -1) {
    let style = mapped.replace('style.', '');
    element.style[style] = values[key]
    } else {
    element[mapped] = values[key];
    }
    }
    }
    }
    }

    export function syncWithElements(app, { collectionName, parent, classList, config, events = ['added', 'removed', 'modified'] as firebase.firestore.DocumentChangeType[] }) {

    const ref = app.firestore().collection(collectionName);
    const idMap = config.id || 'id';
    return collectionChanges(ref, events).pipe(
    map(changes => changes.map(c => ({ type: c.type, ...snapToData(c.doc, idMap) })) as any[])
    ).subscribe(records => {
    records.forEach(record => {
    switch (record.type) {
    case 'added': {
    const element = document.createElement('div');
    element.classList.add(...classList);
    syncDOM(element, config, record)
    parent.appendChild(element);
    break;
    }
    case 'modified': {
    const element = document.getElementById(record[idMap]);
    syncDOM(element, config, record)
    break;
    }
    case 'removed': {
    const element = document.getElementById(record[idMap]);
    element.remove();
    break;
    }
    }
    });
    })
    }