implemented service workers and indexdb to handle data on the front end, still needs to be cleaned up but it works

sql-version-freeze
Ro 6 years ago
parent 1f52df297a
commit bc1b4fa3e8

@ -26,7 +26,9 @@ const dateUtils = new DateUtils();
const stringUtils = new StringUtils();
const rightsManager = new RightsManager();
var uploadPath = "./content/blog-images/" + dateUtils.getDate('year', new Date()) + "/" + dateUtils.getDate('month', new Date());
var PouchDB = require('pouchdb');
var Sequelize = require('sequelize');
const Op = Sequelize.Op;
var _ = require('lodash');
fs.ensureDir(uploadPath, function(err)
{
//console.log(err) // => null
@ -52,26 +54,110 @@ var post_upload = multer(
{
storage: storage
}).array('post_image');
router.post('/couch', function(req, res, next)
router.post("/sync", (req, res, next) =>
{
console.log(req.body)
var db = new PouchDB(req.body.name)
var remote = new PouchDB('http://hnic:myShit!@localhost:5984/forfipamo');
let payload = req.body;
Models.User.findById(req.session.user.id).then((user) =>
{
if (rightsManager.check(user.role, OBJECT_POST, TASK_UPDATE))
{
for (let index = 0; index < payload.length; index++)
{
const item = payload[index];
Models.FreshPost.findOne(
{
where:
{
"post": {
[Op.contains]: {
slug: item.post.slug
}
}
}
}).then(found =>{
if (!_.isEqual(item.post, found.post) ) found.update(item)
}).catch(err=>{
Models.FreshPost.create(item).then(fresh =>{
//console.log(fresh)
})
db.sync(remote).then(result =>
})
}
res.json(
{
message: "postsSynced"
});
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
})
router.post('/jsontest-edit', function(req, res, next)
{
Models.FreshPost.findById(req.body.id).then(fresh =>
{
fresh.update(req.body)
res.json(
{
message: "jsonPostUpdated"
});
}).catch(err =>
{
console.log(result);
}).catch(err=>{
console.log(err)
})
res.json(
{
message: "yes khaleesi"
});
})
router.get('/', function(req, res, next)
{
Models.Post.findAll(
{
order: [
['id']
]
}).then(function(posts)
{
var count = posts.length;
var list = [];
for (let index = 0; index < count; index++)
{
let item = posts[index];
let post = {
post:
{
uuid: item.uuid,
title: item.title,
slug: item.slug,
tags: item.tags,
feature: item.feature_image,
author: "Are0h",
html: item.html,
plaintext: item.plaintext,
featured: item.featured,
published: item.published,
page: item.page,
created: item.created_at,
updated: item.updated_at,
deleted: false
}
}
list.push(post);
}
res.json(list);
}).catch(function(err)
{
//next(err);
})
})
router.get('/json', function(req, res, next)
{
Models.FreshPost.findAll(
{
order: [
['id', 'DESC']

@ -9,6 +9,7 @@ var MemoryStore = require('memorystore')(session)
var flash = require('connect-flash');
var theme = "default";
var app = express();
var request = require('request');
// view engine setup
app.set('views', path.join(__dirname, '../themes'));
app.set('view engine', 'pug');
@ -16,14 +17,15 @@ app.use(express.static(__dirname + '../content/folio-images'));
app.use(logger('dev'));
// wherever your db lives
var DATABASE_URL = 'http://localhost:5984/forfipamo';
var DATABASE_URL = 'http://are0h:pa$$@localhost:5984/forfipamo';
// middleware itself, preceding any parsers
app.use(function(req, res, next){
var proxy_path = req.path.match(/^\/forfipamo(.*)$/);
if(proxy_path){
var db_url = DATABASE_URL + proxy_path[1];
console.log("YUP "+proxy_path[1]);
console.log("YUP "+db_url);
console.log("METH: "+req)
req.pipe(request({
uri: db_url,
method: req.method
@ -33,10 +35,11 @@ app.use(function(req, res, next){
}
});
app.use(bodyParser.json());
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded(
{
extended: false
extended: false,
limit: '50mb'
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../content')));

@ -0,0 +1,33 @@
module.exports = function (sequelize, DataTypes) {
var FreshPost = sequelize.define('FreshPost', {
post: {
type: DataTypes.JSONB
}
}, {
timestamps: false,
// don't delete database entries but set the newly added attribute deletedAt
// to the current date (when deletion was done). paranoid will only work if
// timestamps are enabled
paranoid: false,
// don't use camelcase for automatically added attributes but underscore style
// so updatedAt will be updated_at
underscored: true,
// disable the modification of table names; By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following
freezeTableName: false,
// define the table's name
tableName: 'FreshPosts',
// Enable optimistic locking. When enabled, sequelize will add a version count attriubte
// to the model and throw an OptimisticLockingError error when stale instances are saved.
// Set to true or a string with the attribute name you want to use to enable.
version: false
});
return FreshPost;
};

@ -15,6 +15,7 @@ const dateUtils = new DateUtils();
router.get('/:page?', function (req, res) {
var pageNum = req.params.page;
if (pageNum == "" || pageNum == null) pageNum = 1;
console.log(pageNum);
var offset = ((pageNum * 5) - 5);
if (req.session.user) {
Models.Post.findAll({
@ -49,6 +50,7 @@ router.get('/:page?', function (req, res) {
//next(err);
})
} else {
console.log("REDIRECT")
res.redirect('/@/dashboard');
}
});

@ -15,6 +15,7 @@ export const POST_ERROR = 'postError';
export const POST_ADDED = 'postAdded';
export const POST_UPDATED = 'postUpdated';
export const POST_DELETED = 'postImageAdded';
export const POSTS_SYNCED = 'postsSynced';
class DataEvent
{

@ -10,6 +10,12 @@ import EventEmitter from '../events/EventEmitter';
import * as EditorEvent from '../events/EditorEvent';
class TextEditor extends EventEmitter
{
/**
* Text Editor UI Component
* @constructor
* @param {object} textEditor - Text area that will edit text
* @param {number} scrollLimit - YPos where editor position will become fixed
*/
//--------------------------
// constructor
//--------------------------

882
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -27,6 +27,7 @@
"connect-flash": "latest",
"cookie-parser": "~1.3.3",
"debug": "^4.1.0",
"dexie": "^2.0.4",
"entypo": "^2.1.0",
"esm": "^3.0.84",
"express": "^4.16.4",
@ -34,6 +35,7 @@
"fs-extra": "latest",
"highlight.js": "^9.13.1",
"jsdom": "^12.2.0",
"lodash": "^4.17.11",
"mailgun-js": "^0.18.0",
"markdown-it": "^8.4.1",
"memorystore": "^1.6.0",
@ -42,26 +44,28 @@
"nodemailer": "latest",
"pg": "^7.5.0",
"pg-hstore": "^2.3.2",
"pouchdb": "^7.0.0",
"prismjs": "^1.15.0",
"pug": "latest",
"reframe.js": "^2.2.1",
"request": "^2.83.0",
"request": "^2.88.0",
"sanitize-html": "^1.19.1",
"scrape-metadata": "^2.0.0",
"sequelize": "^4.37.6",
"sequelize-cli": "^5.3.0",
"serve-favicon": "latest",
"tiny-date-picker": "^3.2.6",
"uuid": "^3.2.1"
"uuid": "^3.2.1",
"workbox-sw": "^3.6.3"
},
"devDependencies": {
"@babel/cli": "^7.1.2",
"@babel/core": "^7.1.2",
"@babel/preset-env": "^7.1.0",
"@vue/component-compiler-utils": "^2.3.0",
"animejs": "^2.2.0",
"babel-preset-env": "^1.7.0",
"bulma.styl": "^0.6.11",
"scramble-text": "0.0.8"
"scramble-text": "0.0.8",
"stylus": "^0.54.5",
"vue-template-compiler": "^2.5.17"
}
}

@ -1584,6 +1584,8 @@ svg.icons {
display: flex;
align-items: center;
justify-content: center;
display: none;
visibility: hidden;
}
#loader i {
color: #f5ab35;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -1,3 +1,4 @@
-var versioning = Math.round(new Date().getTime()/1000)
doctype html
html(xmlns='http://www.w3.org/1999/xhtml', lang='en', xml:lang="en")
head
@ -8,7 +9,7 @@ html(xmlns='http://www.w3.org/1999/xhtml', lang='en', xml:lang="en")
meta(http-equiv="content-type", content="text/html; charset=utf-8")
//meta(property="og:image" content="https://thetwelfth.house/base-assets/images/current.png")
//meta(name="twitter:image" content="https://thetwelfth.house/base-assets/images/current.png")
link(rel='stylesheet', href='/dash/assets/css/dash.css', type='text/css')
link(rel='stylesheet', href="/dash/assets/css/dash.css", type='text/css')
body
#loader
i.fa.fa-cog.fa-spin.fa-4x.fa-fw

@ -9,8 +9,8 @@ import DataUtils,
}
from '../../../../brain/tools/utilities/DataUtils';
import * as DataEvent from '../../../../brain/tools/events/DataEvent';
import DisplayManager from './controllers/DisplayManager';
import PouchDB from 'pouchdb';
import DashManager from './controllers/DashManager';
import Dexie from 'dexie';
export default class Base
{
//--------------------------
@ -20,54 +20,75 @@ export default class Base
constructor()
{
var self = this;
var admin = [];
var folio = [];
var displayManager = [];
this.dashManager = [];
this.dataUtils = new DataUtils();
this.settings = [];
//this.start();
this.loadSettings();
this.cacheAssets();
this.storeLocalData();
}
start()
{
this.displayManager = new DisplayManager();
this.dashManager = new DashManager();
}
//--------------------------
// methods
//--------------------------
loadSettings()
storeLocalData()
{
var self = this;
this.dataUtils.request('/api/post', DataEvent.SETTINGS_LOADED).then((response) =>
this.dataUtils.request('/api/post/json', DataEvent.SETTINGS_LOADED).then((response) =>
{
//let posts = JSON.parse(response['request'].response);
var db = new PouchDB('forfipamo');
let posts = JSON.parse(response.request['response']);
/**
self.dataUtils.request("/api/post/couch", DataEvent.POST_IMAGE_ADDED, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, db).then((response) =>
let list = [];
for (let index = 0; index < posts.length; index++) {
list.push({id:posts[index].id ,post:posts[index].post});
}
var fipamoPosts = new Dexie("fipamo_posts");
fipamoPosts.version(1).stores(
{
console.log(JSON.parse(response.request['response']).url);
}).catch((err) =>
postList: 'id, post'
});
fipamoPosts.postList.clear().then(result =>
{
console.log(err)
fipamoPosts.postList.bulkAdd(list).then(key =>
{
self.start();
fipamoPosts.postList.toArray(array =>
{
console.log(array[21].post.title);
})
}).catch(Dexie.BulkError, e =>
{
console.log(e);
})
})
*/
var remote = new PouchDB('http://are0h:pa$$@localhost:5984/forfipamo');
db.sync(remote).then(result=>{
console.log(result);
}).catch(err=>{
console.log(err);
})
//console.log(posts.length);
this.start();
//transfer
}).catch((err) =>
{
//console.log(err);
console.log(err);
});
}
cacheAssets()
{
if ('serviceWorker' in navigator)
{
window.addEventListener('load', function()
{
navigator.serviceWorker.register('https://fipamo.local/tim-duncan.js?'+Math.round(new Date().getTime()/1000)).then(function(registration)
{
//console.log('Service worker successfully registered on scope', registration.scope);
}).catch(function(error)
{
//console.log('Service worker failed to register');
});
});
}
else
{
//console.log("NOPE")
}
}
//--------------------------
// event handlers
//--------------------------

@ -1,40 +1,93 @@
import DataUtils, {
import DataUtils,
{
REQUEST_TYPE_GET,
REQUEST_TYPE_PUT,
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
} from '../../../../../brain//tools/utilities/DataUtils';
}
from '../../../../../brain//tools/utilities/DataUtils';
import * as DataEvent from '../../../../../brain//tools/events/DataEvent';
import StringUtils from '../../../../../brain//tools/utilities/StringUtils';
class PostActions {
import Dexie from 'dexie';
class PostActions
{
//--------------------------
// constructor
//--------------------------
constructor() {
constructor()
{
var folio = [];
this.dataUtils = new DataUtils();
}
//--------------------------
// methods
//--------------------------
start() {}
start()
{}
sync(files)
{
let self = this;
return new Promise((resolve, reject) =>
{
var syncData = new FormData();
var postList = '';
for (var i = 0; i < files.length; i++)
{
var file = files[i];
// Check the file type.
if (!file.type.match('image.*'))
{
continue;
}
// Add the file to the request.
syncData.append('feature_image', file, file.name);
}
var fipamoPosts = new Dexie("fipamo_posts");
fipamoPosts.version(1).stores(
{
postList: 'id,post'
});
submitPost(edit, uploadFiles) {
fipamoPosts.postList.toArray(array =>
{
console.log(array);
self.dataUtils.request('/api/post/sync', DataEvent.POSTS_SYNCED, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, array).then((response) =>
{
resolve(
{
response
})
}).catch((err) =>
{
reject(
{
err
});
})
//console.log("LIST", postList);
})
})
}
submitPost(edit, uploadFiles)
{
let self = this;
return new Promise(function (resolve, reject) {
return new Promise(function(resolve, reject)
{
//collect form data
//if(!this.validateForm())
var postData = new FormData();
//let projectImages = document.getElementById('projectImages');
//var fileSelect = projectImages;
var files = uploadFiles;
for (var i = 0; i < files.length; i++) {
for (var i = 0; i < files.length; i++)
{
var file = files[i];
// Check the file type.
if (!file.type.match('image.*')) {
if (!file.type.match('image.*'))
{
continue;
}
// Add the file to the request.
@ -52,45 +105,53 @@ class PostActions {
postData.append("status_page", document.getElementById('option-page').getAttribute('data-active'));
postData.append("status_feature", document.getElementById('option-feature').getAttribute('data-active'));
postData.append("status_published", document.getElementById('option-published').getAttribute('data-active'));
let postURL;
let postEventType;
if (edit) {
if (edit)
{
let postID = document.getElementById('edit-update').getAttribute('data-id');
postURL = "/api/post/update/" + postID;
postEventType = DataEvent.POST_UPDATED;
} else {
}
else
{
postURL = "/api/post/add";
postEventType = DataEvent.POST_ADDED;
}
self.dataUtils.request(postURL, postEventType, REQUEST_TYPE_POST, CONTENT_TYPE_FORM, postData)
.then((response) => {
resolve({
response
})
}).catch((err) => {
reject({
err
});
self.dataUtils.request(postURL, postEventType, REQUEST_TYPE_POST, CONTENT_TYPE_FORM, postData).then((response) =>
{
resolve(
{
response
})
}).catch((err) =>
{
reject(
{
err
});
})
});
}
deletePost() {
deletePost()
{
let self = this;
let postID = document.getElementById('edit-update').getAttribute('data-id');
return new Promise(function (resolve, reject) {
self.dataUtils.request("/api/post/delete/" + postID, DataEvent.POST_DELETED, REQUEST_TYPE_POST, CONTENT_TYPE_FORM)
.then((response) => {
resolve({
response
})
}).catch((err) => {
reject({
err
});
return new Promise(function(resolve, reject)
{
self.dataUtils.request("/api/post/delete/" + postID, DataEvent.POST_DELETED, REQUEST_TYPE_POST, CONTENT_TYPE_FORM).then((response) =>
{
resolve(
{
response
})
}).catch((err) =>
{
reject(
{
err
});
})
})
//this.dataUtils.re
}
@ -98,7 +159,8 @@ class PostActions {
// event handlers
//--------------------------
}
export {
export
{
PostActions as
default
}

@ -0,0 +1,40 @@
import PostEditor from './PostEditor';
import Animate from '../../../../../brain/tools/effects/Animate';
import PostIndex from './PostIndex';
export default class DashManager {
//--------------------------
// constructor
//--------------------------
constructor() {
this.currentDisplay = '';
this.urlPieces = document.URL.split("/");
this.chooseDisplay(this.urlPieces[5], this.urlPieces[6]);
}
//--------------------------
// methods
//--------------------------
start() {
let self = this;
}
chooseDisplay(section, page) {
this.currentDisplay = '';
switch (section) {
case 'posts':
this.currentDisplay = new PostIndex(page);
break;
default:
// just chill
break;
}
this.start();
}
//--------------------------
// event handlers
//--------------------------
}

@ -1,8 +1,4 @@
import * as DataEvent from '../tools/events/DataEvent.jsx';
import Animate from '../tools/effects/Animate.jsx';
import * as Ease from '../tools/effects/Animate.jsx';
import TextEffects from '../tools/effects/TextEffects.jsx';
import TaskFipamo from '../tasks/TaskFipamo.jsx';
class DisplayAdminFipamo {
//--------------------------
// constructor
@ -15,34 +11,7 @@ class DisplayAdminFipamo {
//--------------------------
start() {
document.getElementById("saved-sumbit-btn").addEventListener('click', f => {
console.log('CLICKED');
let edit = false;
if (f.target.getAttribute('data-action') == 'saved-edit')
edit = true;
new TaskFipamo().submitLink(edit).then((response) => {
let note = JSON.parse(response['response']['request'].response);
if(note.message == 'link added' || note.message == 'bookmark updated')
{
switch(note.message)
{
case 'link added':
document.getElementById('saved_text').value = ''
break
case 'bookmark updated':
document.getElementById('saved_text').value = 'updated'
break
}
}else{
console.log(note);
}
}).catch((err) => {
//console.log(err)
});
});
}
//--------------------------

@ -1,74 +0,0 @@
//TOOLS
import DataUtils, {
REQUEST_TYPE_GET,
REQUEST_TYPE_PUT,
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
} from '../../../../../brain/tools/utilities/DataUtils';
import PostEditor from './PostEditor';
import Animate from '../../../../../brain/tools/effects/Animate';
class DisplayManager {
//--------------------------
// constructor
//--------------------------
constructor() {
this.dataUtils = new DataUtils();
this.currentDisplay = '';
this.urlPieces = document.URL.split("/");
//grab url so system knows what to display
this.chooseDisplay(this.urlPieces[5], this.urlPieces[6]);
}
//--------------------------
// methods
//--------------------------
start() {
let self = this;
// new stuff
new Animate().object({
targets: document.getElementById('loader'),
duration: 300,
opacity: 0,
easing: 'easeInOutQuad',
complete: function () {
document.getElementById('loader').style.display = 'none';
document.getElementById('loader').style.visibility = 'hidden';
new Animate().object({
targets: document.getElementById('header'),
duration: 10,
opacity: 1,
easing: 'easeInOutQuad',
complete: function () {
document.getElementById('loader').style.display = 'none';
document.getElementById('loader').style.visibility = 'hidden';
}
});
}
});
}
chooseDisplay(section, page) {
this.currentDisplay = '';
switch (section) {
case 'posts':
this.currentDisplay = new PostEditor();
break;
default:
// just chill
break;
}
this.start();
}
//--------------------------
// event handlers
//--------------------------
}
export {
DisplayManager as
default
}

@ -16,6 +16,7 @@ import * as EditorEvent from '../../../../../brain/tools/events/EditorEvent';
import TinyDatePicker from 'tiny-date-picker';
import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
import TextEditor from '../../../../../brain/tools/ui/TextEditor';
import Dexie from 'dexie';
class PostEditor
{
//--------------------------
@ -29,6 +30,17 @@ class PostEditor
this.anim = new Animate();
this.dataUtils = new DataUtils
this.dateUtils = new DateUtils();
this.urlPieces = document.URL.split("/");
this.post = [];
var fipamoPosts = new Dexie("fipamo_posts");
fipamoPosts.version(1).stores(
{
postList: 'id, post'
});
fipamoPosts.postList.get(1).then(post=>{
});
if (document.getElementById('edit-post-text'))
{
this.editor = new TextEditor(document.getElementById('edit-post-text'), document.getElementById('header').offsetHeight + document.getElementById('post-header').offsetHeight + document.getElementById('post-feature').offsetHeight);
@ -55,30 +67,6 @@ class PostEditor
start()
{
let self = this;
new Animate().object(
{
targets: document.getElementById('loader'),
duration: 300,
opacity: 0,
easing: 'easeInOutQuad',
complete: function()
{
document.getElementById('loader').style.display = 'none';
document.getElementById('loader').style.visibility = 'hidden';
new Animate().object(
{
targets: document.getElementById('header'),
duration: 10,
opacity: 1,
easing: 'easeInOutQuad',
complete: function()
{
if (document.getElementById('the-intro')) document.getElementById('the-intro').style.opacity = 1;
if (document.getElementById('blog-entry')) document.getElementById('blog-entry').style.opacity = 1;
}
});
}
});
if (document.getElementById('featured-image-drop'))
{
document.getElementById('featured-image-drop').addEventListener('dragover', this.handleDragOver, false);
@ -129,7 +117,18 @@ class PostEditor
case EditorEvent.EDITOR_SAVE:
case EditorEvent.EDITOR_UPDATE:
let edit = false;
if (e == EditorEvent.EDITOR_UPDATE) edit = true;
//if (e == EditorEvent.EDITOR_UPDATE) edit = true;
new PostActions().sync(PostEditor.uploadFiles).then((response) =>
{
let note = JSON.parse(response['response']['request'].response);
//this.editor.notify(note.message, note.postID);
//if (note.message == DataEvent.POST_ADDED) window.location = "/@/dashboard/posts/edit/" + note.postID;
}).catch((err) =>
{
console.log(err)
});
/*
new PostActions().submitPost(edit, PostEditor.uploadFiles).then((response) =>
{
let note = JSON.parse(response['response']['request'].response);
@ -139,6 +138,7 @@ class PostEditor
{
console.log(err)
});
*/
break;
case EditorEvent.EDITOR_DELETE:
if (confirm('Aye! You know you\'re deleting this post, right?'))

@ -1,58 +1,38 @@
import DataUtils, {
REQUEST_TYPE_GET,
REQUEST_TYPE_PUT,
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
} from '../tools/utilities/DataUtils';
import * as DataEvent from '../tools/events/DataEvent';
import ProjectFolio from '../tasks/ProjectFolio';
import TextEffects from '../tools/effects/TextEffects';
import Animate from '../tools/effects/Animate';
import * as Ease from '../tools/effects/Animate';
import DisplayAdminBlog from './PostEditor'
import DisplayAdminFipamo from './DisplayAdminFipamo';
export default class DisplayAdmin {
import Animate from '../../../../../brain/tools/effects/Animate';
import PostEditor from './PostEditor';
export default class PostIndex
{
//--------------------------
// constructor
//--------------------------
constructor(section, page) {
this.section = section;
this.page = page;
this.current = null;
constructor(page)
{
this.currentPage = null;
this.choosePage(page);
this.start();
}
//--------------------------
// methods
//--------------------------
start() {
start()
{
let self = this;
new Animate().object({
targets: document.getElementById('loader'),
duration: 300,
opacity: 0,
easing: 'easeInOutQuad',
complete: function () {
document.getElementById('loader').style.display = 'none';
document.getElementById('loader').style.visibility = 'hidden';
new Animate().object({
targets: document.getElementById('header'),
duration: 10,
opacity: 1,
easing: 'easeInOutQuad',
complete: function () {
document.getElementById('loader').style.display = 'none';
document.getElementById('loader').style.visibility = 'hidden';
}
});
}
});
}
choosePage(page)
{
this.currentPage = '';
switch (page)
{
case "edit":
case "add":
this.currentPage = new PostEditor();
break;
default:
//just chill
break;
}
}
//--------------------------
// event handlers
//--------------------------
}
DisplayAdmin.uploadFiles = [];

@ -24,6 +24,8 @@ svg.icons
display flex
align-items center
justify-content center
display none
visibility hidden
i
color $tertiary

@ -0,0 +1,35 @@
importScripts('./workbox-sw.js');
if (workbox) {
//console.log(`Yay! Workbox is loaded 🎉`);
} else {
//console.log(`Boo! Workbox didn't load 😬`);
}
workbox.routing.registerRoute(
new RegExp('.*\.js'),
workbox.strategies.networkFirst({
cacheName: 'script'
})
);
workbox.routing.registerRoute(
new RegExp('.*\.css'),
workbox.strategies.networkFirst({
cacheName: 'style'
})
);
workbox.routing.registerRoute(
new RegExp('.*\.(?:png|jpg|jpeg|svg|gif)'),
workbox.strategies.networkFirst({
cacheName: 'images'
})
);
workbox.routing.registerRoute(
new RegExp('/@/dashboard'),
workbox.strategies.networkFirst({
cacheName: 'pages'
}));

@ -0,0 +1,3 @@
var workbox=function(){"use strict";try{self.workbox.v["workbox:sw:3.6.3"]=1}catch(t){}const t="https://storage.googleapis.com/workbox-cdn/releases/3.6.3",e={backgroundSync:"background-sync",broadcastUpdate:"broadcast-cache-update",cacheableResponse:"cacheable-response",core:"core",expiration:"cache-expiration",googleAnalytics:"google-analytics",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams"};return new class{constructor(){return this.v={},this.t={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.e=this.t.debug?"dev":"prod",this.s=!1,new Proxy(this,{get(t,s){if(t[s])return t[s];const o=e[s];return o&&t.loadModule(`workbox-${o}`),t[s]}})}setConfig(t={}){if(this.s)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.t,t),this.e=this.t.debug?"dev":"prod"}skipWaiting(){self.addEventListener("install",()=>self.skipWaiting())}clientsClaim(){self.addEventListener("activate",()=>self.clients.claim())}loadModule(t){const e=this.o(t);try{importScripts(e),this.s=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}o(e){if(this.t.modulePathCb)return this.t.modulePathCb(e,this.t.debug);let s=[t];const o=`${e}.${this.e}.js`,r=this.t.modulePathPrefix;return r&&""===(s=r.split("/"))[s.length-1]&&s.splice(s.length-1,1),s.push(o),s.join("/")}}}();
//# sourceMappingURL=workbox-sw.js.map

@ -0,0 +1 @@
{"version":3,"names":[],"mappings":"","sources":["packages/workbox-sw/browser.mjs"],"sourcesContent":["var workbox=function(){\"use strict\";try{self.workbox.v[\"workbox:sw:3.6.3\"]=1}catch(t){}const t=\"https://storage.googleapis.com/workbox-cdn/releases/3.6.3\",e={backgroundSync:\"background-sync\",broadcastUpdate:\"broadcast-cache-update\",cacheableResponse:\"cacheable-response\",core:\"core\",expiration:\"cache-expiration\",googleAnalytics:\"google-analytics\",navigationPreload:\"navigation-preload\",precaching:\"precaching\",rangeRequests:\"range-requests\",routing:\"routing\",strategies:\"strategies\",streams:\"streams\"};return new class{constructor(){return this.v={},this.t={debug:\"localhost\"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.e=this.t.debug?\"dev\":\"prod\",this.s=!1,new Proxy(this,{get(t,s){if(t[s])return t[s];const o=e[s];return o&&t.loadModule(`workbox-${o}`),t[s]}})}setConfig(t={}){if(this.s)throw new Error(\"Config must be set before accessing workbox.* modules\");Object.assign(this.t,t),this.e=this.t.debug?\"dev\":\"prod\"}skipWaiting(){self.addEventListener(\"install\",()=>self.skipWaiting())}clientsClaim(){self.addEventListener(\"activate\",()=>self.clients.claim())}loadModule(t){const e=this.o(t);try{importScripts(e),this.s=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}o(e){if(this.t.modulePathCb)return this.t.modulePathCb(e,this.t.debug);let s=[t];const o=`${e}.${this.e}.js`,r=this.t.modulePathPrefix;return r&&\"\"===(s=r.split(\"/\"))[s.length-1]&&s.splice(s.length-1,1),s.push(o),s.join(\"/\")}}}();\n"],"file":"workbox-sw.js"}
Loading…
Cancel
Save