commit
6bcf6b143c
|
@ -28,6 +28,7 @@ Everything is designed and engineered for my own use case, following my taste an
|
|||
- 🪟 Compose window pop-out/in
|
||||
- 🌗 Light/dark/auto theme
|
||||
- 🔔 Grouped notifications
|
||||
- 🪺 Nested replies view
|
||||
|
||||
## Design decisions
|
||||
|
||||
|
|
379
index.html
379
index.html
|
@ -28,385 +28,6 @@
|
|||
content="#242526"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<script vite-if="import.meta.env.VITE_APP_ENV === production">
|
||||
var isDev = /dev\./.test(window.location.hostname);
|
||||
var _rollbarConfig = {
|
||||
accessToken: 'ec3e07829d324a29abf6c83472a9740d',
|
||||
captureUncaught: true,
|
||||
captureUnhandledRejections: true,
|
||||
enabled: isDev,
|
||||
hostSafeList: ['dev.phanpy.social', 'phanpy.social'],
|
||||
payload: {
|
||||
environment: isDev ? 'development' : 'production',
|
||||
},
|
||||
};
|
||||
// Rollbar Snippet
|
||||
!(function (r) {
|
||||
function e(n) {
|
||||
if (o[n]) return o[n].exports;
|
||||
var t = (o[n] = { exports: {}, id: n, loaded: !1 });
|
||||
return (
|
||||
r[n].call(t.exports, t, t.exports, e), (t.loaded = !0), t.exports
|
||||
);
|
||||
}
|
||||
var o = {};
|
||||
return (e.m = r), (e.c = o), (e.p = ''), e(0);
|
||||
})([
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
var n = o(1),
|
||||
t = o(4);
|
||||
(_rollbarConfig = _rollbarConfig || {}),
|
||||
(_rollbarConfig.rollbarJsUrl =
|
||||
_rollbarConfig.rollbarJsUrl ||
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/rollbar.js/2.4.6/rollbar.min.js'),
|
||||
(_rollbarConfig.async =
|
||||
void 0 === _rollbarConfig.async || _rollbarConfig.async);
|
||||
var a = n.setupShim(window, _rollbarConfig),
|
||||
l = t(_rollbarConfig);
|
||||
(window.rollbar = n.Rollbar),
|
||||
a.loadFull(
|
||||
window,
|
||||
document,
|
||||
!_rollbarConfig.async,
|
||||
_rollbarConfig,
|
||||
l,
|
||||
);
|
||||
},
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
function n(r) {
|
||||
return function () {
|
||||
try {
|
||||
return r.apply(this, arguments);
|
||||
} catch (r) {
|
||||
try {
|
||||
console.error('[Rollbar]: Internal error', r);
|
||||
} catch (r) {}
|
||||
}
|
||||
};
|
||||
}
|
||||
function t(r, e) {
|
||||
(this.options = r), (this._rollbarOldOnError = null);
|
||||
var o = s++;
|
||||
(this.shimId = function () {
|
||||
return o;
|
||||
}),
|
||||
'undefined' != typeof window &&
|
||||
window._rollbarShims &&
|
||||
(window._rollbarShims[o] = { handler: e, messages: [] });
|
||||
}
|
||||
function a(r, e) {
|
||||
if (r) {
|
||||
var o = e.globalAlias || 'Rollbar';
|
||||
if ('object' == typeof r[o]) return r[o];
|
||||
(r._rollbarShims = {}), (r._rollbarWrappedError = null);
|
||||
var t = new p(e);
|
||||
return n(function () {
|
||||
e.captureUncaught &&
|
||||
((t._rollbarOldOnError = r.onerror),
|
||||
i.captureUncaughtExceptions(r, t, !0),
|
||||
i.wrapGlobals(r, t, !0)),
|
||||
e.captureUnhandledRejections &&
|
||||
i.captureUnhandledRejections(r, t, !0);
|
||||
var n = e.autoInstrument;
|
||||
return (
|
||||
e.enabled !== !1 &&
|
||||
(void 0 === n ||
|
||||
n === !0 ||
|
||||
('object' == typeof n && n.network)) &&
|
||||
r.addEventListener &&
|
||||
(r.addEventListener('load', t.captureLoad.bind(t)),
|
||||
r.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
t.captureDomContentLoaded.bind(t),
|
||||
)),
|
||||
(r[o] = t),
|
||||
t
|
||||
);
|
||||
})();
|
||||
}
|
||||
}
|
||||
function l(r) {
|
||||
return n(function () {
|
||||
var e = this,
|
||||
o = Array.prototype.slice.call(arguments, 0),
|
||||
n = { shim: e, method: r, args: o, ts: new Date() };
|
||||
window._rollbarShims[this.shimId()].messages.push(n);
|
||||
});
|
||||
}
|
||||
var i = o(2),
|
||||
s = 0,
|
||||
d = o(3),
|
||||
c = function (r, e) {
|
||||
return new t(r, e);
|
||||
},
|
||||
p = d.bind(null, c);
|
||||
(t.prototype.loadFull = function (r, e, o, t, a) {
|
||||
var l = function () {
|
||||
var e;
|
||||
if (void 0 === r._rollbarDidLoad) {
|
||||
e = new Error('rollbar.js did not load');
|
||||
for (var o, n, t, l, i = 0; (o = r._rollbarShims[i++]); )
|
||||
for (o = o.messages || []; (n = o.shift()); )
|
||||
for (t = n.args || [], i = 0; i < t.length; ++i)
|
||||
if (((l = t[i]), 'function' == typeof l)) {
|
||||
l(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
'function' == typeof a && a(e);
|
||||
},
|
||||
i = !1,
|
||||
s = e.createElement('script'),
|
||||
d = e.getElementsByTagName('script')[0],
|
||||
c = d.parentNode;
|
||||
(s.crossOrigin = ''),
|
||||
(s.src = t.rollbarJsUrl),
|
||||
o || (s.async = !0),
|
||||
(s.onload = s.onreadystatechange =
|
||||
n(function () {
|
||||
if (
|
||||
!(
|
||||
i ||
|
||||
(this.readyState &&
|
||||
'loaded' !== this.readyState &&
|
||||
'complete' !== this.readyState)
|
||||
)
|
||||
) {
|
||||
s.onload = s.onreadystatechange = null;
|
||||
try {
|
||||
c.removeChild(s);
|
||||
} catch (r) {}
|
||||
(i = !0), l();
|
||||
}
|
||||
})),
|
||||
c.insertBefore(s, d);
|
||||
}),
|
||||
(t.prototype.wrap = function (r, e, o) {
|
||||
try {
|
||||
var n;
|
||||
if (
|
||||
((n =
|
||||
'function' == typeof e
|
||||
? e
|
||||
: function () {
|
||||
return e || {};
|
||||
}),
|
||||
'function' != typeof r)
|
||||
)
|
||||
return r;
|
||||
if (r._isWrap) return r;
|
||||
if (
|
||||
!r._rollbar_wrapped &&
|
||||
((r._rollbar_wrapped = function () {
|
||||
o && 'function' == typeof o && o.apply(this, arguments);
|
||||
try {
|
||||
return r.apply(this, arguments);
|
||||
} catch (o) {
|
||||
var e = o;
|
||||
throw (
|
||||
(e &&
|
||||
('string' == typeof e && (e = new String(e)),
|
||||
(e._rollbarContext = n() || {}),
|
||||
(e._rollbarContext._wrappedSource = r.toString()),
|
||||
(window._rollbarWrappedError = e)),
|
||||
e)
|
||||
);
|
||||
}
|
||||
}),
|
||||
(r._rollbar_wrapped._isWrap = !0),
|
||||
r.hasOwnProperty)
|
||||
)
|
||||
for (var t in r)
|
||||
r.hasOwnProperty(t) && (r._rollbar_wrapped[t] = r[t]);
|
||||
return r._rollbar_wrapped;
|
||||
} catch (e) {
|
||||
return r;
|
||||
}
|
||||
});
|
||||
for (
|
||||
var u =
|
||||
'log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleUnhandledRejection,captureEvent,captureDomContentLoaded,captureLoad'.split(
|
||||
',',
|
||||
),
|
||||
f = 0;
|
||||
f < u.length;
|
||||
++f
|
||||
)
|
||||
t.prototype[u[f]] = l(u[f]);
|
||||
r.exports = { setupShim: a, Rollbar: p };
|
||||
},
|
||||
function (r, e) {
|
||||
'use strict';
|
||||
function o(r, e, o) {
|
||||
if (r) {
|
||||
var t;
|
||||
'function' == typeof e._rollbarOldOnError
|
||||
? (t = e._rollbarOldOnError)
|
||||
: r.onerror &&
|
||||
!r.onerror.belongsToShim &&
|
||||
((t = r.onerror), (e._rollbarOldOnError = t));
|
||||
var a = function () {
|
||||
var o = Array.prototype.slice.call(arguments, 0);
|
||||
n(r, e, t, o);
|
||||
};
|
||||
(a.belongsToShim = o), (r.onerror = a);
|
||||
}
|
||||
}
|
||||
function n(r, e, o, n) {
|
||||
r._rollbarWrappedError &&
|
||||
(n[4] || (n[4] = r._rollbarWrappedError),
|
||||
n[5] || (n[5] = r._rollbarWrappedError._rollbarContext),
|
||||
(r._rollbarWrappedError = null)),
|
||||
e.handleUncaughtException.apply(e, n),
|
||||
o && o.apply(r, n);
|
||||
}
|
||||
function t(r, e, o) {
|
||||
if (r) {
|
||||
'function' == typeof r._rollbarURH &&
|
||||
r._rollbarURH.belongsToShim &&
|
||||
r.removeEventListener('unhandledrejection', r._rollbarURH);
|
||||
var n = function (r) {
|
||||
var o, n, t;
|
||||
try {
|
||||
o = r.reason;
|
||||
} catch (r) {
|
||||
o = void 0;
|
||||
}
|
||||
try {
|
||||
n = r.promise;
|
||||
} catch (r) {
|
||||
n = '[unhandledrejection] error getting `promise` from event';
|
||||
}
|
||||
try {
|
||||
(t = r.detail), !o && t && ((o = t.reason), (n = t.promise));
|
||||
} catch (r) {
|
||||
t = '[unhandledrejection] error getting `detail` from event';
|
||||
}
|
||||
o ||
|
||||
(o =
|
||||
'[unhandledrejection] error getting `reason` from event'),
|
||||
e &&
|
||||
e.handleUnhandledRejection &&
|
||||
e.handleUnhandledRejection(o, n);
|
||||
};
|
||||
(n.belongsToShim = o),
|
||||
(r._rollbarURH = n),
|
||||
r.addEventListener('unhandledrejection', n);
|
||||
}
|
||||
}
|
||||
function a(r, e, o) {
|
||||
if (r) {
|
||||
var n,
|
||||
t,
|
||||
a =
|
||||
'EventTarget,Window,Node,ApplicationCache,AudioTrackList,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload'.split(
|
||||
',',
|
||||
);
|
||||
for (n = 0; n < a.length; ++n)
|
||||
(t = a[n]), r[t] && r[t].prototype && l(e, r[t].prototype, o);
|
||||
}
|
||||
}
|
||||
function l(r, e, o) {
|
||||
if (e.hasOwnProperty && e.hasOwnProperty('addEventListener')) {
|
||||
for (
|
||||
var n = e.addEventListener;
|
||||
n._rollbarOldAdd && n.belongsToShim;
|
||||
|
||||
)
|
||||
n = n._rollbarOldAdd;
|
||||
var t = function (e, o, t) {
|
||||
n.call(this, e, r.wrap(o), t);
|
||||
};
|
||||
(t._rollbarOldAdd = n),
|
||||
(t.belongsToShim = o),
|
||||
(e.addEventListener = t);
|
||||
for (
|
||||
var a = e.removeEventListener;
|
||||
a._rollbarOldRemove && a.belongsToShim;
|
||||
|
||||
)
|
||||
a = a._rollbarOldRemove;
|
||||
var l = function (r, e, o) {
|
||||
a.call(this, r, (e && e._rollbar_wrapped) || e, o);
|
||||
};
|
||||
(l._rollbarOldRemove = a),
|
||||
(l.belongsToShim = o),
|
||||
(e.removeEventListener = l);
|
||||
}
|
||||
}
|
||||
r.exports = {
|
||||
captureUncaughtExceptions: o,
|
||||
captureUnhandledRejections: t,
|
||||
wrapGlobals: a,
|
||||
};
|
||||
},
|
||||
function (r, e) {
|
||||
'use strict';
|
||||
function o(r, e) {
|
||||
(this.impl = r(e, this)), (this.options = e), n(o.prototype);
|
||||
}
|
||||
function n(r) {
|
||||
for (
|
||||
var e = function (r) {
|
||||
return function () {
|
||||
var e = Array.prototype.slice.call(arguments, 0);
|
||||
if (this.impl[r]) return this.impl[r].apply(this.impl, e);
|
||||
};
|
||||
},
|
||||
o =
|
||||
'log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleUnhandledRejection,_createItem,wrap,loadFull,shimId,captureEvent,captureDomContentLoaded,captureLoad'.split(
|
||||
',',
|
||||
),
|
||||
n = 0;
|
||||
n < o.length;
|
||||
n++
|
||||
)
|
||||
r[o[n]] = e(o[n]);
|
||||
}
|
||||
(o.prototype._swapAndProcessMessages = function (r, e) {
|
||||
this.impl = r(this.options);
|
||||
for (var o, n, t; (o = e.shift()); )
|
||||
(n = o.method),
|
||||
(t = o.args),
|
||||
this[n] &&
|
||||
'function' == typeof this[n] &&
|
||||
('captureDomContentLoaded' === n || 'captureLoad' === n
|
||||
? this[n].apply(this, [t[0], o.ts])
|
||||
: this[n].apply(this, t));
|
||||
return this;
|
||||
}),
|
||||
(r.exports = o);
|
||||
},
|
||||
function (r, e) {
|
||||
'use strict';
|
||||
r.exports = function (r) {
|
||||
return function (e) {
|
||||
if (!e && !window._rollbarInitialized) {
|
||||
r = r || {};
|
||||
for (
|
||||
var o,
|
||||
n,
|
||||
t = r.globalAlias || 'Rollbar',
|
||||
a = window.rollbar,
|
||||
l = function (r) {
|
||||
return new a(r);
|
||||
},
|
||||
i = 0;
|
||||
(o = window._rollbarShims[i++]);
|
||||
|
||||
)
|
||||
n || (n = o.handler),
|
||||
o.handler._swapAndProcessMessages(l, o.messages);
|
||||
(window[t] = n), (window._rollbarInitialized = !0);
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
]);
|
||||
// End Rollbar Snippet
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
|
31
package-lock.json
generated
31
package-lock.json
generated
|
@ -20,6 +20,7 @@
|
|||
"preact-router": "~4.1.0",
|
||||
"react-intersection-observer": "~9.4.1",
|
||||
"string-length": "~5.0.1",
|
||||
"swiped-events": "~1.1.7",
|
||||
"toastify-js": "~1.12.0",
|
||||
"use-resize-observer": "~9.1.0",
|
||||
"valtio": "~1.8.0"
|
||||
|
@ -32,6 +33,7 @@
|
|||
"postcss-dark-theme-class": "~0.7.3",
|
||||
"twitter-text": "~3.1.0",
|
||||
"vite": "~4.0.3",
|
||||
"vite-plugin-html-config": "~1.0.11",
|
||||
"vite-plugin-html-env": "~1.2.7",
|
||||
"vite-plugin-pwa": "~0.14.0",
|
||||
"workbox-cacheable-response": "~6.5.4",
|
||||
|
@ -5040,6 +5042,11 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/swiped-events": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/swiped-events/-/swiped-events-1.1.7.tgz",
|
||||
"integrity": "sha512-bxEy7djwuLykZpPfoE4IFsbna/ngACEpyPqw9tBOaPQtAshsRK7H5CxoCgSXr0QRQ+7rd2TT3bSKLL3R6xJFwg=="
|
||||
},
|
||||
"node_modules/temp-dir": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
|
||||
|
@ -5407,6 +5414,18 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-html-config": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-html-config/-/vite-plugin-html-config-1.0.11.tgz",
|
||||
"integrity": "sha512-hUybhgI+/LQQ5q6xoMMsTvI4PBuQD/Wv6Z1vtDPVWjanS8weCIexXuLLYNGD/93f0v8W2hpNfXpmxgpZMahJ0g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": ">=2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-html-env": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-html-env/-/vite-plugin-html-env-1.2.7.tgz",
|
||||
|
@ -9382,6 +9401,11 @@
|
|||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"devOptional": true
|
||||
},
|
||||
"swiped-events": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/swiped-events/-/swiped-events-1.1.7.tgz",
|
||||
"integrity": "sha512-bxEy7djwuLykZpPfoE4IFsbna/ngACEpyPqw9tBOaPQtAshsRK7H5CxoCgSXr0QRQ+7rd2TT3bSKLL3R6xJFwg=="
|
||||
},
|
||||
"temp-dir": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
|
||||
|
@ -9610,6 +9634,13 @@
|
|||
"rollup": "^3.7.0"
|
||||
}
|
||||
},
|
||||
"vite-plugin-html-config": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-html-config/-/vite-plugin-html-config-1.0.11.tgz",
|
||||
"integrity": "sha512-hUybhgI+/LQQ5q6xoMMsTvI4PBuQD/Wv6Z1vtDPVWjanS8weCIexXuLLYNGD/93f0v8W2hpNfXpmxgpZMahJ0g==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"vite-plugin-html-env": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-html-env/-/vite-plugin-html-env-1.2.7.tgz",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"preact-router": "~4.1.0",
|
||||
"react-intersection-observer": "~9.4.1",
|
||||
"string-length": "~5.0.1",
|
||||
"swiped-events": "~1.1.7",
|
||||
"toastify-js": "~1.12.0",
|
||||
"use-resize-observer": "~9.1.0",
|
||||
"valtio": "~1.8.0"
|
||||
|
@ -34,6 +35,7 @@
|
|||
"postcss-dark-theme-class": "~0.7.3",
|
||||
"twitter-text": "~3.1.0",
|
||||
"vite": "~4.0.3",
|
||||
"vite-plugin-html-config": "~1.0.11",
|
||||
"vite-plugin-html-env": "~1.2.7",
|
||||
"vite-plugin-pwa": "~0.14.0",
|
||||
"workbox-cacheable-response": "~6.5.4",
|
||||
|
|
418
rollbar.js
Normal file
418
rollbar.js
Normal file
|
@ -0,0 +1,418 @@
|
|||
var isDev = /dev\./.test(window.location.hostname);
|
||||
var _rollbarConfig = {
|
||||
accessToken: 'ec3e07829d324a29abf6c83472a9740d',
|
||||
captureUncaught: true,
|
||||
captureUnhandledRejections: true,
|
||||
enabled: isDev,
|
||||
hostSafeList: ['dev.phanpy.social', 'phanpy.social'],
|
||||
payload: {
|
||||
environment: isDev ? 'development' : 'production',
|
||||
},
|
||||
};
|
||||
|
||||
// Rollbar Snippet
|
||||
!(function (r) {
|
||||
var e = {};
|
||||
function o(n) {
|
||||
if (e[n]) return e[n].exports;
|
||||
var t = (e[n] = { i: n, l: !1, exports: {} });
|
||||
return r[n].call(t.exports, t, t.exports, o), (t.l = !0), t.exports;
|
||||
}
|
||||
(o.m = r),
|
||||
(o.c = e),
|
||||
(o.d = function (r, e, n) {
|
||||
o.o(r, e) || Object.defineProperty(r, e, { enumerable: !0, get: n });
|
||||
}),
|
||||
(o.r = function (r) {
|
||||
'undefined' != typeof Symbol &&
|
||||
Symbol.toStringTag &&
|
||||
Object.defineProperty(r, Symbol.toStringTag, { value: 'Module' }),
|
||||
Object.defineProperty(r, '__esModule', { value: !0 });
|
||||
}),
|
||||
(o.t = function (r, e) {
|
||||
if ((1 & e && (r = o(r)), 8 & e)) return r;
|
||||
if (4 & e && 'object' == typeof r && r && r.__esModule) return r;
|
||||
var n = Object.create(null);
|
||||
if (
|
||||
(o.r(n),
|
||||
Object.defineProperty(n, 'default', { enumerable: !0, value: r }),
|
||||
2 & e && 'string' != typeof r)
|
||||
)
|
||||
for (var t in r)
|
||||
o.d(
|
||||
n,
|
||||
t,
|
||||
function (e) {
|
||||
return r[e];
|
||||
}.bind(null, t),
|
||||
);
|
||||
return n;
|
||||
}),
|
||||
(o.n = function (r) {
|
||||
var e =
|
||||
r && r.__esModule
|
||||
? function () {
|
||||
return r.default;
|
||||
}
|
||||
: function () {
|
||||
return r;
|
||||
};
|
||||
return o.d(e, 'a', e), e;
|
||||
}),
|
||||
(o.o = function (r, e) {
|
||||
return Object.prototype.hasOwnProperty.call(r, e);
|
||||
}),
|
||||
(o.p = ''),
|
||||
o((o.s = 0));
|
||||
})([
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
var n = o(1),
|
||||
t = o(5);
|
||||
(_rollbarConfig = _rollbarConfig || {}),
|
||||
(_rollbarConfig.rollbarJsUrl =
|
||||
_rollbarConfig.rollbarJsUrl ||
|
||||
'https://cdn.rollbar.com/rollbarjs/refs/tags/v2.26.0/rollbar.min.js'),
|
||||
(_rollbarConfig.async =
|
||||
void 0 === _rollbarConfig.async || _rollbarConfig.async);
|
||||
var a = n.setupShim(window, _rollbarConfig),
|
||||
l = t(_rollbarConfig);
|
||||
(window.rollbar = n.Rollbar),
|
||||
a.loadFull(window, document, !_rollbarConfig.async, _rollbarConfig, l);
|
||||
},
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
var n = o(2),
|
||||
t = o(3);
|
||||
function a(r) {
|
||||
return function () {
|
||||
try {
|
||||
return r.apply(this, arguments);
|
||||
} catch (r) {
|
||||
try {
|
||||
console.error('[Rollbar]: Internal error', r);
|
||||
} catch (r) {}
|
||||
}
|
||||
};
|
||||
}
|
||||
var l = 0;
|
||||
function i(r, e) {
|
||||
(this.options = r), (this._rollbarOldOnError = null);
|
||||
var o = l++;
|
||||
(this.shimId = function () {
|
||||
return o;
|
||||
}),
|
||||
'undefined' != typeof window &&
|
||||
window._rollbarShims &&
|
||||
(window._rollbarShims[o] = { handler: e, messages: [] });
|
||||
}
|
||||
var s = o(4),
|
||||
d = function (r, e) {
|
||||
return new i(r, e);
|
||||
},
|
||||
c = function (r) {
|
||||
return new s(d, r);
|
||||
};
|
||||
function u(r) {
|
||||
return a(function () {
|
||||
var e = this,
|
||||
o = Array.prototype.slice.call(arguments, 0),
|
||||
n = { shim: e, method: r, args: o, ts: new Date() };
|
||||
window._rollbarShims[this.shimId()].messages.push(n);
|
||||
});
|
||||
}
|
||||
(i.prototype.loadFull = function (r, e, o, n, t) {
|
||||
var l = !1,
|
||||
i = e.createElement('script'),
|
||||
s = e.getElementsByTagName('script')[0],
|
||||
d = s.parentNode;
|
||||
(i.crossOrigin = ''),
|
||||
(i.src = n.rollbarJsUrl),
|
||||
o || (i.async = !0),
|
||||
(i.onload = i.onreadystatechange =
|
||||
a(function () {
|
||||
if (
|
||||
!(
|
||||
l ||
|
||||
(this.readyState &&
|
||||
'loaded' !== this.readyState &&
|
||||
'complete' !== this.readyState)
|
||||
)
|
||||
) {
|
||||
i.onload = i.onreadystatechange = null;
|
||||
try {
|
||||
d.removeChild(i);
|
||||
} catch (r) {}
|
||||
(l = !0),
|
||||
(function () {
|
||||
var e;
|
||||
if (void 0 === r._rollbarDidLoad) {
|
||||
e = new Error('rollbar.js did not load');
|
||||
for (var o, n, a, l, i = 0; (o = r._rollbarShims[i++]); )
|
||||
for (o = o.messages || []; (n = o.shift()); )
|
||||
for (a = n.args || [], i = 0; i < a.length; ++i)
|
||||
if ('function' == typeof (l = a[i])) {
|
||||
l(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
'function' == typeof t && t(e);
|
||||
})();
|
||||
}
|
||||
})),
|
||||
d.insertBefore(i, s);
|
||||
}),
|
||||
(i.prototype.wrap = function (r, e, o) {
|
||||
try {
|
||||
var n;
|
||||
if (
|
||||
((n =
|
||||
'function' == typeof e
|
||||
? e
|
||||
: function () {
|
||||
return e || {};
|
||||
}),
|
||||
'function' != typeof r)
|
||||
)
|
||||
return r;
|
||||
if (r._isWrap) return r;
|
||||
if (
|
||||
!r._rollbar_wrapped &&
|
||||
((r._rollbar_wrapped = function () {
|
||||
o && 'function' == typeof o && o.apply(this, arguments);
|
||||
try {
|
||||
return r.apply(this, arguments);
|
||||
} catch (o) {
|
||||
var e = o;
|
||||
throw (
|
||||
(e &&
|
||||
('string' == typeof e && (e = new String(e)),
|
||||
(e._rollbarContext = n() || {}),
|
||||
(e._rollbarContext._wrappedSource = r.toString()),
|
||||
(window._rollbarWrappedError = e)),
|
||||
e)
|
||||
);
|
||||
}
|
||||
}),
|
||||
(r._rollbar_wrapped._isWrap = !0),
|
||||
r.hasOwnProperty)
|
||||
)
|
||||
for (var t in r)
|
||||
r.hasOwnProperty(t) && (r._rollbar_wrapped[t] = r[t]);
|
||||
return r._rollbar_wrapped;
|
||||
} catch (e) {
|
||||
return r;
|
||||
}
|
||||
});
|
||||
for (
|
||||
var p =
|
||||
'log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleAnonymousErrors,handleUnhandledRejection,captureEvent,captureDomContentLoaded,captureLoad'.split(
|
||||
',',
|
||||
),
|
||||
f = 0;
|
||||
f < p.length;
|
||||
++f
|
||||
)
|
||||
i.prototype[p[f]] = u(p[f]);
|
||||
r.exports = {
|
||||
setupShim: function (r, e) {
|
||||
if (r) {
|
||||
var o = e.globalAlias || 'Rollbar';
|
||||
if ('object' == typeof r[o]) return r[o];
|
||||
(r._rollbarShims = {}), (r._rollbarWrappedError = null);
|
||||
var l = new c(e);
|
||||
return a(function () {
|
||||
e.captureUncaught &&
|
||||
((l._rollbarOldOnError = r.onerror),
|
||||
n.captureUncaughtExceptions(r, l, !0),
|
||||
e.wrapGlobalEventHandlers && t(r, l, !0)),
|
||||
e.captureUnhandledRejections &&
|
||||
n.captureUnhandledRejections(r, l, !0);
|
||||
var a = e.autoInstrument;
|
||||
return (
|
||||
!1 !== e.enabled &&
|
||||
(void 0 === a ||
|
||||
!0 === a ||
|
||||
(function (r) {
|
||||
return !(
|
||||
'object' != typeof r ||
|
||||
(void 0 !== r.page && !r.page)
|
||||
);
|
||||
})(a)) &&
|
||||
r.addEventListener &&
|
||||
(r.addEventListener('load', l.captureLoad.bind(l)),
|
||||
r.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
l.captureDomContentLoaded.bind(l),
|
||||
)),
|
||||
(r[o] = l),
|
||||
l
|
||||
);
|
||||
})();
|
||||
}
|
||||
},
|
||||
Rollbar: c,
|
||||
};
|
||||
},
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
function n(r, e, o, n) {
|
||||
r._rollbarWrappedError &&
|
||||
(n[4] || (n[4] = r._rollbarWrappedError),
|
||||
n[5] || (n[5] = r._rollbarWrappedError._rollbarContext),
|
||||
(r._rollbarWrappedError = null));
|
||||
var t = e.handleUncaughtException.apply(e, n);
|
||||
o && o.apply(r, n), 'anonymous' === t && (e.anonymousErrorsPending += 1);
|
||||
}
|
||||
r.exports = {
|
||||
captureUncaughtExceptions: function (r, e, o) {
|
||||
if (r) {
|
||||
var t;
|
||||
if ('function' == typeof e._rollbarOldOnError)
|
||||
t = e._rollbarOldOnError;
|
||||
else if (r.onerror) {
|
||||
for (t = r.onerror; t._rollbarOldOnError; )
|
||||
t = t._rollbarOldOnError;
|
||||
e._rollbarOldOnError = t;
|
||||
}
|
||||
e.handleAnonymousErrors();
|
||||
var a = function () {
|
||||
var o = Array.prototype.slice.call(arguments, 0);
|
||||
n(r, e, t, o);
|
||||
};
|
||||
o && (a._rollbarOldOnError = t), (r.onerror = a);
|
||||
}
|
||||
},
|
||||
captureUnhandledRejections: function (r, e, o) {
|
||||
if (r) {
|
||||
'function' == typeof r._rollbarURH &&
|
||||
r._rollbarURH.belongsToShim &&
|
||||
r.removeEventListener('unhandledrejection', r._rollbarURH);
|
||||
var n = function (r) {
|
||||
var o, n, t;
|
||||
try {
|
||||
o = r.reason;
|
||||
} catch (r) {
|
||||
o = void 0;
|
||||
}
|
||||
try {
|
||||
n = r.promise;
|
||||
} catch (r) {
|
||||
n = '[unhandledrejection] error getting `promise` from event';
|
||||
}
|
||||
try {
|
||||
(t = r.detail), !o && t && ((o = t.reason), (n = t.promise));
|
||||
} catch (r) {}
|
||||
o || (o = '[unhandledrejection] error getting `reason` from event'),
|
||||
e &&
|
||||
e.handleUnhandledRejection &&
|
||||
e.handleUnhandledRejection(o, n);
|
||||
};
|
||||
(n.belongsToShim = o),
|
||||
(r._rollbarURH = n),
|
||||
r.addEventListener('unhandledrejection', n);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
function n(r, e, o) {
|
||||
if (e.hasOwnProperty && e.hasOwnProperty('addEventListener')) {
|
||||
for (var n = e.addEventListener; n._rollbarOldAdd && n.belongsToShim; )
|
||||
n = n._rollbarOldAdd;
|
||||
var t = function (e, o, t) {
|
||||
n.call(this, e, r.wrap(o), t);
|
||||
};
|
||||
(t._rollbarOldAdd = n), (t.belongsToShim = o), (e.addEventListener = t);
|
||||
for (
|
||||
var a = e.removeEventListener;
|
||||
a._rollbarOldRemove && a.belongsToShim;
|
||||
|
||||
)
|
||||
a = a._rollbarOldRemove;
|
||||
var l = function (r, e, o) {
|
||||
a.call(this, r, (e && e._rollbar_wrapped) || e, o);
|
||||
};
|
||||
(l._rollbarOldRemove = a),
|
||||
(l.belongsToShim = o),
|
||||
(e.removeEventListener = l);
|
||||
}
|
||||
}
|
||||
r.exports = function (r, e, o) {
|
||||
if (r) {
|
||||
var t,
|
||||
a,
|
||||
l =
|
||||
'EventTarget,Window,Node,ApplicationCache,AudioTrackList,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload'.split(
|
||||
',',
|
||||
);
|
||||
for (t = 0; t < l.length; ++t)
|
||||
r[(a = l[t])] && r[a].prototype && n(e, r[a].prototype, o);
|
||||
}
|
||||
};
|
||||
},
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
function n(r, e) {
|
||||
(this.impl = r(e, this)),
|
||||
(this.options = e),
|
||||
(function (r) {
|
||||
for (
|
||||
var e = function (r) {
|
||||
return function () {
|
||||
var e = Array.prototype.slice.call(arguments, 0);
|
||||
if (this.impl[r]) return this.impl[r].apply(this.impl, e);
|
||||
};
|
||||
},
|
||||
o =
|
||||
'log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleAnonymousErrors,handleUnhandledRejection,_createItem,wrap,loadFull,shimId,captureEvent,captureDomContentLoaded,captureLoad'.split(
|
||||
',',
|
||||
),
|
||||
n = 0;
|
||||
n < o.length;
|
||||
n++
|
||||
)
|
||||
r[o[n]] = e(o[n]);
|
||||
})(n.prototype);
|
||||
}
|
||||
(n.prototype._swapAndProcessMessages = function (r, e) {
|
||||
var o, n, t;
|
||||
for (this.impl = r(this.options); (o = e.shift()); )
|
||||
(n = o.method),
|
||||
(t = o.args),
|
||||
this[n] &&
|
||||
'function' == typeof this[n] &&
|
||||
('captureDomContentLoaded' === n || 'captureLoad' === n
|
||||
? this[n].apply(this, [t[0], o.ts])
|
||||
: this[n].apply(this, t));
|
||||
return this;
|
||||
}),
|
||||
(r.exports = n);
|
||||
},
|
||||
function (r, e, o) {
|
||||
'use strict';
|
||||
r.exports = function (r) {
|
||||
return function (e) {
|
||||
if (!e && !window._rollbarInitialized) {
|
||||
for (
|
||||
var o,
|
||||
n,
|
||||
t = (r = r || {}).globalAlias || 'Rollbar',
|
||||
a = window.rollbar,
|
||||
l = function (r) {
|
||||
return new a(r);
|
||||
},
|
||||
i = 0;
|
||||
(o = window._rollbarShims[i++]);
|
||||
|
||||
)
|
||||
n || (n = o.handler),
|
||||
o.handler._swapAndProcessMessages(l, o.messages);
|
||||
(window[t] = n), (window._rollbarInitialized = !0);
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
]);
|
||||
// End Rollbar Snippet
|
18
src/app.css
18
src/app.css
|
@ -79,6 +79,7 @@ a.mention span {
|
|||
position: sticky;
|
||||
top: 0;
|
||||
background-color: var(--bg-blur-color);
|
||||
background-image: linear-gradient(to bottom, var(--bg-color), transparent);
|
||||
backdrop-filter: saturate(180%) blur(20px);
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
z-index: 1;
|
||||
|
@ -455,6 +456,7 @@ a.mention span {
|
|||
/* scroll-behavior: smooth; */
|
||||
scrollbar-width: none;
|
||||
overscroll-behavior: contain;
|
||||
touch-action: pan-x;
|
||||
}
|
||||
.carousel::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
@ -476,9 +478,11 @@ a.mention span {
|
|||
height: auto;
|
||||
max-height: 100vh;
|
||||
max-height: 100dvh;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.carousel > * video {
|
||||
min-height: 80px;
|
||||
max-height: 80vh; /* prevent other UI elements from obscuring video */
|
||||
}
|
||||
|
||||
.carousel-top-controls {
|
||||
|
@ -502,6 +506,9 @@ a.mention span {
|
|||
text-align: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
:is(.carousel-top-controls, .carousel-controls)[hidden] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
button.carousel-button,
|
||||
button.carousel-dot {
|
||||
|
@ -546,6 +553,9 @@ button.carousel-dot[disabled].active {
|
|||
transform: translateY(100%);
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
:is(.carousel-top-controls, .carousel-controls)[hidden] {
|
||||
opacity: 1;
|
||||
}
|
||||
.carousel:hover + .carousel-top-controls,
|
||||
.carousel:hover + .carousel-top-controls + .carousel-controls,
|
||||
.carousel-top-controls:hover,
|
||||
|
@ -761,6 +771,9 @@ meter.donut:is(.danger, .explode):after {
|
|||
box-shadow: 0 3px 8px -1px var(--bg-faded-blur-color),
|
||||
0 10px 36px -4px var(--button-bg-blur-color);
|
||||
}
|
||||
.toastify-bottom {
|
||||
margin-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
:root .toastify:hover {
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
|
@ -792,6 +805,11 @@ meter.donut:is(.danger, .explode):after {
|
|||
min-height: 6em;
|
||||
border-bottom: 0;
|
||||
background-color: var(--bg-faded-blur-color);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--bg-faded-color),
|
||||
transparent 50%
|
||||
);
|
||||
border-bottom: 0;
|
||||
mask-image: linear-gradient(
|
||||
rgba(0, 0, 0, 1) 50%,
|
||||
|
|
26
src/app.jsx
26
src/app.jsx
|
@ -384,18 +384,20 @@ export function App() {
|
|||
states.showCompose = false;
|
||||
if (newStatus) {
|
||||
states.reloadStatusPage++;
|
||||
const toast = Toastify({
|
||||
text: 'Status posted. Check it out.',
|
||||
duration: 10_000, // 10 seconds
|
||||
gravity: 'bottom',
|
||||
position: 'center',
|
||||
// destination: `/#/s/${newStatus.id}`,
|
||||
onClick: () => {
|
||||
toast.hideToast();
|
||||
route(`/s/${newStatus.id}`);
|
||||
},
|
||||
});
|
||||
toast.showToast();
|
||||
setTimeout(() => {
|
||||
const toast = Toastify({
|
||||
text: 'Status posted. Check it out.',
|
||||
duration: 10_000, // 10 seconds
|
||||
gravity: 'bottom',
|
||||
position: 'center',
|
||||
// destination: `/#/s/${newStatus.id}`,
|
||||
onClick: () => {
|
||||
toast.hideToast();
|
||||
route(`/s/${newStatus.id}`);
|
||||
},
|
||||
});
|
||||
toast.showToast();
|
||||
}, 1000);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -198,7 +198,7 @@ function Account({ account }) {
|
|||
<button
|
||||
type="button"
|
||||
class={`${following ? 'light' : ''} swap`}
|
||||
data-swap-state="danger"
|
||||
data-swap-state={following ? 'danger' : ''}
|
||||
disabled={relationshipUIState === 'loading'}
|
||||
onClick={() => {
|
||||
setRelationshipUIState('loading');
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
display: inline-block;
|
||||
position: absolute;
|
||||
inset-block-end: 1.5em;
|
||||
left: 50%;
|
||||
left: 45%;
|
||||
transform: translateX(-50%);
|
||||
color: var(--text-color);
|
||||
background-color: var(--bg-faded-color);
|
||||
|
@ -280,37 +280,48 @@
|
|||
|
||||
.status .media-container {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-auto-rows: 1fr;
|
||||
gap: 2px;
|
||||
flex-direction: row;
|
||||
height: 160px;
|
||||
}
|
||||
.status:not(.large) .media-container.media-gt4 {
|
||||
flex-wrap: nowrap;
|
||||
overflow: auto;
|
||||
.status .media-container.media-gt2 {
|
||||
height: 200px;
|
||||
}
|
||||
.status.large :is(.media-container, .media-container.media-gt2) {
|
||||
height: auto;
|
||||
max-height: 80vh;
|
||||
}
|
||||
.status .media {
|
||||
flex-grow: 1;
|
||||
flex-basis: calc(50% - 8px);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
max-height: 160px;
|
||||
min-height: 80px;
|
||||
border: 1px solid var(--outline-color);
|
||||
}
|
||||
.status .media-container.media-gt2 .media {
|
||||
aspect-ratio: 1 / 1;
|
||||
.status .media:only-child {
|
||||
grid-area: span 2 / span 2;
|
||||
}
|
||||
.status:not(.large) .media-container.media-gt4 .media {
|
||||
min-width: 80px;
|
||||
.status .media:first-child:nth-last-child(3) {
|
||||
grid-area: span 2;
|
||||
}
|
||||
|
||||
.status:not(.large) .media-container.media-gt4 .media:last-child {
|
||||
position: relative;
|
||||
}
|
||||
.status:not(.large) .media-container.media-gt4 .media:last-child:after {
|
||||
content: '4+';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
background-color: var(--bg-faded-blur-color);
|
||||
}
|
||||
|
||||
.status .media:hover {
|
||||
border-color: var(--outline-hover-color);
|
||||
}
|
||||
.status .media.block {
|
||||
flex-basis: 100%;
|
||||
max-height: auto;
|
||||
}
|
||||
.status .media :is(img, video) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
useState,
|
||||
} from 'preact/hooks';
|
||||
import { InView } from 'react-intersection-observer';
|
||||
import 'swiped-events';
|
||||
import useResizeObserver from 'use-resize-observer';
|
||||
import { useSnapshot } from 'valtio';
|
||||
|
||||
|
@ -417,16 +418,19 @@ function Status({
|
|||
mediaAttachments.length > 2 ? 'media-gt2' : ''
|
||||
} ${mediaAttachments.length > 4 ? 'media-gt4' : ''}`}
|
||||
>
|
||||
{mediaAttachments.map((media, i) => (
|
||||
<Media
|
||||
media={media}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setShowMediaModal(i);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{mediaAttachments
|
||||
.slice(0, size === 'l' ? undefined : 4)
|
||||
.map((media, i) => (
|
||||
<Media
|
||||
key={media.id}
|
||||
media={media}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setShowMediaModal(i);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{!!card &&
|
||||
|
@ -756,19 +760,10 @@ function Media({ media, showOriginal, onClick = () => {} }) {
|
|||
rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`,
|
||||
}}
|
||||
onClick={(e) => {
|
||||
if (isGIF) {
|
||||
// Hmm, the videoRef might conflict here
|
||||
if (showOriginal) {
|
||||
try {
|
||||
if (videoRef.current.paused) {
|
||||
videoRef.current.play();
|
||||
} else {
|
||||
videoRef.current.pause();
|
||||
}
|
||||
} catch (e) {}
|
||||
} else {
|
||||
if (!showOriginal && isGIF) {
|
||||
try {
|
||||
videoRef.current.pause();
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
onClick(e);
|
||||
}}
|
||||
|
@ -788,19 +783,24 @@ function Media({ media, showOriginal, onClick = () => {} }) {
|
|||
}}
|
||||
>
|
||||
{showOriginal ? (
|
||||
<video
|
||||
ref={videoRef}
|
||||
src={url}
|
||||
poster={previewUrl}
|
||||
width={width}
|
||||
height={height}
|
||||
preload="auto"
|
||||
autoplay
|
||||
muted={isGIF}
|
||||
controls={!isGIF}
|
||||
playsinline
|
||||
loop={loopable}
|
||||
></video>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
<video
|
||||
src="${url}"
|
||||
poster="${previewUrl}"
|
||||
width="${width}"
|
||||
height="${height}"
|
||||
preload="auto"
|
||||
autoplay
|
||||
muted="${isGIF}"
|
||||
${isGIF ? '' : 'controls'}
|
||||
playsinline
|
||||
loop="${loopable}"
|
||||
></video>
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
) : isGIF ? (
|
||||
<video
|
||||
ref={videoRef}
|
||||
|
@ -1269,10 +1269,27 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
}
|
||||
}, 100);
|
||||
|
||||
const [showControls, setShowControls] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
let handleSwipe = () => {
|
||||
onClose();
|
||||
};
|
||||
if (carouselRef.current) {
|
||||
carouselRef.current.addEventListener('swiped-down', handleSwipe);
|
||||
}
|
||||
return () => {
|
||||
if (carouselRef.current) {
|
||||
carouselRef.current.removeEventListener('swiped-down', handleSwipe);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={carouselRef}
|
||||
data-swipe-threshold="44"
|
||||
class="carousel"
|
||||
onClick={(e) => {
|
||||
if (
|
||||
|
@ -1302,13 +1319,18 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
root={carouselRef.current}
|
||||
threshold={1}
|
||||
onChange={(inView) => onSnap(inView, i)}
|
||||
onClick={(e) => {
|
||||
if (e.target !== e.currentTarget) {
|
||||
setShowControls(!showControls);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Media media={media} showOriginal />
|
||||
</InView>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div class="carousel-top-controls">
|
||||
<div class="carousel-top-controls" hidden={!showControls}>
|
||||
<span />
|
||||
<button
|
||||
type="button"
|
||||
|
@ -1319,7 +1341,7 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
</button>
|
||||
</div>
|
||||
{mediaAttachments?.length > 1 && (
|
||||
<div class="carousel-controls">
|
||||
<div class="carousel-controls" hidden={!showControls}>
|
||||
<button
|
||||
type="button"
|
||||
class="carousel-button plain2"
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
padding: 16px !important;
|
||||
gap: 12px;
|
||||
}
|
||||
.notification.mention {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.only-mentions .notification:not(.mention),
|
||||
.only-mentions .timeline-empty {
|
||||
display: none;
|
||||
|
|
|
@ -51,6 +51,7 @@ function StatusPage({ id }) {
|
|||
|
||||
useEffect(() => {
|
||||
setUIState('loading');
|
||||
let heroTimer;
|
||||
|
||||
const cachedStatuses = store.session.getJSON('statuses-' + id);
|
||||
if (cachedStatuses) {
|
||||
|
@ -73,18 +74,28 @@ function StatusPage({ id }) {
|
|||
}
|
||||
|
||||
(async () => {
|
||||
const heroFetch = masto.v1.statuses.fetch(id);
|
||||
const heroFetch = () => masto.v1.statuses.fetch(id);
|
||||
const contextFetch = masto.v1.statuses.fetchContext(id);
|
||||
|
||||
const hasStatus = snapStates.statuses.has(id);
|
||||
let heroStatus = snapStates.statuses.get(id);
|
||||
try {
|
||||
heroStatus = await heroFetch;
|
||||
states.statuses.set(id, heroStatus);
|
||||
} catch (e) {
|
||||
// Silent fail if status is cached
|
||||
console.error(e);
|
||||
if (!hasStatus) {
|
||||
if (hasStatus) {
|
||||
console.log('Hero status is cached');
|
||||
heroTimer = setTimeout(async () => {
|
||||
try {
|
||||
heroStatus = await heroFetch();
|
||||
states.statuses.set(id, heroStatus);
|
||||
} catch (e) {
|
||||
// Silent fail if status is cached
|
||||
console.error(e);
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
try {
|
||||
heroStatus = await heroFetch();
|
||||
states.statuses.set(id, heroStatus);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setUIState('error');
|
||||
alert('Error fetching status');
|
||||
return;
|
||||
|
@ -153,6 +164,10 @@ function StatusPage({ id }) {
|
|||
setUIState('error');
|
||||
}
|
||||
})();
|
||||
|
||||
return () => {
|
||||
clearTimeout(heroTimer);
|
||||
};
|
||||
}, [id, snapStates.reloadStatusPage]);
|
||||
|
||||
const firstLoad = useRef(true);
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
import preact from '@preact/preset-vite';
|
||||
import { execSync } from 'child_process';
|
||||
import fs from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { defineConfig, loadEnv, splitVendorChunkPlugin } from 'vite';
|
||||
import htmlPlugin from 'vite-plugin-html-config';
|
||||
import VitePluginHtmlEnv from 'vite-plugin-html-env';
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
|
||||
const { VITE_CLIENT_NAME: CLIENT_NAME, NODE_ENV } = loadEnv(
|
||||
'production',
|
||||
process.cwd(),
|
||||
);
|
||||
const {
|
||||
VITE_CLIENT_NAME: CLIENT_NAME,
|
||||
NODE_ENV,
|
||||
VITE_APP_ERROR_LOGGING,
|
||||
} = loadEnv('production', process.cwd());
|
||||
|
||||
const commitHash = execSync('git rev-parse --short HEAD').toString().trim();
|
||||
|
||||
const rollbarCode = fs.readFileSync(
|
||||
resolve(__dirname, './rollbar.js'),
|
||||
'utf-8',
|
||||
);
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
mode: NODE_ENV,
|
||||
|
@ -23,6 +31,9 @@ export default defineConfig({
|
|||
preact(),
|
||||
splitVendorChunkPlugin(),
|
||||
VitePluginHtmlEnv(),
|
||||
htmlPlugin({
|
||||
headScripts: VITE_APP_ERROR_LOGGING ? [rollbarCode] : [],
|
||||
}),
|
||||
VitePWA({
|
||||
manifest: {
|
||||
name: CLIENT_NAME,
|
||||
|
|
Loading…
Reference in a new issue