Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion extension/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "CleanMyPosts",
"version": "1.0.0",
"version": "1.0.1",
"description": "Bulk-delete your posts, replies, reposts, likes and followings on X, and your comments and liked videos on YouTube.",
"icons": {
"32": "icons/32x32.png",
Expand Down
2 changes: 1 addition & 1 deletion extension/src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function targetUrl(platform: Platform, action: Action, userName: string): string
case 'deleteReplies':
return `https://x.com/${user}/with_replies`;
case 'deleteReposts':
return `https://x.com/${user}`;
return `https://x.com/${user}/reposts`;
case 'deleteLikes':
return `https://x.com/${user}/likes`;
case 'deleteFollowing':
Expand Down
20 changes: 20 additions & 0 deletions release-notes/v3.5.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
### What's Changed

**Reposts moved, the app follows**

- Fix: X moved reposts off the profile timeline into a Reposts tab of their own. Deleting
reposts still opened the profile, found nothing there that could be unretweeted, and
reported nothing to remove (#64). The app and the extension now open
`x.com/<user>/reposts`, which is where the reposts went.
- Fix: The standalone script for reposts names the Reposts tab as the page to run it on.
Download it again if you kept a copy.

**Elsewhere**

- New: A reload button in the header, beside the assistant's, while X or YouTube is up —
triggering the same reload a finished run already does.
- Fix: The address in the header now follows every navigation the page makes, wherever a
link leads. It used to freeze on the last platform page once the user left the
platform's own hosts.

The extension carries the same fix on its own version line as v1.0.1.
2 changes: 1 addition & 1 deletion scripts/build-standalone.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const ACTIONS = [
file: 'cleanmyposts-x-delete-reposts',
from: 'x/reposts',
name: 'repostsAction',
page: 'your profile'
page: 'your profile’s Reposts tab'
},
{ file: 'cleanmyposts-x-delete-likes', from: 'x/likes', name: 'likesAction', page: 'your likes' },
{
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cleanmyposts"
version = "3.5.0"
version = "3.5.1"
description = "Bulk-delete your posts, reposts, replies, likes and comments on X and YouTube"
authors = ["thorstenalpers"]
repository = "https://github.com/thorstenalpers/CleanMyPosts"
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/commands/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn target_url(platform: &str, action: &str, user_name: &str) -> Option<String> {
("x", "showReplies" | "deleteReplies") => {
format!("https://x.com/{user}/with_replies")
}
("x", "showReposts" | "deleteReposts") => format!("https://x.com/{user}"),
("x", "showReposts" | "deleteReposts") => format!("https://x.com/{user}/reposts"),
("x", "showLikes" | "deleteLikes") => format!("https://x.com/{user}/likes"),
("x", "showFollowing" | "deleteFollowing") => {
format!("https://x.com/{user}/following")
Expand Down Expand Up @@ -663,7 +663,7 @@ mod tests {
);
assert_eq!(
target_url("x", "deleteReposts", "someuser").unwrap(),
"https://x.com/someuser"
"https://x.com/someuser/reposts"
);
assert_eq!(
target_url("x", "deleteLikes", "someuser").unwrap(),
Expand Down
18 changes: 18 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,13 +533,31 @@ pub fn run() {
// may land a beat early.
let auto_consent = app.state::<AppState>().settings.get().auto_consent;
let site_window = window.clone();
let nav_handle = app.handle().clone();
let _ = window.run_on_main_thread(move || {
for (label, url) in SITE_WEBVIEWS {
// The injected reporter goes quiet the moment the user leaves the
// platform's hosts, and the header would keep showing the last address it
// heard. This hook fires on every document navigation, whatever the host.
let platform = if label == "site-youtube" {
"youtube"
} else {
"x"
};
let handle = nav_handle.clone();
let built = site_window.add_child(
WebviewBuilder::new(
label,
WebviewUrl::External(url.parse().expect("static url")),
)
.on_navigation(move |url| {
crate::bridge::push_event(
&handle,
"siteUrl",
serde_json::json!({ "platform": platform, "url": url.as_str() }),
);
true
})
.initialization_script_for_all_frames(site_init_script(auto_consent)),
LogicalPosition::new(size.width, f64::from(DEFAULT_HEADER_HEIGHT)),
LogicalSize::new(
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "CleanMyPosts",
"version": "3.5.0",
"version": "3.5.1",
"identifier": "com.thorstenalpers.cleanmyposts",
"build": {
"frontendDist": "../build",
Expand Down
14 changes: 13 additions & 1 deletion src/lib/bridge/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,17 @@ export const SiteLoginPayloadSchema = z.object({
});
export type SiteLoginPayload = z.infer<typeof SiteLoginPayloadSchema>;

/**
* Every document navigation of a platform's webview, reported by the host. The injected
* reporter only speaks on the platform's own hosts; this is what keeps the header's address
* honest when the user follows a link off them.
*/
export const SiteUrlPayloadSchema = z.object({
platform: PlatformSchema,
url: z.string()
});
export type SiteUrlPayload = z.infer<typeof SiteUrlPayloadSchema>;

export const UpdateProgressPayloadSchema = z.object({
downloaded: z.number().int().nonnegative(),
/** Absent when the server sends no length; the bar runs indeterminate then. */
Expand All @@ -479,7 +490,8 @@ export const PushEventSchema = z.discriminatedUnion('event', [
z.object({ event: z.literal('progress'), payload: ProgressPayloadSchema }),
z.object({ event: z.literal('updateProgress'), payload: UpdateProgressPayloadSchema }),
z.object({ event: z.literal('settingsChanged'), payload: AppSettingsSchema }),
z.object({ event: z.literal('siteLogin'), payload: SiteLoginPayloadSchema })
z.object({ event: z.literal('siteLogin'), payload: SiteLoginPayloadSchema }),
z.object({ event: z.literal('siteUrl'), payload: SiteUrlPayloadSchema })
]);
export type PushEvent = z.infer<typeof PushEventSchema>;

Expand Down
15 changes: 15 additions & 0 deletions src/lib/components/page-header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import LanguageMenu from '$lib/components/language-menu.svelte';
import ModeToggle from '$lib/components/mode-toggle.svelte';
import PanelLeftIcon from '@lucide/svelte/icons/panel-left';
import RefreshCwIcon from '@lucide/svelte/icons/refresh-cw';
import SparklesIcon from '@lucide/svelte/icons/sparkles';
import { cn } from '$lib/utils';
import type { SettingsStore } from '$lib/stores/settings.svelte';
Expand All @@ -28,6 +29,8 @@
* it, so this is the way back.
*/
onOpenActions?: () => void;
/** Given only while a platform is up: the app's own pages have nothing to reload. */
onReload?: () => void;
/** The assistant lives in the app's own column, so its way in belongs in this bar. */
onToggleAssistant?: () => void;
assistantOpen?: boolean;
Expand All @@ -40,6 +43,7 @@
iconOnly = false,
settingsStore,
onMenuOpenChange,
onReload,
onOpenActions,
onToggleAssistant,
assistantOpen = false
Expand Down Expand Up @@ -76,6 +80,17 @@
</span>

<div class="flex shrink-0 items-center gap-0.5">
{#if onReload}
<button
type="button"
aria-label={t('header.reload')}
title={t('header.reload')}
onclick={onReload}
class="flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors duration-150 hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none"
>
<RefreshCwIcon class="size-4" />
</button>
{/if}
{#if onToggleAssistant}
<button
type="button"
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ export const ar: Record<MessageKey, string> = {
'assistant.dismiss': 'إخفاء',

'header.url': 'أنت هنا',
'header.reload': 'إعادة تحميل الصفحة',

'log.column.time': 'الوقت',
'log.column.level': 'المستوى',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ export const de: Record<MessageKey, string> = {
'assistant.dismiss': 'Ausblenden',

'header.url': 'Du bist hier',
'header.reload': 'Seite neu laden',

'log.column.time': 'Zeit',
'log.column.level': 'Stufe',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ export const en = {
'assistant.dismiss': 'Dismiss',

'header.url': 'You are here',
'header.reload': 'Reload page',

'log.column.time': 'Time',
'log.column.level': 'Level',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ export const es: Record<MessageKey, string> = {
'assistant.dismiss': 'Ocultar',

'header.url': 'Estás aquí',
'header.reload': 'Recargar la página',

'log.column.time': 'Hora',
'log.column.level': 'Nivel',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ export const fr: Record<MessageKey, string> = {
'assistant.dismiss': 'Masquer',

'header.url': 'Tu es ici',
'header.reload': 'Recharger la page',

'log.column.time': 'Heure',
'log.column.level': 'Niveau',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/hi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ export const hi: Record<MessageKey, string> = {
'assistant.dismiss': 'हटाएँ',

'header.url': 'आप यहाँ हैं',
'header.reload': 'पेज फिर से लोड करें',

'log.column.time': 'समय',
'log.column.level': 'स्तर',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ export const it: Record<MessageKey, string> = {
'assistant.dismiss': 'Nascondi',

'header.url': 'Sei qui',
'header.reload': 'Ricarica la pagina',

'log.column.time': 'Ora',
'log.column.level': 'Livello',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ export const ja: Record<MessageKey, string> = {
'assistant.dismiss': '閉じる',

'header.url': '現在の場所',
'header.reload': 'ページを再読み込み',

'log.column.time': '時刻',
'log.column.level': 'レベル',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ export const pt: Record<MessageKey, string> = {
'assistant.dismiss': 'Esconder',

'header.url': 'Estás aqui',
'header.reload': 'Recarregar a página',

'log.column.time': 'Hora',
'log.column.level': 'Nível',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ export const ru: Record<MessageKey, string> = {
'assistant.dismiss': 'Скрыть',

'header.url': 'Вы здесь',
'header.reload': 'Перезагрузить страницу',

'log.column.time': 'Время',
'log.column.level': 'Уровень',
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ export const zh: Record<MessageKey, string> = {
'assistant.dismiss': '关闭',

'header.url': '你在这里',
'header.reload': '重新加载页面',

'log.column.time': '时间',
'log.column.level': '级别',
Expand Down
2 changes: 2 additions & 0 deletions src/lib/stores/site-login.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export class SiteLoginStore {
if (event.payload.url) {
this.url = { ...this.url, [event.payload.platform]: event.payload.url };
}
} else if (event.event === 'siteUrl') {
this.url = { ...this.url, [event.payload.platform]: event.payload.url };
}
});
}
Expand Down
3 changes: 3 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,9 @@
{location}
{settingsStore}
onMenuOpenChange={(open: boolean) => (headerMenuOpen = open)}
onReload={railPlatform
? () => void bridge.call('site.reload', { platform: railPlatform }).catch(() => {})
: undefined}
onToggleAssistant={assistantReady ? () => (assistantOpen = !assistantOpen) : undefined}
assistantOpen={assistantVisible}
onOpenActions={railPlatform && !panelVisible
Expand Down