Compare commits

..

7 Commits

Author SHA1 Message Date
Alex The Bot
3dddc6b449 Version v1.93.2 2024-01-19 18:29:04 +00:00
Alex
88ac3c2016 fix(web): better invite shared user to album layout (#6511)
* fix(web): better invite to album design

* rounded corner

* use icon

* padding
2024-01-19 12:27:29 -06:00
martin
17eaeb695e feat: smart merge (#6508)
* pr feedback

* fix: tests

* update assets statistics

* pr feedback

* pr feedback

* fix: linter

* pr feedback

* fix: don't limit the smart merge

* pr feedback

* fix: server code

* remove slider

* fix: tests

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2024-01-19 17:52:26 +00:00
shenlong
f80f867976 fix(mobile): stack button not in bottom app bar (#6497)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2024-01-19 17:40:10 +00:00
martin
d15c443d9b fix(web): user list when sharing an album (#6500)
fix: user list when sharing an album

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-01-19 17:38:44 +00:00
Alex
07b874edda fix(web): revert smart merge (#6504)
* revert smart merge

* fix test

* fix test

* Remove Slider file
2024-01-19 11:34:20 -06:00
Jason Rasmussen
df27460f1c fix: open api pump (#6502) 2024-01-19 11:09:18 -06:00
20 changed files with 119 additions and 125 deletions

View File

@@ -7,11 +7,7 @@ Immich uses the [OpenAPI](https://swagger.io/specification/) standard to generat
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). The generated SDK is based on the `immich-openapi-specs.json` file, which is autogenerated by the server **when running in development mode**. The `immich-openapi-specs.json` file can be modified with `@nestjs/swagger` decorators used or referenced by controller endpoints. See the [NestJS OpenAPI docs](https://docs.nestjs.com/openapi/types-and-parameters) for more info. When you add a new endpoint or modify an existing one, you must run the server in development mode and run the command below to update the client SDK.
```bash
npm run api:generate # Run from the `server/` directory
make open-api
```
You can find the generated client SDK in the `web/src/api` for Typescript SDK and `mobile/openapi` for Dart SDK.
:::tip
This can also be run via `make open-api` from the project root directory (not in the `server` folder)
:::
You can find the generated client SDK in the `open-api/typescript-sdk/client` for Typescript SDK and `mobile/openapi` for Dart SDK.

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "machine-learning"
version = "1.93.1"
version = "1.93.2"
description = ""
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
readme = "README.md"

View File

@@ -62,7 +62,7 @@ fi
if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
echo "Pumping Server: $CURRENT_SERVER => $NEXT_SERVER"
npm --prefix server version $SERVER_PUMP
npm --prefix server run api:generate
make open-api
poetry --directory machine-learning version $SERVER_PUMP
fi

View File

@@ -35,8 +35,8 @@ platform :android do
task: 'bundle',
build_type: 'Release',
properties: {
"android.injected.version.code" => 118,
"android.injected.version.name" => "1.93.1",
"android.injected.version.code" => 119,
"android.injected.version.name" => "1.93.2",
}
)
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')

View File

@@ -19,7 +19,7 @@ platform :ios do
desc "iOS Beta"
lane :beta do
increment_version_number(
version_number: "1.93.1"
version_number: "1.93.2"
)
increment_build_number(
build_number: latest_testflight_build_number + 1,

View File

@@ -197,7 +197,7 @@ class ControlBottomAppBar extends ConsumerWidget {
label: "control_bottom_app_bar_edit_location".tr(),
onPressed: enabled ? onEditLocation : null,
),
if (!hasLocal &&
if (!selectionAssetState.hasLocal &&
selectionAssetState.selectedCount > 1 &&
onStack != null)
ControlBoxButton(
@@ -211,7 +211,7 @@ class ControlBottomAppBar extends ConsumerWidget {
label: 'album_viewer_appbar_share_remove'.tr(),
onPressed: enabled ? onRemoveFromAlbum : null,
),
if (hasLocal)
if (selectionAssetState.hasLocal)
ControlBoxButton(
iconData: Icons.backup_outlined,
label: "Upload",

View File

@@ -3,7 +3,7 @@ Immich API
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
- API version: 1.93.0
- API version: 1.93.2
- Build package: org.openapitools.codegen.languages.DartClientCodegen
## Requirements

View File

@@ -2,7 +2,7 @@ name: immich_mobile
description: Immich - selfhosted backup media file on mobile phone
publish_to: "none"
version: 1.93.1+118
version: 1.93.2+119
isar_version: &isar_version 3.1.0+1
environment:

View File

@@ -6221,7 +6221,7 @@
"info": {
"title": "Immich",
"description": "Immich API",
"version": "1.93.0",
"version": "1.93.2",
"contact": {}
},
"tags": [],

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.93.0
* The version of the OpenAPI document: 1.93.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.93.0
* The version of the OpenAPI document: 1.93.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.93.0
* The version of the OpenAPI document: 1.93.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.93.0
* The version of the OpenAPI document: 1.93.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.93.0
* The version of the OpenAPI document: 1.93.2
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -1,12 +1,12 @@
{
"name": "immich",
"version": "1.93.1",
"version": "1.93.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "immich",
"version": "1.93.1",
"version": "1.93.2",
"license": "UNLICENSED",
"dependencies": {
"@babel/runtime": "^7.22.11",

View File

@@ -1,6 +1,6 @@
{
"name": "immich",
"version": "1.93.1",
"version": "1.93.2",
"description": "",
"author": "",
"private": true,

View File

@@ -1014,8 +1014,6 @@ describe(PersonService.name, () => {
oldPersonId: personStub.mergePerson.id,
});
expect(personMock.update).not.toHaveBeenCalled();
expect(accessMock.person.checkOwnerAccess).toHaveBeenCalledWith(authStub.admin.user.id, new Set(['person-1']));
});
@@ -1040,7 +1038,6 @@ describe(PersonService.name, () => {
name: personStub.primaryPerson.name,
});
expect(personMock.delete).toHaveBeenCalledWith([personStub.primaryPerson]);
expect(accessMock.person.checkOwnerAccess).toHaveBeenCalledWith(authStub.admin.user.id, new Set(['person-1']));
});

View File

@@ -2,7 +2,6 @@
import { quintOut } from 'svelte/easing';
import { fly } from 'svelte/transition';
import { createEventDispatcher } from 'svelte';
import Slider from '$lib/components/elements/slider.svelte';
export let title: string;
export let subtitle = '';
@@ -11,6 +10,7 @@
export let isEdited = false;
const dispatch = createEventDispatcher<{ toggle: boolean }>();
const onToggle = (event: Event) => dispatch('toggle', (event.target as HTMLInputElement).checked);
</script>
<div class="flex place-items-center justify-between">
@@ -31,5 +31,67 @@
<p class="text-sm dark:text-immich-dark-fg">{subtitle}</p>
</div>
<Slider bind:checked {disabled} on:toggle={() => dispatch('toggle', checked)} />
<label class="relative inline-block h-[10px] w-[36px] flex-none">
<input
class="disabled::cursor-not-allowed h-0 w-0 opacity-0"
type="checkbox"
bind:checked
on:click={onToggle}
{disabled}
/>
{#if disabled}
<span class="slider slider-disabled cursor-not-allowed" />
{:else}
<span class="slider slider-enabled cursor-pointer" />
{/if}
</label>
</div>
<style>
.slider {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 34px;
}
input:disabled {
cursor: not-allowed;
}
.slider:before {
position: absolute;
content: '';
height: 20px;
width: 20px;
left: 0px;
right: 0px;
bottom: -4px;
background-color: gray;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 50%;
}
input:checked + .slider:before {
-webkit-transform: translateX(18px);
-ms-transform: translateX(18px);
transform: translateX(18px);
background-color: #4250af;
}
input:checked + .slider-disabled {
background-color: gray;
}
input:checked + .slider-enabled {
background-color: #adcbfa;
}
</style>

View File

@@ -7,7 +7,7 @@
import ImmichLogo from '../shared-components/immich-logo.svelte';
import Button from '../elements/buttons/button.svelte';
import { AppRoute } from '$lib/constants';
import { mdiLink, mdiShareCircle } from '@mdi/js';
import { mdiCheck, mdiLink, mdiShareCircle } from '@mdi/js';
import Icon from '$lib/components/elements/icon.svelte';
export let album: AlbumResponseDto;
@@ -60,28 +60,25 @@
</span>
</svelte:fragment>
<div class="immich-scrollbar max-h-[300px] overflow-y-auto">
{#if selectedUsers.length > 0}
<div class="mb-2 flex place-items-center gap-4 overflow-x-auto px-5 py-2">
<p class="font-medium">To</p>
{#if selectedUsers.length > 0}
<div class="mb-2 flex flex-wrap place-items-center gap-4 overflow-x-auto px-5 py-2 sticky">
<p class="font-medium">To</p>
{#each selectedUsers as user}
{#key user.id}
<button
on:click={() => handleUnselect(user)}
class="flex place-items-center gap-1 rounded-full border border-gray-400 p-1 transition-colors hover:bg-gray-200 dark:hover:bg-gray-700"
>
<UserAvatar {user} size="sm" />
<p class="text-xs font-medium">{user.name}</p>
</button>
{/key}
{/each}
<div class="flex place-content-end mr-0 ml-auto p-5">
<Button size="sm" rounded="lg" on:click={() => dispatch('select', selectedUsers)}>Add</Button>
</div>
</div>
{/if}
{#each selectedUsers as user}
{#key user.id}
<button
on:click={() => handleUnselect(user)}
class="flex place-items-center gap-1 rounded-full border border-gray-500 p-2 transition-colors hover:bg-gray-200 dark:hover:bg-gray-700"
>
<UserAvatar {user} size="sm" />
<p class="text-xs font-medium">{user.name}</p>
</button>
{/key}
{/each}
</div>
{/if}
<div class="immich-scrollbar max-h-[500px] overflow-y-auto">
{#if users.length > 0}
<p class="px-5 text-xs font-medium">SUGGESTIONS</p>
@@ -92,10 +89,11 @@
class="flex w-full place-items-center gap-4 px-5 py-4 transition-all hover:bg-gray-200 dark:hover:bg-gray-700"
>
{#if selectedUsers.includes(user)}
<span
class="flex h-12 w-12 place-content-center place-items-center rounded-full border bg-immich-primary text-3xl text-white dark:border-immich-dark-gray dark:bg-immich-dark-primary dark:text-immich-dark-bg"
></span
<div
class="flex h-10 w-10 items-center justify-center rounded-full border bg-immich-primary text-3xl text-white dark:border-immich-dark-gray dark:bg-immich-dark-primary dark:text-immich-dark-bg"
>
<Icon path={mdiCheck} size={24} />
</div>
{:else}
<UserAvatar {user} size="md" />
{/if}
@@ -118,7 +116,20 @@
{/if}
</div>
{#if users.length > 0}
<div class="p-3">
<Button
size="sm"
fullwidth
rounded="full"
disabled={!selectedUsers.length}
on:click={() => dispatch('select', selectedUsers)}>Add</Button
>
</div>
{/if}
<hr />
<div id="shared-buttons" class="my-4 flex place-content-center place-items-center justify-around">
<button
class="flex flex-col place-content-center place-items-center gap-2 hover:cursor-pointer"

View File

@@ -1,72 +0,0 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
export let checked = false;
export let disabled = false;
const dispatch = createEventDispatcher<{ toggle: boolean }>();
const onToggle = (event: Event) => dispatch('toggle', (event.target as HTMLInputElement).checked);
</script>
<label class="relative inline-block h-[10px] w-[36px] flex-none">
<input
class="disabled::cursor-not-allowed h-0 w-0 opacity-0"
type="checkbox"
bind:checked
on:click={onToggle}
{disabled}
/>
{#if disabled}
<span class="slider slider-disabled cursor-not-allowed" />
{:else}
<span class="slider slider-enabled cursor-pointer" />
{/if}
</label>
<style>
.slider {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 34px;
}
input:disabled {
cursor: not-allowed;
}
.slider:before {
position: absolute;
content: '';
height: 20px;
width: 20px;
left: 0px;
right: 0px;
bottom: -4px;
background-color: gray;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 50%;
}
input:checked + .slider:before {
-webkit-transform: translateX(18px);
-ms-transform: translateX(18px);
transform: translateX(18px);
background-color: #4250af;
}
input:checked + .slider-disabled {
background-color: gray;
}
input:checked + .slider-enabled {
background-color: #adcbfa;
}
</style>