diff --git a/.github/workflows/release-workflow.yml b/.github/workflows/release-workflow.yml
deleted file mode 100644
index 36532db40..000000000
--- a/.github/workflows/release-workflow.yml
+++ /dev/null
@@ -1,175 +0,0 @@
-name: Stable Workflow
-
-on:
- push:
- branches: ['release/**']
- pull_request:
- branches: [ 'develop' ]
- types: [ closed ]
- workflow_dispatch:
-
-jobs:
- debug:
- runs-on: ubuntu-latest
- steps:
- - name: Debug Info
- run: |
- echo "Event Name: ${{ github.event_name }}"
- echo "Ref: ${{ github.ref }}"
- echo "Not Contains Release: ${{ !contains(github.head_ref, 'release') }}"
- echo "Matches Develop: ${{ github.ref == 'refs/heads/develop' }}"
- if_merged:
- if: github.event.pull_request.merged == true && contains(github.head_ref, 'release')
- runs-on: ubuntu-latest
- steps:
- - run: |
- echo The PR was merged
- build:
- name: Upload Kavita.Common for Version Bump
- runs-on: ubuntu-latest
- if: github.event.pull_request.merged == true && contains(github.head_ref, 'release')
- steps:
- - name: Checkout Repo
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- - uses: actions/upload-artifact@v4
- with:
- name: csproj
- path: Kavita.Common/Kavita.Common.csproj
-
- stable:
- name: Build Stable and Nightly Docker if Release
- needs: [ build ]
- if: github.event.pull_request.merged == true && contains(github.head_ref, 'release')
- runs-on: ubuntu-latest
- permissions:
- packages: write
- contents: read
- steps:
- - name: Find Current Pull Request
- uses: jwalton/gh-find-current-pr@v1
- id: findPr
- with:
- state: all
- github-token: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Parse PR body
- id: parse-body
- run: |
- body="Read full changelog: https://github.com/Kareadita/Kavita/releases/latest"
-
- echo $body
- echo "BODY=$body" >> $GITHUB_OUTPUT
-
- - name: Check Out Repo
- uses: actions/checkout@v4
- with:
- ref: develop
-
- - name: NodeJS to Compile WebUI
- uses: actions/setup-node@v4
- with:
- node-version: 20
- - run: |
-
- cd UI/Web || exit
- echo 'Installing web dependencies'
- npm ci
-
- echo 'Building UI'
- npm run prod
-
- echo 'Copying back to Kavita wwwroot'
- rsync -a dist/ ../../API/wwwroot/
-
- cd ../ || exit
-
- - name: Get csproj Version
- uses: kzrnm/get-net-sdk-project-versions-action@v2
- id: get-version
- with:
- proj-path: Kavita.Common/Kavita.Common.csproj
-
- - name: Echo csproj version
- run: echo "${{steps.get-version.outputs.assembly-version}}"
-
- - name: Parse Version
- run: |
- version='${{steps.get-version.outputs.assembly-version}}'
- newVersion=${version%.*}
- echo $newVersion
- echo "VERSION=$newVersion" >> $GITHUB_OUTPUT
- id: parse-version
-
- - name: Compile dotnet app
- uses: actions/setup-dotnet@v4
- with:
- dotnet-version: 8.0.x
- - name: Install Swashbuckle CLI
- run: dotnet tool install -g --version 6.5.0 Swashbuckle.AspNetCore.Cli
-
- - run: ./monorepo-build.sh
-
- - name: Login to Docker Hub
- uses: docker/login-action@v3
- with:
- username: ${{ secrets.DOCKER_HUB_USERNAME }}
- password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
-
- - name: Login to GitHub Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- - name: Set up Docker Buildx
- id: buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Build and push stable
- id: docker_build_stable
- uses: docker/build-push-action@v5
- with:
- context: .
- platforms: linux/amd64,linux/arm/v7,linux/arm64
- push: true
- tags: jvmilazz0/kavita:latest, jvmilazz0/kavita:${{ steps.parse-version.outputs.VERSION }}, ghcr.io/kareadita/kavita:latest, ghcr.io/kareadita/kavita:${{ steps.parse-version.outputs.VERSION }}
-
- - name: Build and push nightly
- id: docker_build_nightly
- uses: docker/build-push-action@v5
- with:
- context: .
- platforms: linux/amd64,linux/arm/v7,linux/arm64
- push: true
- tags: jvmilazz0/kavita:nightly, jvmilazz0/kavita:nightly-${{ steps.parse-version.outputs.VERSION }}, ghcr.io/kareadita/kavita:nightly, ghcr.io/kareadita/kavita:nightly-${{ steps.parse-version.outputs.VERSION }}
-
- - name: Image digest
- run: echo ${{ steps.docker_build_stable.outputs.digest }}
-
- - name: Image digest
- run: echo ${{ steps.docker_build_nightly.outputs.digest }}
-
- - name: Notify Discord
- uses: rjstone/discord-webhook-notify@v1
- with:
- severity: info
- description: v${{steps.get-version.outputs.assembly-version}} - ${{ steps.findPr.outputs.title }}
- details: '${{ steps.findPr.outputs.body }}'
- text: <@&939225192553644133> A new stable build has been released.
- webhookUrl: ${{ secrets.DISCORD_DOCKER_UPDATE_URL }}
-
- - name: Notify Discord
- uses: rjstone/discord-webhook-notify@v1
- with:
- severity: info
- description: v${{steps.get-version.outputs.assembly-version}} - ${{ steps.findPr.outputs.title }}
- details: '${{ steps.findPr.outputs.body }}'
- text: <@&939225459156217917> <@&939225350775406643> A new nightly build has been released for docker.
- webhookUrl: ${{ secrets.DISCORD_DOCKER_UPDATE_URL }}
diff --git a/API/DTOs/Filtering/SortField.cs b/API/DTOs/Filtering/SortField.cs
index b072819f4..7082ded69 100644
--- a/API/DTOs/Filtering/SortField.cs
+++ b/API/DTOs/Filtering/SortField.cs
@@ -33,5 +33,9 @@ public enum SortField
///
/// Kavita+ Only - External Average Rating
///
- AverageRating = 8
+ AverageRating = 8,
+ ///
+ /// Randomise the order
+ ///
+ Random = 9
}
diff --git a/API/Extensions/QueryExtensions/Filtering/BookmarkSort.cs b/API/Extensions/QueryExtensions/Filtering/BookmarkSort.cs
index f3dbfef14..030517dbf 100644
--- a/API/Extensions/QueryExtensions/Filtering/BookmarkSort.cs
+++ b/API/Extensions/QueryExtensions/Filtering/BookmarkSort.cs
@@ -1,6 +1,7 @@
using System.Linq;
using API.DTOs.Filtering;
using API.Entities;
+using Microsoft.EntityFrameworkCore;
namespace API.Extensions.QueryExtensions.Filtering;
#nullable enable
@@ -39,6 +40,7 @@ public static class BookmarkSort
SortField.ReadProgress => query.DoOrderBy(s => s.Series.Progress.Where(p => p.SeriesId == s.Series.Id).Select(p => p.LastModified).Max(), sortOptions),
SortField.AverageRating => query.DoOrderBy(s => s.Series.ExternalSeriesMetadata.ExternalRatings
.Where(p => p.SeriesId == s.Series.Id).Average(p => p.AverageScore), sortOptions),
+ SortField.Random => query.DoOrderBy(s => EF.Functions.Random(), sortOptions),
_ => query
};
diff --git a/API/Extensions/QueryExtensions/Filtering/SeriesSort.cs b/API/Extensions/QueryExtensions/Filtering/SeriesSort.cs
index efc4bc670..d6c7ff77d 100644
--- a/API/Extensions/QueryExtensions/Filtering/SeriesSort.cs
+++ b/API/Extensions/QueryExtensions/Filtering/SeriesSort.cs
@@ -1,6 +1,7 @@
using System.Linq;
using API.DTOs.Filtering;
using API.Entities;
+using Microsoft.EntityFrameworkCore;
namespace API.Extensions.QueryExtensions.Filtering;
#nullable enable
@@ -35,6 +36,7 @@ public static class SeriesSort
.Max(), sortOptions),
SortField.AverageRating => query.DoOrderBy(s => s.ExternalSeriesMetadata.ExternalRatings
.Where(p => p.SeriesId == s.Id).Average(p => p.AverageScore), sortOptions),
+ SortField.Random => query.DoOrderBy(s => EF.Functions.Random(), sortOptions),
_ => query
};
diff --git a/UI/Web/src/app/_models/metadata/series-filter.ts b/UI/Web/src/app/_models/metadata/series-filter.ts
index 663fc2380..bfaee4f3f 100644
--- a/UI/Web/src/app/_models/metadata/series-filter.ts
+++ b/UI/Web/src/app/_models/metadata/series-filter.ts
@@ -24,7 +24,8 @@ export enum SortField {
/**
* Kavita+ only
*/
- AverageRating = 8
+ AverageRating = 8,
+ Random = 9
}
export const allSortFields = Object.keys(SortField)
diff --git a/UI/Web/src/app/_pipes/sort-field.pipe.ts b/UI/Web/src/app/_pipes/sort-field.pipe.ts
index ea54d124d..8044631b3 100644
--- a/UI/Web/src/app/_pipes/sort-field.pipe.ts
+++ b/UI/Web/src/app/_pipes/sort-field.pipe.ts
@@ -29,6 +29,8 @@ export class SortFieldPipe implements PipeTransform {
return this.translocoService.translate('sort-field-pipe.read-progress');
case SortField.AverageRating:
return this.translocoService.translate('sort-field-pipe.average-rating');
+ case SortField.Random:
+ return this.translocoService.translate('sort-field-pipe.random');
}
}
diff --git a/UI/Web/src/app/app.component.scss b/UI/Web/src/app/app.component.scss
index f36dbb0c3..ece19f0eb 100644
--- a/UI/Web/src/app/app.component.scss
+++ b/UI/Web/src/app/app.component.scss
@@ -21,7 +21,7 @@
.content-wrapper {
padding: 0 5px 0;
overflow: hidden;
- height: calc(100vh - 56px);
+ height: calc(var(--vh)*100 - 56px);
&.closed {
overflow: auto;
diff --git a/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.scss b/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.scss
index b1705ff03..92b389322 100644
--- a/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.scss
+++ b/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.scss
@@ -99,7 +99,7 @@ form {
.dropdown {
width: 100vw;
- height: calc(100vh - 56px); //header offset
+ height: calc(var(--vh)*100 - 56px); //header offset
background: var(--dropdown-overlay-color);
position: fixed;
justify-content: center;
diff --git a/UI/Web/src/assets/langs/en.json b/UI/Web/src/assets/langs/en.json
index b160f10f8..32e57bd14 100644
--- a/UI/Web/src/assets/langs/en.json
+++ b/UI/Web/src/assets/langs/en.json
@@ -1745,7 +1745,8 @@
"time-to-read": "Time to Read",
"release-year": "Release Year",
"read-progress": "Last Read",
- "average-rating": "Average Rating"
+ "average-rating": "Average Rating",
+ "random": "Random"
},
"edit-series-modal": {