mirror of
https://github.com/immich-app/immich.git
synced 2024-11-15 09:59:00 -07:00
feat: support and feedback modal with third party support (#13056)
This commit is contained in:
parent
ecb5cb00eb
commit
3eccff4306
@ -36,6 +36,10 @@ services:
|
||||
IMMICH_BUILD_URL: https://github.com/immich-app/immich/actions/runs/9654404849
|
||||
IMMICH_BUILD_IMAGE: development
|
||||
IMMICH_BUILD_IMAGE_URL: https://github.com/immich-app/immich/pkgs/container/immich-server
|
||||
IMMICH_THIRD_PARTY_SOURCE_URL: https://github.com/immich-app/immich/
|
||||
IMMICH_THIRD_PARTY_BUG_FEATURE_URL: https://github.com/immich-app/immich/issues
|
||||
IMMICH_THIRD_PARTY_DOCUMENTATION_URL: https://immich.app/docs
|
||||
IMMICH_THIRD_PARTY_SUPPORT_URL: https://immich.app/docs/third-party
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 1048576
|
||||
|
@ -28,6 +28,10 @@ class ServerAboutResponseDto {
|
||||
this.sourceCommit,
|
||||
this.sourceRef,
|
||||
this.sourceUrl,
|
||||
this.thirdPartyBugFeatureUrl,
|
||||
this.thirdPartyDocumentationUrl,
|
||||
this.thirdPartySourceUrl,
|
||||
this.thirdPartySupportUrl,
|
||||
required this.version,
|
||||
required this.versionUrl,
|
||||
});
|
||||
@ -146,6 +150,38 @@ class ServerAboutResponseDto {
|
||||
///
|
||||
String? sourceUrl;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? thirdPartyBugFeatureUrl;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? thirdPartyDocumentationUrl;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? thirdPartySourceUrl;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? thirdPartySupportUrl;
|
||||
|
||||
String version;
|
||||
|
||||
String versionUrl;
|
||||
@ -167,6 +203,10 @@ class ServerAboutResponseDto {
|
||||
other.sourceCommit == sourceCommit &&
|
||||
other.sourceRef == sourceRef &&
|
||||
other.sourceUrl == sourceUrl &&
|
||||
other.thirdPartyBugFeatureUrl == thirdPartyBugFeatureUrl &&
|
||||
other.thirdPartyDocumentationUrl == thirdPartyDocumentationUrl &&
|
||||
other.thirdPartySourceUrl == thirdPartySourceUrl &&
|
||||
other.thirdPartySupportUrl == thirdPartySupportUrl &&
|
||||
other.version == version &&
|
||||
other.versionUrl == versionUrl;
|
||||
|
||||
@ -188,11 +228,15 @@ class ServerAboutResponseDto {
|
||||
(sourceCommit == null ? 0 : sourceCommit!.hashCode) +
|
||||
(sourceRef == null ? 0 : sourceRef!.hashCode) +
|
||||
(sourceUrl == null ? 0 : sourceUrl!.hashCode) +
|
||||
(thirdPartyBugFeatureUrl == null ? 0 : thirdPartyBugFeatureUrl!.hashCode) +
|
||||
(thirdPartyDocumentationUrl == null ? 0 : thirdPartyDocumentationUrl!.hashCode) +
|
||||
(thirdPartySourceUrl == null ? 0 : thirdPartySourceUrl!.hashCode) +
|
||||
(thirdPartySupportUrl == null ? 0 : thirdPartySupportUrl!.hashCode) +
|
||||
(version.hashCode) +
|
||||
(versionUrl.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'ServerAboutResponseDto[build=$build, buildImage=$buildImage, buildImageUrl=$buildImageUrl, buildUrl=$buildUrl, exiftool=$exiftool, ffmpeg=$ffmpeg, imagemagick=$imagemagick, libvips=$libvips, licensed=$licensed, nodejs=$nodejs, repository=$repository, repositoryUrl=$repositoryUrl, sourceCommit=$sourceCommit, sourceRef=$sourceRef, sourceUrl=$sourceUrl, version=$version, versionUrl=$versionUrl]';
|
||||
String toString() => 'ServerAboutResponseDto[build=$build, buildImage=$buildImage, buildImageUrl=$buildImageUrl, buildUrl=$buildUrl, exiftool=$exiftool, ffmpeg=$ffmpeg, imagemagick=$imagemagick, libvips=$libvips, licensed=$licensed, nodejs=$nodejs, repository=$repository, repositoryUrl=$repositoryUrl, sourceCommit=$sourceCommit, sourceRef=$sourceRef, sourceUrl=$sourceUrl, thirdPartyBugFeatureUrl=$thirdPartyBugFeatureUrl, thirdPartyDocumentationUrl=$thirdPartyDocumentationUrl, thirdPartySourceUrl=$thirdPartySourceUrl, thirdPartySupportUrl=$thirdPartySupportUrl, version=$version, versionUrl=$versionUrl]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@ -266,6 +310,26 @@ class ServerAboutResponseDto {
|
||||
json[r'sourceUrl'] = this.sourceUrl;
|
||||
} else {
|
||||
// json[r'sourceUrl'] = null;
|
||||
}
|
||||
if (this.thirdPartyBugFeatureUrl != null) {
|
||||
json[r'thirdPartyBugFeatureUrl'] = this.thirdPartyBugFeatureUrl;
|
||||
} else {
|
||||
// json[r'thirdPartyBugFeatureUrl'] = null;
|
||||
}
|
||||
if (this.thirdPartyDocumentationUrl != null) {
|
||||
json[r'thirdPartyDocumentationUrl'] = this.thirdPartyDocumentationUrl;
|
||||
} else {
|
||||
// json[r'thirdPartyDocumentationUrl'] = null;
|
||||
}
|
||||
if (this.thirdPartySourceUrl != null) {
|
||||
json[r'thirdPartySourceUrl'] = this.thirdPartySourceUrl;
|
||||
} else {
|
||||
// json[r'thirdPartySourceUrl'] = null;
|
||||
}
|
||||
if (this.thirdPartySupportUrl != null) {
|
||||
json[r'thirdPartySupportUrl'] = this.thirdPartySupportUrl;
|
||||
} else {
|
||||
// json[r'thirdPartySupportUrl'] = null;
|
||||
}
|
||||
json[r'version'] = this.version;
|
||||
json[r'versionUrl'] = this.versionUrl;
|
||||
@ -296,6 +360,10 @@ class ServerAboutResponseDto {
|
||||
sourceCommit: mapValueOfType<String>(json, r'sourceCommit'),
|
||||
sourceRef: mapValueOfType<String>(json, r'sourceRef'),
|
||||
sourceUrl: mapValueOfType<String>(json, r'sourceUrl'),
|
||||
thirdPartyBugFeatureUrl: mapValueOfType<String>(json, r'thirdPartyBugFeatureUrl'),
|
||||
thirdPartyDocumentationUrl: mapValueOfType<String>(json, r'thirdPartyDocumentationUrl'),
|
||||
thirdPartySourceUrl: mapValueOfType<String>(json, r'thirdPartySourceUrl'),
|
||||
thirdPartySupportUrl: mapValueOfType<String>(json, r'thirdPartySupportUrl'),
|
||||
version: mapValueOfType<String>(json, r'version')!,
|
||||
versionUrl: mapValueOfType<String>(json, r'versionUrl')!,
|
||||
);
|
||||
|
@ -10780,6 +10780,18 @@
|
||||
"sourceUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"thirdPartyBugFeatureUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"thirdPartyDocumentationUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"thirdPartySourceUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"thirdPartySupportUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -917,6 +917,10 @@ export type ServerAboutResponseDto = {
|
||||
sourceCommit?: string;
|
||||
sourceRef?: string;
|
||||
sourceUrl?: string;
|
||||
thirdPartyBugFeatureUrl?: string;
|
||||
thirdPartyDocumentationUrl?: string;
|
||||
thirdPartySourceUrl?: string;
|
||||
thirdPartySupportUrl?: string;
|
||||
version: string;
|
||||
versionUrl: string;
|
||||
};
|
||||
|
@ -415,6 +415,10 @@ export const getBuildMetadata = () => ({
|
||||
sourceRef: process.env.IMMICH_SOURCE_REF,
|
||||
sourceCommit: process.env.IMMICH_SOURCE_COMMIT,
|
||||
sourceUrl: process.env.IMMICH_SOURCE_URL,
|
||||
thirdPartySourceUrl: process.env.IMMICH_THIRD_PARTY_SOURCE_URL,
|
||||
thirdPartyBugFeatureUrl: process.env.IMMICH_THIRD_PARTY_BUG_FEATURE_URL,
|
||||
thirdPartyDocumentationUrl: process.env.IMMICH_THIRD_PARTY_DOCUMENTATION_URL,
|
||||
thirdPartySupportUrl: process.env.IMMICH_THIRD_PARTY_SUPPORT_URL,
|
||||
});
|
||||
|
||||
const clientLicensePublicKeyProd =
|
||||
|
@ -30,6 +30,11 @@ export class ServerAboutResponseDto {
|
||||
exiftool?: string;
|
||||
|
||||
licensed!: boolean;
|
||||
|
||||
thirdPartySourceUrl?: string;
|
||||
thirdPartyBugFeatureUrl?: string;
|
||||
thirdPartyDocumentationUrl?: string;
|
||||
thirdPartySupportUrl?: string;
|
||||
}
|
||||
|
||||
export class ServerStorageResponseDto {
|
||||
|
@ -4,3 +4,6 @@ export const sunPath =
|
||||
|
||||
export const moonViewBox = '0 0 20 20';
|
||||
export const sunViewBox = '0 0 20 20';
|
||||
|
||||
export const discordPath =
|
||||
'M 9.1367188 3.8691406 C 9.1217187 3.8691406 9.1067969 3.8700938 9.0917969 3.8710938 C 8.9647969 3.8810937 5.9534375 4.1403594 4.0234375 5.6933594 C 3.0154375 6.6253594 1 12.073203 1 16.783203 C 1 16.866203 1.0215 16.946531 1.0625 17.019531 C 2.4535 19.462531 6.2473281 20.102859 7.1113281 20.130859 L 7.1269531 20.130859 C 7.2799531 20.130859 7.4236719 20.057594 7.5136719 19.933594 L 8.3886719 18.732422 C 6.0296719 18.122422 4.8248594 17.086391 4.7558594 17.025391 C 4.5578594 16.850391 4.5378906 16.549563 4.7128906 16.351562 C 4.8068906 16.244563 4.9383125 16.189453 5.0703125 16.189453 C 5.1823125 16.189453 5.2957188 16.228594 5.3867188 16.308594 C 5.4157187 16.334594 7.6340469 18.216797 11.998047 18.216797 C 16.370047 18.216797 18.589328 16.325641 18.611328 16.306641 C 18.702328 16.227641 18.815734 16.189453 18.927734 16.189453 C 19.059734 16.189453 19.190156 16.243562 19.285156 16.351562 C 19.459156 16.549563 19.441141 16.851391 19.244141 17.025391 C 19.174141 17.087391 17.968375 18.120469 15.609375 18.730469 L 16.484375 19.933594 C 16.574375 20.057594 16.718094 20.130859 16.871094 20.130859 L 16.886719 20.130859 C 17.751719 20.103859 21.5465 19.463531 22.9375 17.019531 C 22.9785 16.947531 23 16.866203 23 16.783203 C 23 12.073203 20.984172 6.624875 19.951172 5.671875 C 18.047172 4.140875 15.036203 3.8820937 14.908203 3.8710938 C 14.895203 3.8700938 14.880188 3.8691406 14.867188 3.8691406 C 14.681188 3.8691406 14.510594 3.9793906 14.433594 4.1503906 C 14.427594 4.1623906 14.362062 4.3138281 14.289062 4.5488281 C 15.548063 4.7608281 17.094141 5.1895937 18.494141 6.0585938 C 18.718141 6.1975938 18.787437 6.4917969 18.648438 6.7167969 C 18.558438 6.8627969 18.402188 6.9433594 18.242188 6.9433594 C 18.156188 6.9433594 18.069234 6.9200937 17.990234 6.8710938 C 15.584234 5.3800938 12.578 5.3046875 12 5.3046875 C 11.422 5.3046875 8.4157187 5.3810469 6.0117188 6.8730469 C 5.9327188 6.9210469 5.8457656 6.9433594 5.7597656 6.9433594 C 5.5997656 6.9433594 5.4425625 6.86475 5.3515625 6.71875 C 5.2115625 6.49375 5.2818594 6.1985938 5.5058594 6.0585938 C 6.9058594 5.1905937 8.4528906 4.7627812 9.7128906 4.5507812 C 9.6388906 4.3147813 9.5714062 4.1643437 9.5664062 4.1523438 C 9.4894063 3.9813438 9.3217188 3.8691406 9.1367188 3.8691406 z M 12 7.3046875 C 12.296 7.3046875 14.950594 7.3403125 16.933594 8.5703125 C 17.326594 8.8143125 17.777234 8.9453125 18.240234 8.9453125 C 18.633234 8.9453125 19.010656 8.8555 19.347656 8.6875 C 19.964656 10.2405 20.690828 12.686219 20.923828 15.199219 C 20.883828 15.143219 20.840922 15.089109 20.794922 15.037109 C 20.324922 14.498109 19.644687 14.191406 18.929688 14.191406 C 18.332687 14.191406 17.754078 14.405437 17.330078 14.773438 C 17.257078 14.832437 15.505 16.21875 12 16.21875 C 8.496 16.21875 6.7450313 14.834687 6.7070312 14.804688 C 6.2540312 14.407687 5.6742656 14.189453 5.0722656 14.189453 C 4.3612656 14.189453 3.6838438 14.494391 3.2148438 15.025391 C 3.1658438 15.080391 3.1201719 15.138266 3.0761719 15.197266 C 3.3091719 12.686266 4.0344375 10.235594 4.6484375 8.6835938 C 4.9864375 8.8525938 5.3657656 8.9433594 5.7597656 8.9433594 C 6.2217656 8.9433594 6.6724531 8.8143125 7.0644531 8.5703125 C 9.0494531 7.3393125 11.704 7.3046875 12 7.3046875 z M 8.890625 10.044922 C 7.966625 10.044922 7.2167969 10.901031 7.2167969 11.957031 C 7.2167969 13.013031 7.965625 13.869141 8.890625 13.869141 C 9.815625 13.869141 10.564453 13.013031 10.564453 11.957031 C 10.564453 10.900031 9.815625 10.044922 8.890625 10.044922 z M 15.109375 10.044922 C 14.185375 10.044922 13.435547 10.901031 13.435547 11.957031 C 13.435547 13.013031 14.184375 13.869141 15.109375 13.869141 C 16.034375 13.869141 16.783203 13.013031 16.783203 11.957031 C 16.783203 10.900031 16.033375 10.044922 15.109375 10.044922 z';
|
||||
|
@ -0,0 +1,131 @@
|
||||
<script lang="ts">
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
import Portal from '$lib/components/shared-components/portal/portal.svelte';
|
||||
import { type ServerAboutResponseDto } from '@immich/sdk';
|
||||
import { t } from 'svelte-i18n';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiBugOutline, mdiFaceAgent, mdiGit, mdiGithub, mdiInformationOutline } from '@mdi/js';
|
||||
import { discordPath } from '$lib/assets/svg-paths';
|
||||
|
||||
export let onClose: () => void;
|
||||
|
||||
export let info: ServerAboutResponseDto;
|
||||
</script>
|
||||
|
||||
<Portal>
|
||||
<FullScreenModal title={$t('support_and_feedback')} {onClose}>
|
||||
<p>{$t('official_immich_resources')}</p>
|
||||
<div class="flex flex-col sm:grid sm:grid-cols-2 gap-2 mt-3">
|
||||
<div>
|
||||
<a href="https://{info.version}.archive.immich.app/docs/overview/introduction" target="_blank" rel="noreferrer">
|
||||
<Icon path={mdiInformationOutline} size="1.5em" class="inline-block" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="documentation-label"
|
||||
>
|
||||
{$t('documentation')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="https://github.com/immich-app/immich/" target="_blank" rel="noreferrer">
|
||||
<Icon path={mdiGithub} size="1.5em" class="inline-block" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="github-label"
|
||||
>
|
||||
{$t('source')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="https://discord.immich.app" target="_blank" rel="noreferrer">
|
||||
<Icon path={discordPath} class="inline-block" size="1.5em" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="github-label"
|
||||
>
|
||||
{$t('discord')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="https://github.com/immich-app/immich/issues/new/choose" target="_blank" rel="noreferrer">
|
||||
<Icon path={mdiBugOutline} size="1.5em" class="inline-block" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="github-label"
|
||||
>
|
||||
{$t('bugs_and_feature_requests')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{#if info.thirdPartyBugFeatureUrl || info.thirdPartySourceUrl || info.thirdPartyDocumentationUrl || info.thirdPartySupportUrl}
|
||||
<p class="mt-3">{$t('third_party_resources')}</p>
|
||||
<p class="text-xs mt-1">
|
||||
{$t('support_third_party_description')}
|
||||
</p>
|
||||
<div class="flex flex-col sm:grid sm:grid-cols-2 gap-2 mt-3">
|
||||
{#if info.thirdPartyDocumentationUrl}
|
||||
<div>
|
||||
<a href={info.thirdPartyDocumentationUrl} target="_blank" rel="noreferrer">
|
||||
<Icon path={mdiInformationOutline} size="1.5em" class="inline-block" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="documentation-label"
|
||||
>
|
||||
{$t('documentation')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if info.thirdPartySourceUrl}
|
||||
<div>
|
||||
<a href={info.thirdPartySourceUrl} target="_blank" rel="noreferrer">
|
||||
<Icon path={mdiGit} size="1.5em" class="inline-block" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="github-label"
|
||||
>
|
||||
{$t('source')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if info.thirdPartySupportUrl}
|
||||
<div>
|
||||
<a href={info.thirdPartySupportUrl} target="_blank" rel="noreferrer">
|
||||
<Icon path={mdiFaceAgent} class="inline-block" size="1.5em" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="github-label"
|
||||
>
|
||||
{$t('support')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if info.thirdPartyBugFeatureUrl}
|
||||
<div>
|
||||
<a href={info.thirdPartyBugFeatureUrl} target="_blank" rel="noreferrer">
|
||||
<Icon path={mdiBugOutline} size="1.5em" class="inline-block" />
|
||||
<p
|
||||
class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm underline inline-block"
|
||||
id="github-label"
|
||||
>
|
||||
{$t('bugs_and_feature_requests')}
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</FullScreenModal>
|
||||
</Portal>
|
@ -8,32 +8,45 @@
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { handleLogout } from '$lib/utils/auth';
|
||||
import { logout } from '@immich/sdk';
|
||||
import { mdiMagnify, mdiTrayArrowUp } from '@mdi/js';
|
||||
import { getAboutInfo, logout, type ServerAboutResponseDto } from '@immich/sdk';
|
||||
import { mdiHelpCircleOutline, mdiMagnify, mdiTrayArrowUp } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { AppRoute } from '../../../constants';
|
||||
import ImmichLogo from '../immich-logo.svelte';
|
||||
import SearchBar from '../search-bar/search-bar.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
|
||||
import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte';
|
||||
import ThemeButton from '../theme-button.svelte';
|
||||
import UserAvatar from '../user-avatar.svelte';
|
||||
import AccountInfoPanel from './account-info-panel.svelte';
|
||||
import HelpAndFeedbackModal from '$lib/components/shared-components/help-and-feedback-modal.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let showUploadButton = true;
|
||||
export let onUploadClick: () => void;
|
||||
|
||||
let shouldShowAccountInfo = false;
|
||||
let shouldShowAccountInfoPanel = false;
|
||||
let shouldShowHelpPanel = false;
|
||||
let innerWidth: number;
|
||||
|
||||
const onLogout = async () => {
|
||||
const { redirectUri } = await logout();
|
||||
await handleLogout(redirectUri);
|
||||
};
|
||||
|
||||
let aboutInfo: ServerAboutResponseDto;
|
||||
|
||||
onMount(async () => {
|
||||
aboutInfo = await getAboutInfo();
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:window bind:innerWidth />
|
||||
|
||||
{#if shouldShowHelpPanel}
|
||||
<HelpAndFeedbackModal onClose={() => (shouldShowHelpPanel = false)} info={aboutInfo} />
|
||||
{/if}
|
||||
|
||||
<section id="dashboard-navbar" class="fixed z-[900] h-[var(--navbar-height)] w-screen text-sm">
|
||||
<SkipLink text={$t('skip_to_content')} />
|
||||
<div
|
||||
@ -49,7 +62,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<section class="flex place-items-center justify-end gap-2 md:gap-4 w-full sm:w-auto">
|
||||
<section class="flex place-items-center justify-end gap-1 md:gap-2 w-full sm:w-auto">
|
||||
{#if $featureFlags.search}
|
||||
<CircleIconButton
|
||||
href={AppRoute.SEARCH}
|
||||
@ -63,6 +76,20 @@
|
||||
|
||||
<ThemeButton padding="2" />
|
||||
|
||||
<div
|
||||
use:clickOutside={{
|
||||
onEscape: () => (shouldShowHelpPanel = false),
|
||||
}}
|
||||
>
|
||||
<CircleIconButton
|
||||
id="support-feedback-button"
|
||||
title={$t('support_and_feedback')}
|
||||
icon={mdiHelpCircleOutline}
|
||||
on:click={() => (shouldShowHelpPanel = !shouldShowHelpPanel)}
|
||||
padding="1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if !$page.url.pathname.includes('/admin') && showUploadButton}
|
||||
<LinkButton on:click={onUploadClick} class="hidden lg:block">
|
||||
<div class="flex gap-2">
|
||||
@ -87,7 +114,7 @@
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="flex"
|
||||
class="flex pl-2"
|
||||
on:mouseover={() => (shouldShowAccountInfo = true)}
|
||||
on:focus={() => (shouldShowAccountInfo = true)}
|
||||
on:blur={() => (shouldShowAccountInfo = false)}
|
||||
|
@ -416,6 +416,7 @@
|
||||
"birthdate_saved": "Date of birth saved successfully",
|
||||
"birthdate_set_description": "Date of birth is used to calculate the age of this person at the time of a photo.",
|
||||
"blurred_background": "Blurred background",
|
||||
"bugs_and_feature_requests": "Bugs & Feature Requests",
|
||||
"build": "Build",
|
||||
"build_image": "Build Image",
|
||||
"bulk_delete_duplicates_confirmation": "Are you sure you want to bulk delete {count, plural, one {# duplicate asset} other {# duplicate assets}}? This will keep the largest asset of each group and permanently delete all other duplicates. You cannot undo this action!",
|
||||
@ -521,6 +522,7 @@
|
||||
"direction": "Direction",
|
||||
"disabled": "Disabled",
|
||||
"disallow_edits": "Disallow edits",
|
||||
"discord": "Discord",
|
||||
"discover": "Discover",
|
||||
"dismiss_all_errors": "Dismiss all errors",
|
||||
"dismiss_error": "Dismiss error",
|
||||
@ -529,6 +531,7 @@
|
||||
"display_original_photos": "Display original photos",
|
||||
"display_original_photos_setting_description": "Prefer to display the original photo when viewing an asset rather than thumbnails when the original asset is web-compatible. This may result in slower photo display speeds.",
|
||||
"do_not_show_again": "Do not show this message again",
|
||||
"documentation": "Documentation",
|
||||
"done": "Done",
|
||||
"download": "Download",
|
||||
"download_include_embedded_motion_videos": "Embedded videos",
|
||||
@ -882,6 +885,7 @@
|
||||
"notifications": "Notifications",
|
||||
"notifications_setting_description": "Manage notifications",
|
||||
"oauth": "OAuth",
|
||||
"official_immich_resources": "Official Immich Resources",
|
||||
"offline": "Offline",
|
||||
"offline_paths": "Offline paths",
|
||||
"offline_paths_description": "These results may be due to manual deletion of files that are not part of an external library.",
|
||||
@ -1188,6 +1192,9 @@
|
||||
"submit": "Submit",
|
||||
"suggestions": "Suggestions",
|
||||
"sunrise_on_the_beach": "Sunrise on the beach",
|
||||
"support": "Support",
|
||||
"support_and_feedback": "Support & Feedback",
|
||||
"support_third_party_description": "Your immich installation was packaged by a third-party. Issues you experience may be caused by that package, so please raise issues with them in the first instance using the links below.",
|
||||
"swap_merge_direction": "Swap merge direction",
|
||||
"sync": "Sync",
|
||||
"tag": "Tag",
|
||||
@ -1203,6 +1210,7 @@
|
||||
"theme_selection": "Theme selection",
|
||||
"theme_selection_description": "Automatically set the theme to light or dark based on your browser's system preference",
|
||||
"they_will_be_merged_together": "They will be merged together",
|
||||
"third_party_resources": "Third-Party Resources",
|
||||
"time_based_memories": "Time-based memories",
|
||||
"timezone": "Timezone",
|
||||
"to_archive": "Archive",
|
||||
|
Loading…
Reference in New Issue
Block a user