Conversation
de5b08e to
1baf5fd
Compare
73357f6 to
6db275d
Compare
1baf5fd to
9676f6f
Compare
6db275d to
4cff483
Compare
6192b58 to
30ade19
Compare
ccebb0e to
1555eba
Compare
30ade19 to
6ee19d9
Compare
1555eba to
4da5ad5
Compare
6ee19d9 to
c9b2a78
Compare
817712c to
7158776
Compare
packages/playground/personal-wp/src/components/backup-reminder/index.tsx
Outdated
Show resolved
Hide resolved
packages/playground/personal-wp/src/components/backup-reminder/index.tsx
Show resolved
Hide resolved
| const response = await playground.run({ | ||
| code: `<?php | ||
| require_once '/wordpress/wp-load.php'; | ||
| echo html_entity_decode(get_option('blogname', 'WordPress'), ENT_QUOTES, 'UTF-8'); |
There was a problem hiding this comment.
Can we use WordPress HTML API for this? Or decode is in JavaScript? html_entity_decode doesn't do its job well.
There was a problem hiding this comment.
What about using json_encode() in PHP and JSON.parse() in JS? That would fully avoid any HTML entities.
There was a problem hiding this comment.
or actually, right now:
get_option()→Alex's WordPresshtml_entity_decode()→Alex's WordPresssanitizeForFilename()→Alex-s-WordPress(apostrophe becomes-)
I just verified that WordPress stores the blogname via
case 'blogdescription':
case 'blogname':
// ...
$value = esc_html( $value );
break;Which itself uses _wp_specialchars which itself uses htmlspecialchars for which html_entity_decode should be appropriate.
7158776 to
b72b187
Compare
Adds a dropdown to the backup reminder UI that lets users schedule automatic backup downloads on a daily, every-2-days, or weekly basis. When enabled, the toolbar backup indicator is hidden and backups trigger automatically after WordPress boots.
Remove redundant daysUsedSinceLastBackup tracking. The backup indicator now derives days since last backup directly from backupHistory timestamps, which is simpler and more reliable.
| const [showHistory, setShowHistory] = useState(false); | ||
| const importInputRef = useRef<HTMLInputElement>(null); | ||
|
|
||
| // TODO: Support local directory sites. With a directory handle, we could |
| } from '../../lib/hooks/use-backup-constants'; | ||
| import { isSameDay } from '../../lib/utils/date'; | ||
|
|
||
| function getDaysSinceBackup(lastBackupTimestamp: number | undefined): number { |
There was a problem hiding this comment.
We have some datetime formatting utils we could reuse here. Not a blocker.
|
|
||
| const message = hasBackup | ||
| ? 'Are you sure you want to start over? This will delete all your data and reset WordPress to a fresh install.' | ||
| : 'Are you sure you want to start over? You have never made a backup – all your data will be permanently lost.'; |
| return; | ||
| } | ||
|
|
||
| // Reset trigger flag when switching to a different site |
There was a problem hiding this comment.
oh, you can switch to a different site here? how? or is this just "defense in depth" in case someone finds a button we forgot to hide?
| code: `<?php | ||
| require_once '/wordpress/wp-load.php'; | ||
| $name = get_option('blogname', 'WordPress'); | ||
| echo html_entity_decode($name, ENT_QUOTES, 'UTF-8'); |
There was a problem hiding this comment.
hm I can't see my previous comment, I'm pretty sure I've left it here 🤔 html_entity_decode is pretty bad, we'd be better off decoding in JS. I wouldn't say it's a blocker because of how the siteName is used, but changing it might save us some & literals.
There was a problem hiding this comment.
@copilot echo $name and decode the entity in JS in a secure way.
| @@ -0,0 +1,31 @@ | |||
| export function getRelativeDate(inputDate: Date): string { | |||
There was a problem hiding this comment.
nit: we could extract this to a shared package and import in both website and personal-wp. Not blocking.
adamziel
left a comment
There was a problem hiding this comment.
LGTM aside of the html encoding issue. I've asked copilot to adjust it. We can merge regardless.


Based on #3157.
Motivation for the change, related issues
Personal Playgrounds store data in the browser's Origin Private File System (OPFS), which can be cleared unexpectedly by the browser. Users need a gentle reminder to back up their work periodically to avoid data loss.
This PR adds a backup status indicator that tracks usage days since the last backup and prompts users to download backups based on urgency.
Screenshots
(No button when the backup is up to date)
Auto-Backup
Implementation details
New files:
backup-status-indicator.tsx- Component showing days since last backup with color-coded urgency (green ≤1 day, yellow 2-4 days, red 5+ days)backup-status-indicator.module.css- Styles for the indicator buttonuse-backup.ts- Hook that handles backup creation usingzipWpContentandfile-saverModified files:
slice-sites.ts- Added metadata fields:backupHistory- Array of recent backups (filename + timestamp)lastAccessDate- Timestamp for tracking usage daysdaysUsedSinceLastBackup- Counter reset on backuppersistent-browser-chrome/index.tsx- Added BackupStatusIndicator to toolbarBehavior:
Testing Instructions (or ideally a Blueprint)
{site-name}-backup-{date}-{time}.zipdaysUsedSinceLastBackupto 5 - indicator should appear in red