@cocreate/pwa 1.19.4 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/package.json +1 -1
- package/prettier.config.js +16 -0
- package/src/index.js +106 -96
- package/src/theme.js +57 -0
- package/src/web-share.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
# [1.21.0](https://github.com/CoCreate-app/CoCreate-pwa/compare/v1.20.0...v1.21.0) (2024-12-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* dynamic theme handling ([c2688f2](https://github.com/CoCreate-app/CoCreate-pwa/commit/c2688f2f148f0c68e3693cf932a24976658eb475))
|
|
7
|
+
|
|
8
|
+
# [1.20.0](https://github.com/CoCreate-app/CoCreate-pwa/compare/v1.19.4...v1.20.0) (2024-11-04)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* observer taget has been renamed to selector ([9f13f9d](https://github.com/CoCreate-app/CoCreate-pwa/commit/9f13f9d8e259c790a5b37ba9cc2d1f563cc14484))
|
|
14
|
+
* pretier.config.js and file formating ([77421cc](https://github.com/CoCreate-app/CoCreate-pwa/commit/77421cc3636d3ddb56afc764443c596aaf26e5d9))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* add prettier.config.js and format files ([2cb51a6](https://github.com/CoCreate-app/CoCreate-pwa/commit/2cb51a69aed9023c80102bc586f67916aec06ce3))
|
|
20
|
+
|
|
1
21
|
## [1.19.4](https://github.com/CoCreate-app/CoCreate-pwa/compare/v1.19.3...v1.19.4) (2024-06-12)
|
|
2
22
|
|
|
3
23
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
* For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import observer from
|
|
26
|
-
import localStorage from
|
|
27
|
-
import
|
|
28
|
-
|
|
25
|
+
import observer from "@cocreate/observer";
|
|
26
|
+
import localStorage from "@cocreate/local-storage";
|
|
27
|
+
import "./web-share";
|
|
28
|
+
// import "./theme";
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Warn the page must be served over HTTPS
|
|
@@ -41,104 +41,114 @@ import './web-share'
|
|
|
41
41
|
// }
|
|
42
42
|
|
|
43
43
|
function init() {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
44
|
+
const button = document.querySelector('[actions*="install"]');
|
|
45
|
+
|
|
46
|
+
window.addEventListener("beforeinstallprompt", (event) => {
|
|
47
|
+
window.deferredPrompt = event;
|
|
48
|
+
if (button) button.removeAttribute("hidden");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (button) {
|
|
52
|
+
button.addEventListener("click", async () => {
|
|
53
|
+
// console.log('👍', 'installBtn-clicked');
|
|
54
|
+
const promptEvent = window.deferredPrompt;
|
|
55
|
+
if (!promptEvent) {
|
|
56
|
+
// The deferred prompt isn't available.
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Show the install prompt.
|
|
60
|
+
promptEvent.prompt();
|
|
61
|
+
// Log the result
|
|
62
|
+
const result = await promptEvent.userChoice;
|
|
63
|
+
console.log("👍", "userChoice", result);
|
|
64
|
+
// Reset the deferred prompt variable, since
|
|
65
|
+
// prompt() can only be called once.
|
|
66
|
+
window.deferredPrompt = null;
|
|
67
|
+
// Hide the install button.
|
|
68
|
+
button.setAttribute("hidden", "");
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
window.addEventListener("appinstalled", (event) => {
|
|
73
|
+
// console.log('👍', 'appinstalled', event);
|
|
74
|
+
// Clear the deferredPrompt so it can be garbage collected
|
|
75
|
+
window.deferredPrompt = null;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if ("serviceWorker" in navigator) {
|
|
79
|
+
let workerPath;
|
|
80
|
+
if (window.CoCreateConfig && window.CoCreateConfig.serviceWorker)
|
|
81
|
+
workerPath = window.CoCreateConfig.serviceWorker;
|
|
82
|
+
else
|
|
83
|
+
workerPath =
|
|
84
|
+
localStorage.getItem("serviceWorker") || "/service-worker.js";
|
|
85
|
+
|
|
86
|
+
localStorage.setItem("serviceWorker", workerPath);
|
|
87
|
+
|
|
88
|
+
let cache;
|
|
89
|
+
if (window.CoCreateConfig && window.CoCreateConfig.cache)
|
|
90
|
+
cache = window.CoCreateConfig.cache;
|
|
91
|
+
else cache = localStorage.getItem("cache") || "true";
|
|
92
|
+
|
|
93
|
+
localStorage.setItem("cache", cache);
|
|
94
|
+
workerPath += `?cache=${cache}`;
|
|
95
|
+
|
|
96
|
+
let isPwa = true;
|
|
97
|
+
if (workerPath) {
|
|
98
|
+
navigator.serviceWorker.getRegistrations().then((registrations) => {
|
|
99
|
+
if (registrations.length === 0 || isPwa == true)
|
|
100
|
+
window.addEventListener("load", function () {
|
|
101
|
+
navigator.serviceWorker
|
|
102
|
+
.getRegistration(workerPath)
|
|
103
|
+
.then((registration) => {
|
|
104
|
+
if (
|
|
105
|
+
registration &&
|
|
106
|
+
registration.active &&
|
|
107
|
+
registration.active.scriptURL.includes(
|
|
108
|
+
workerPath
|
|
109
|
+
)
|
|
110
|
+
) {
|
|
111
|
+
console.log("Service Worker Active");
|
|
112
|
+
} else {
|
|
113
|
+
navigator.serviceWorker
|
|
114
|
+
.register(workerPath)
|
|
115
|
+
.then((reg) => {
|
|
116
|
+
reg.onupdatefound = () => {
|
|
117
|
+
const installingWorker =
|
|
118
|
+
reg.installing;
|
|
119
|
+
installingWorker.onstatechange =
|
|
120
|
+
() => {
|
|
121
|
+
// console.log('Service Worker', installingWorker.state);
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
.catch((err) =>
|
|
126
|
+
console.log("SW ERROR", err)
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
123
134
|
}
|
|
124
135
|
|
|
125
|
-
init()
|
|
136
|
+
init();
|
|
126
137
|
|
|
127
138
|
async function persistData() {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
139
|
+
if (navigator.storage && navigator.storage.persist) {
|
|
140
|
+
const result = await navigator.storage.persist();
|
|
141
|
+
// console.log(`Data persisted: ${result}`);
|
|
142
|
+
}
|
|
132
143
|
}
|
|
133
144
|
|
|
134
145
|
observer.init({
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
name: "initPwa",
|
|
147
|
+
observe: ["addedNodes"],
|
|
148
|
+
selector: '[actions="install"]',
|
|
149
|
+
callback: (mutation) => {
|
|
150
|
+
init();
|
|
151
|
+
}
|
|
141
152
|
});
|
|
142
153
|
|
|
143
|
-
|
|
144
|
-
export default { persistData }
|
|
154
|
+
export default { persistData };
|
package/src/theme.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
function applyThemeAttributes() {
|
|
2
|
+
// Detect the current theme (light or dark)
|
|
3
|
+
const isDarkMode = window.matchMedia(
|
|
4
|
+
"(prefers-color-scheme: dark)"
|
|
5
|
+
).matches;
|
|
6
|
+
|
|
7
|
+
// Select all elements with light or dark attributes
|
|
8
|
+
const elements = document.querySelectorAll("[light], [dark]");
|
|
9
|
+
|
|
10
|
+
elements.forEach((element) => {
|
|
11
|
+
// Determine the attribute to use based on the theme
|
|
12
|
+
const themeAttr = isDarkMode ? "dark" : "light";
|
|
13
|
+
const themeValue = element.getAttribute(themeAttr);
|
|
14
|
+
|
|
15
|
+
// Determine the current value of the attribute to update
|
|
16
|
+
let attributeToUpdate;
|
|
17
|
+
if (element.tagName === "LINK" && element.rel === "manifest") {
|
|
18
|
+
attributeToUpdate = "href";
|
|
19
|
+
} else if (
|
|
20
|
+
element.tagName === "META" &&
|
|
21
|
+
element.name === "theme-color"
|
|
22
|
+
) {
|
|
23
|
+
attributeToUpdate = "content";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (attributeToUpdate && themeValue) {
|
|
27
|
+
const currentValue = element.getAttribute(attributeToUpdate);
|
|
28
|
+
|
|
29
|
+
// Update only if the current value does not match the new value
|
|
30
|
+
if (currentValue !== themeValue) {
|
|
31
|
+
if (element.tagName === "LINK" && element.rel === "manifest") {
|
|
32
|
+
// Handle manifest link replacement
|
|
33
|
+
const newElement = element.cloneNode(); // Clone the element
|
|
34
|
+
newElement.setAttribute(attributeToUpdate, themeValue); // Update href
|
|
35
|
+
|
|
36
|
+
// Replace the old link with the new one to force fetch
|
|
37
|
+
element.parentNode.replaceChild(newElement, element);
|
|
38
|
+
console.log(`Manifest updated: ${themeValue}`);
|
|
39
|
+
} else {
|
|
40
|
+
// For other elements like meta, update the attribute directly
|
|
41
|
+
element.setAttribute(attributeToUpdate, themeValue);
|
|
42
|
+
if (element.tagName === "META") {
|
|
43
|
+
console.log(`Theme color updated: ${themeValue}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Apply theme attributes on page load
|
|
52
|
+
applyThemeAttributes();
|
|
53
|
+
|
|
54
|
+
// Listen for changes in the user's theme preference
|
|
55
|
+
window
|
|
56
|
+
.matchMedia("(prefers-color-scheme: dark)")
|
|
57
|
+
.addEventListener("change", applyThemeAttributes);
|