Compare commits

...

4 Commits

Author SHA1 Message Date
Alex Tran
b192dfff38 wip 2025-03-01 13:53:22 -06:00
Mert
b3b15e9b61 fix(server): include deleted assets if searching offline assets (#16417)
include deleted assets if searching for offline assets
2025-02-28 09:23:18 -06:00
Zack Pollard
819e56d9ca fix: user delete sync query sort by id (#16420) 2025-02-28 09:22:36 -06:00
shenlong
9a98712db7 fix(mobile): background backup failing due to store (#16418)
fix: background backup failing due to store

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-02-28 07:38:51 -06:00
7 changed files with 59 additions and 4 deletions

View File

@@ -720,7 +720,6 @@ enum IosBackgroundTask { fetch, processing }
/// entry point called by Kotlin/Java code; needs to be a top-level function
@pragma('vm:entry-point')
void _nativeEntry() {
HttpOverrides.global = HttpSSLCertOverride();
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
BackgroundService backgroundService = BackgroundService();

View File

@@ -352,7 +352,7 @@ const joinDeduplicationPlugin = new DeduplicateJoinsPlugin();
/** TODO: This should only be used for search-related queries, not as a general purpose query builder */
export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuilderOptions) {
options.isArchived ??= options.withArchived ? undefined : false;
options.withDeleted ||= !!(options.trashedAfter || options.trashedBefore);
options.withDeleted ||= !!(options.trashedAfter || options.trashedBefore || options.isOffline);
return kysely
.withPlugin(joinDeduplicationPlugin)
.selectFrom('assets')

View File

@@ -53,7 +53,7 @@ export class SyncRepository {
.select(['id', 'userId'])
.$if(!!ack, (qb) => qb.where('id', '>', ack!.updateId))
.where('deletedAt', '<', sql.raw<Date>("now() - interval '1 millisecond'"))
.orderBy(['deletedAt asc', 'userId asc'])
.orderBy(['id asc'])
.stream();
}
}

View File

@@ -8,12 +8,14 @@
import { preferences, user } from '$lib/stores/user.store';
import { handleError } from '$lib/utils/handle-error';
import { deleteProfileImage, updateMyPreferences, type UserAvatarColor } from '@immich/sdk';
import { mdiCog, mdiLogout, mdiPencil, mdiWrench } from '@mdi/js';
import { mdiCog, mdiLogout, mdiPencil, mdiQrcode, mdiWrench } from '@mdi/js';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
import { NotificationType, notificationController } from '../notification/notification';
import UserAvatar from '../user-avatar.svelte';
import AvatarSelector from './avatar-selector.svelte';
import { IconButton } from '@immich/ui';
import { qrCodeLoginStore } from '$lib/stores/qrcode-login.svelte';
interface Props {
onLogout: () => void;
@@ -51,6 +53,14 @@
class="absolute right-[25px] top-[75px] z-[100] w-[min(360px,100vw-50px)] rounded-3xl bg-gray-200 shadow-lg dark:border dark:border-immich-dark-gray dark:bg-immich-dark-gray"
use:focusTrap
>
<div class="absolute right-8 top-8">
<IconButton
icon={mdiQrcode}
shape="round"
aria-label="Signin With QR Code"
onclick={() => qrCodeLoginStore.showForm()}
/>
</div>
<div
class="mx-4 mt-4 flex flex-col items-center justify-center gap-4 rounded-3xl bg-white p-4 dark:bg-immich-dark-primary/10"
>

View File

@@ -0,0 +1,31 @@
<script lang="ts">
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import { qrCodeLoginStore } from '$lib/stores/qrcode-login.svelte';
import { Button, Input } from '@immich/ui';
let password = $state('');
const submitPassword = (event: Event) => {
event.preventDefault();
console.log('Password submitted:', password);
};
</script>
{#if qrCodeLoginStore.shouldShowForm}
<div id="instance-qr-login">
<FullScreenModal title={'Login QR Code'} onClose={() => {}}>
<p class="text-xs">Enter your password to show the QR code</p>
<div class="mt-4">
<form onsubmit={submitPassword}>
<Input size="small" placeholder="Password" type="password" bind:value={password} required />
<div class="mt-6">
<Button type="submit" size="small" shape="round" fullWidth>Confirm</Button>
</div>
</form>
</div>
</FullScreenModal>
</div>
{/if}

View File

@@ -0,0 +1,13 @@
class QRCodeLoginStore {
shouldShowForm = $state(false);
showForm() {
this.shouldShowForm = true;
}
hideForm() {
this.shouldShowForm = false;
}
}
export const qrCodeLoginStore = new QRCodeLoginStore();

View File

@@ -22,6 +22,7 @@
import { setTranslations } from '@immich/ui';
import '../app.css';
import { t } from 'svelte-i18n';
import QRCodeLoginForm from '$lib/components/shared-components/qrcode-login-form.svelte';
interface Props {
children?: Snippet;
@@ -154,6 +155,7 @@
<UploadPanel />
<NotificationList />
<DialogWrapper />
<QRCodeLoginForm />
{#if $user?.isAdmin}
<VersionAnnouncementBox />