v0.12.15 PWA bug and schema error for GM
This commit is contained in:
@@ -19,6 +19,9 @@ export default function ProfileModal({ onClose }) {
|
||||
const [tab, setTab] = useState('profile'); // 'profile' | 'password' | 'notifications'
|
||||
const [pushTesting, setPushTesting] = useState(false);
|
||||
const [pushResult, setPushResult] = useState(null);
|
||||
const [notifPermission, setNotifPermission] = useState(
|
||||
typeof Notification !== 'undefined' ? Notification.permission : 'unsupported'
|
||||
);
|
||||
const [hideAdminTag, setHideAdminTag] = useState(!!user?.hide_admin_tag);
|
||||
const [allowDm, setAllowDm] = useState(user?.allow_dm !== 0);
|
||||
|
||||
@@ -172,58 +175,77 @@ export default function ProfileModal({ onClose }) {
|
||||
|
||||
{tab === 'notifications' && (
|
||||
<div className="flex-col gap-3">
|
||||
<div style={{ fontSize: 14, color: 'var(--text-secondary)', lineHeight: 1.5 }}>
|
||||
<p style={{ margin: '0 0 8px' }}>Tap <strong>Send Test Notification</strong> to trigger a push to this device. The notification will arrive shortly if everything is configured correctly.</p>
|
||||
<p style={{ margin: 0 }}>If it doesn't arrive, check:<br/>
|
||||
• Notification permission granted (browser prompt)<br/>
|
||||
• Android Settings → Apps → RosterChirp → Notifications → Enabled<br/>
|
||||
• App is backgrounded when the test fires
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
style={{ flex: 1 }}
|
||||
disabled={pushTesting}
|
||||
onClick={async () => {
|
||||
setPushTesting(true);
|
||||
setPushResult(null);
|
||||
try {
|
||||
const { results } = await api.testPush('data');
|
||||
setPushResult({ ok: true, results, mode: 'data' });
|
||||
} catch (e) {
|
||||
setPushResult({ ok: false, error: e.message });
|
||||
} finally {
|
||||
setPushTesting(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{pushTesting ? 'Sending…' : 'Test (via SW)'}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-secondary"
|
||||
style={{ flex: 1 }}
|
||||
disabled={pushTesting}
|
||||
onClick={async () => {
|
||||
setPushTesting(true);
|
||||
setPushResult(null);
|
||||
try {
|
||||
const { results } = await api.testPush('browser');
|
||||
setPushResult({ ok: true, results, mode: 'browser' });
|
||||
} catch (e) {
|
||||
setPushResult({ ok: false, error: e.message });
|
||||
} finally {
|
||||
setPushTesting(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{pushTesting ? 'Sending…' : 'Test (via Browser)'}
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-tertiary)', lineHeight: 1.4 }}>
|
||||
<strong>Test (via SW)</strong> — normal production path, service worker shows notification.<br/>
|
||||
<strong>Test (via Browser)</strong> — bypasses service worker; Chrome displays directly.
|
||||
</div>
|
||||
{notifPermission !== 'granted' && notifPermission !== 'unsupported' && (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '10px 12px', borderRadius: 8, background: 'var(--surface-variant)' }}>
|
||||
<div style={{ fontSize: 14, color: 'var(--text-secondary)' }}>
|
||||
{notifPermission === 'denied'
|
||||
? 'Notifications are blocked. Enable them in Android Settings → Apps → RosterChirp → Notifications.'
|
||||
: 'Push notifications are not yet enabled on this device.'}
|
||||
</div>
|
||||
{notifPermission === 'default' && (
|
||||
<button className="btn btn-primary btn-sm" onClick={async () => {
|
||||
const result = await Notification.requestPermission();
|
||||
setNotifPermission(result);
|
||||
if (result === 'granted') window.dispatchEvent(new CustomEvent('rosterchirp:push-init'));
|
||||
}}>Enable Notifications</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{notifPermission === 'granted' && (
|
||||
<div style={{ fontSize: 14, color: 'var(--text-secondary)', lineHeight: 1.5 }}>
|
||||
<p style={{ margin: '0 0 8px' }}>Tap <strong>Send Test Notification</strong> to trigger a push to this device. The notification will arrive shortly if everything is configured correctly.</p>
|
||||
<p style={{ margin: 0 }}>If it doesn't arrive, check:<br/>
|
||||
• Android Settings → Apps → RosterChirp → Notifications → Enabled<br/>
|
||||
• App is backgrounded when the test fires
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{notifPermission === 'granted' && (<>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
style={{ flex: 1 }}
|
||||
disabled={pushTesting}
|
||||
onClick={async () => {
|
||||
setPushTesting(true);
|
||||
setPushResult(null);
|
||||
try {
|
||||
const { results } = await api.testPush('data');
|
||||
setPushResult({ ok: true, results, mode: 'data' });
|
||||
} catch (e) {
|
||||
setPushResult({ ok: false, error: e.message });
|
||||
} finally {
|
||||
setPushTesting(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{pushTesting ? 'Sending…' : 'Test (via SW)'}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-secondary"
|
||||
style={{ flex: 1 }}
|
||||
disabled={pushTesting}
|
||||
onClick={async () => {
|
||||
setPushTesting(true);
|
||||
setPushResult(null);
|
||||
try {
|
||||
const { results } = await api.testPush('browser');
|
||||
setPushResult({ ok: true, results, mode: 'browser' });
|
||||
} catch (e) {
|
||||
setPushResult({ ok: false, error: e.message });
|
||||
} finally {
|
||||
setPushTesting(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{pushTesting ? 'Sending…' : 'Test (via Browser)'}
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-tertiary)', lineHeight: 1.4 }}>
|
||||
<strong>Test (via SW)</strong> — normal production path, service worker shows notification.<br/>
|
||||
<strong>Test (via Browser)</strong> — bypasses service worker; Chrome displays directly.
|
||||
</div>
|
||||
</>)}
|
||||
{pushResult && (
|
||||
<div style={{
|
||||
padding: '10px 12px',
|
||||
|
||||
Reference in New Issue
Block a user