Merge branch 'develop' of https://github.com/tidusjar/Ombi into develop
60
CHANGELOG.md
|
@ -4,14 +4,68 @@
|
|||
|
||||
### **New Features**
|
||||
|
||||
- Added the Recently Added Newsletter! You are welcome. [tidusjar]
|
||||
|
||||
- Added a new scrollbar to Ombi. [tidusjar]
|
||||
|
||||
- Added the ability to automatically generate the API Key on startup if it does not exist #2070. [tidusjar]
|
||||
|
||||
- Updated npm dependancies. [Jamie]
|
||||
|
||||
- Update README.md. [Jamie]
|
||||
|
||||
- Update README.md. [Jamie]
|
||||
|
||||
- Update ISSUE_TEMPLATE.md. [Jamie]
|
||||
|
||||
- Update appveyor.yml. [Jamie]
|
||||
|
||||
- Added recently added stuff. [Jamie]
|
||||
|
||||
- Added the recently added engine with some basic methods. [Jamie]
|
||||
|
||||
- Added the ability to refresh out backend metadata (#2078) [Jamie]
|
||||
|
||||
### **Fixes**
|
||||
|
||||
- Fixed #2074 and #2079. [Jamie]
|
||||
- Specific favicons for different platforms. [louis-lau]
|
||||
|
||||
- MovieDbId was switched to string fron number so accomodated for change. [Anojh]
|
||||
|
||||
- Removing duplicate functions. [Anojh Thayaparan]
|
||||
|
||||
- Conflict resolving and adopting Jamie's new method. [Anojh]
|
||||
|
||||
- Wrote new calls to just get poster and bg. [Anojh]
|
||||
|
||||
- Fix for issue #1907, which is to add content poster and bg to issue details page. [Anojh]
|
||||
|
||||
- Dynamic Background Animation. [Anojh]
|
||||
|
||||
- Improved the message for #2037. [tidusjar]
|
||||
|
||||
- Improved the way we use the notification variables, we have now split out the Username and Alias (Requested User is depricated but not removed) [tidusjar]
|
||||
|
||||
- Removed redundant timers. [Anojh]
|
||||
|
||||
- More optimizations by reducing requests. [Anojh]
|
||||
|
||||
- Improved version. [Anojh]
|
||||
|
||||
- Dynamic Background Animation. [Anojh]
|
||||
|
||||
- Fixed #2055 and #1903. [Jamie]
|
||||
|
||||
- Small changes to the auto updater, let's see how this works. [Jamie]
|
||||
|
||||
- Fixed build. [Jamie]
|
||||
|
||||
- Fixed the update check for the master build. [Jamie]
|
||||
|
||||
- Fixed build. [Jamie]
|
||||
|
||||
- Fixed #2074 and #2079. [Jamie]
|
||||
|
||||
|
||||
## v3.0.3030 (2018-03-14)
|
||||
|
||||
|
@ -19,6 +73,10 @@
|
|||
|
||||
- Updated the .Net core dependancies #2072. [Jamie]
|
||||
|
||||
### **Fixes**
|
||||
|
||||
- Delete Ombi.testdb. [Jamie]
|
||||
|
||||
|
||||
## v3.0.3020 (2018-03-13)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
||||
|
@ -9,7 +10,7 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
{
|
||||
|
||||
Task RemoveTvRequest(int requestId);
|
||||
Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv);
|
||||
Task<RequestEngineResult> RequestTvShow(TvRequestViewModel tv);
|
||||
Task<RequestEngineResult> DenyChildRequest(int requestId);
|
||||
Task<IEnumerable<TvRequests>> SearchTvRequest(string search);
|
||||
Task<IEnumerable<TreeNode<TvRequests, List<ChildRequests>>>> SearchTvRequestTree(string search);
|
||||
|
|
|
@ -43,13 +43,13 @@ namespace Ombi.Core.Engine
|
|||
private IAuditRepository Audit { get; }
|
||||
private readonly IRepository<RequestLog> _requestLog;
|
||||
|
||||
public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv)
|
||||
public async Task<RequestEngineResult> RequestTvShow(TvRequestViewModel tv)
|
||||
{
|
||||
var user = await GetUser();
|
||||
|
||||
var tvBuilder = new TvShowRequestBuilder(TvApi);
|
||||
(await tvBuilder
|
||||
.GetShowInfo(tv.Id))
|
||||
.GetShowInfo(tv.TvDbId))
|
||||
.CreateTvList(tv)
|
||||
.CreateChild(tv, user.Id);
|
||||
|
||||
|
@ -78,9 +78,9 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
}
|
||||
|
||||
await Audit.Record(AuditType.Added, AuditArea.TvRequest, $"Added Request {tv.Title}", Username);
|
||||
await Audit.Record(AuditType.Added, AuditArea.TvRequest, $"Added Request {tvBuilder.ChildRequest.Title}", Username);
|
||||
|
||||
var existingRequest = await TvRepository.Get().FirstOrDefaultAsync(x => x.TvDbId == tv.Id);
|
||||
var existingRequest = await TvRepository.Get().FirstOrDefaultAsync(x => x.TvDbId == tv.TvDbId);
|
||||
if (existingRequest != null)
|
||||
{
|
||||
// Remove requests we already have, we just want new ones
|
||||
|
@ -127,7 +127,7 @@ namespace Ombi.Core.Engine
|
|||
var newRequest = tvBuilder.CreateNewRequest(tv);
|
||||
return await AddRequest(newRequest.NewRequest);
|
||||
}
|
||||
|
||||
|
||||
public async Task<IEnumerable<TvRequests>> GetRequests(int count, int position)
|
||||
{
|
||||
var shouldHide = await HideFromOtherUsers();
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Threading.Tasks;
|
||||
using Ombi.Api.TvMaze;
|
||||
using Ombi.Api.TvMaze.Models;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
|
@ -23,7 +24,7 @@ namespace Ombi.Core.Helpers
|
|||
private ITvMazeApi TvApi { get; }
|
||||
|
||||
public ChildRequests ChildRequest { get; set; }
|
||||
public List<SeasonRequests> TvRequests { get; protected set; }
|
||||
public List<SeasonsViewModel> TvRequests { get; protected set; }
|
||||
public string PosterPath { get; protected set; }
|
||||
public DateTime FirstAir { get; protected set; }
|
||||
public TvRequests NewRequest { get; protected set; }
|
||||
|
@ -33,7 +34,7 @@ namespace Ombi.Core.Helpers
|
|||
{
|
||||
ShowInfo = await TvApi.ShowLookupByTheTvDbId(id);
|
||||
|
||||
DateTime.TryParse(ShowInfo.premiered, out DateTime dt);
|
||||
DateTime.TryParse(ShowInfo.premiered, out var dt);
|
||||
|
||||
FirstAir = dt;
|
||||
|
||||
|
@ -43,37 +44,29 @@ namespace Ombi.Core.Helpers
|
|||
return this;
|
||||
}
|
||||
|
||||
public TvShowRequestBuilder CreateChild(SearchTvShowViewModel model, string userId)
|
||||
public TvShowRequestBuilder CreateChild(TvRequestViewModel model, string userId)
|
||||
{
|
||||
ChildRequest = new ChildRequests
|
||||
{
|
||||
Id = model.Id,
|
||||
Id = model.TvDbId,
|
||||
RequestType = RequestType.TvShow,
|
||||
RequestedDate = DateTime.UtcNow,
|
||||
Approved = false,
|
||||
RequestedUserId = userId,
|
||||
SeasonRequests = new List<SeasonRequests>(),
|
||||
Title = model.Title,
|
||||
Title = ShowInfo.name,
|
||||
SeriesType = ShowInfo.type.Equals("Animation", StringComparison.CurrentCultureIgnoreCase) ? SeriesType.Anime : SeriesType.Standard
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TvShowRequestBuilder CreateTvList(SearchTvShowViewModel tv)
|
||||
public TvShowRequestBuilder CreateTvList(TvRequestViewModel tv)
|
||||
{
|
||||
TvRequests = new List<SeasonRequests>();
|
||||
TvRequests = new List<SeasonsViewModel>();
|
||||
// Only have the TV requests we actually requested and not everything
|
||||
foreach (var season in tv.SeasonRequests)
|
||||
foreach (var season in tv.Seasons)
|
||||
{
|
||||
for (int i = season.Episodes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!season.Episodes[i].Requested)
|
||||
{
|
||||
season.Episodes.RemoveAt(i); // Remove the episode since it's not requested
|
||||
}
|
||||
}
|
||||
|
||||
if (season.Episodes.Any())
|
||||
{
|
||||
TvRequests.Add(season);
|
||||
|
@ -81,11 +74,10 @@ namespace Ombi.Core.Helpers
|
|||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public async Task<TvShowRequestBuilder> BuildEpisodes(SearchTvShowViewModel tv)
|
||||
public async Task<TvShowRequestBuilder> BuildEpisodes(TvRequestViewModel tv)
|
||||
{
|
||||
if (tv.RequestAll)
|
||||
{
|
||||
|
@ -173,26 +165,68 @@ namespace Ombi.Core.Helpers
|
|||
else
|
||||
{
|
||||
// It's a custom request
|
||||
ChildRequest.SeasonRequests = TvRequests;
|
||||
var seasonRequests = new List<SeasonRequests>();
|
||||
var episodes = await TvApi.EpisodeLookup(ShowInfo.id);
|
||||
foreach (var ep in episodes)
|
||||
{
|
||||
var existingSeasonRequest = seasonRequests.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||
if (existingSeasonRequest != null)
|
||||
{
|
||||
var requestedSeason = tv.Seasons.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||
var requestedEpisode = requestedSeason?.Episodes?.Any(x => x.EpisodeNumber == ep.number) ?? false;
|
||||
if (requestedSeason != null && requestedEpisode)
|
||||
{
|
||||
// We already have this, let's just add the episodes to it
|
||||
existingSeasonRequest.Episodes.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = FormatDate(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url,
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var newRequest = new SeasonRequests {SeasonNumber = ep.season};
|
||||
var requestedSeason = tv.Seasons.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||
var requestedEpisode = requestedSeason?.Episodes?.Any(x => x.EpisodeNumber == ep.number) ?? false;
|
||||
if (requestedSeason != null && requestedEpisode)
|
||||
{
|
||||
newRequest.Episodes.Add(new EpisodeRequests
|
||||
{
|
||||
EpisodeNumber = ep.number,
|
||||
AirDate = FormatDate(ep.airdate),
|
||||
Title = ep.name,
|
||||
Url = ep.url,
|
||||
});
|
||||
seasonRequests.Add(newRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var s in seasonRequests)
|
||||
{
|
||||
ChildRequest.SeasonRequests.Add(s);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TvShowRequestBuilder CreateNewRequest(SearchTvShowViewModel tv)
|
||||
public TvShowRequestBuilder CreateNewRequest(TvRequestViewModel tv)
|
||||
{
|
||||
NewRequest = new TvRequests
|
||||
{
|
||||
Id = tv.Id,
|
||||
Overview = ShowInfo.summary.RemoveHtml(),
|
||||
PosterPath = PosterPath,
|
||||
Title = ShowInfo.name,
|
||||
ReleaseDate = FirstAir,
|
||||
Status = ShowInfo.status,
|
||||
ImdbId = ShowInfo.externals?.imdb ?? string.Empty,
|
||||
TvDbId = tv.Id,
|
||||
TvDbId = tv.TvDbId,
|
||||
ChildRequests = new List<ChildRequests>(),
|
||||
TotalSeasons = tv.SeasonRequests.Count()
|
||||
TotalSeasons = tv.Seasons.Count()
|
||||
};
|
||||
NewRequest.ChildRequests.Add(ChildRequest);
|
||||
|
||||
|
|
25
src/Ombi.Core/Models/Requests/TvRequestViewModel.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Core.Models.Requests
|
||||
{
|
||||
public class TvRequestViewModel
|
||||
{
|
||||
public bool RequestAll { get; set; }
|
||||
public bool LatestSeason { get; set; }
|
||||
public bool FirstSeason { get; set; }
|
||||
public int TvDbId { get; set; }
|
||||
public List<SeasonsViewModel> Seasons { get; set; } = new List<SeasonsViewModel>();
|
||||
}
|
||||
|
||||
public class SeasonsViewModel
|
||||
{
|
||||
public int SeasonNumber { get; set; }
|
||||
public List<EpisodesViewModel> Episodes { get; set; } = new List<EpisodesViewModel>();
|
||||
}
|
||||
|
||||
public class EpisodesViewModel
|
||||
{
|
||||
public int EpisodeNumber { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -336,8 +336,16 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
TableData(sb);
|
||||
|
||||
Href(sb, $"https://www.imdb.com/title/{info.ImdbId}/");
|
||||
var releaseDate = DateTime.Parse(info.ReleaseDate);
|
||||
Header(sb, 3, $"{info.Title} ({releaseDate.Year})");
|
||||
var releaseDate = string.Empty;
|
||||
try
|
||||
{
|
||||
releaseDate = $"({DateTime.Parse(info.ReleaseDate).Year})";
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Swallow, couldn't parse the date
|
||||
}
|
||||
Header(sb, 3, $"{info.Title} {releaseDate}");
|
||||
EndTag(sb, "a");
|
||||
|
||||
if (info.Genres.Any())
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Ombi.Store.Repository.Requests
|
|||
public class SeasonRequests : Entity
|
||||
{
|
||||
public int SeasonNumber { get; set; }
|
||||
public List<EpisodeRequests> Episodes { get; set; }
|
||||
public List<EpisodeRequests> Episodes { get; set; } = new List<EpisodeRequests>();
|
||||
|
||||
public int ChildRequestId { get; set; }
|
||||
[ForeignKey(nameof(ChildRequestId))]
|
||||
|
|
|
@ -30,3 +30,20 @@ export interface ISearchTvResult {
|
|||
firstSeason: boolean;
|
||||
latestSeason: boolean;
|
||||
}
|
||||
|
||||
export interface ITvRequestViewModel {
|
||||
requestAll: boolean;
|
||||
firstSeason: boolean;
|
||||
latestSeason: boolean;
|
||||
tvDbId: number;
|
||||
seasons: ISeasonsViewModel[];
|
||||
}
|
||||
|
||||
export interface ISeasonsViewModel {
|
||||
seasonNumber: number;
|
||||
episodes: IEpisodesViewModel[];
|
||||
}
|
||||
|
||||
export interface IEpisodesViewModel {
|
||||
episodeNumber: number;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<div *ngIf="issue">
|
||||
<div class="myBg backdrop" [style.background-image]="backgroundPath"></div>
|
||||
<div class="tint" style="background-image: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.6) 100%);"></div>
|
||||
<h1>{{issue.title}} </h1>
|
||||
<div class="col-md-6">
|
||||
<span class="label label-info">{{IssueStatus[issue.status]}}</span>
|
||||
<span class="label label-success">{{issue.issueCategory.value}}</span>
|
||||
|
||||
<h3 *ngIf="issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.alias}}</h3>
|
||||
<h3 *ngIf="!issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.userName}}</h3>
|
||||
<img class="img-responsive poster" src="{{posterPath}}" alt="poster">
|
||||
<span class="label label-info">{{IssueStatus[issue.status]}}</span>
|
||||
<span class="label label-success">{{issue.issueCategory.value}}</span>
|
||||
|
||||
<h3 *ngIf="issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.alias}}</h3>
|
||||
<h3 *ngIf="!issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.userName}}</h3>
|
||||
<h3 *ngIf="issue.subject">{{'Issues.Subject' | translate}}: {{issue.subject}}</h3>
|
||||
<br>
|
||||
<br>
|
||||
<div class="form-group">
|
||||
<label for="description" class="control-label" [translate]="'Issues.Description'"></label>
|
||||
<div>
|
||||
|
@ -26,7 +29,8 @@
|
|||
<div class="panel-heading top-bar">
|
||||
<div class="col-md-8 col-xs-8">
|
||||
<h3 class="panel-title">
|
||||
<span class="glyphicon glyphicon-comment"></span> {{'Issues.Comments' | translate}}</h3>
|
||||
<span class="glyphicon glyphicon-comment"></span> {{'Issues.Comments' | translate}}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -51,8 +55,7 @@
|
|||
</div>
|
||||
<div class="panel-footer">
|
||||
<div class="input-group">
|
||||
<input id="btn-input" type="text" class="form-control input-sm chat_input" [(ngModel)]="newComment.comment" [attr.placeholder]="'Issues.WriteMessagePlaceholder' | translate"
|
||||
/>
|
||||
<input id="btn-input" type="text" class="form-control input-sm chat_input" [(ngModel)]="newComment.comment" [attr.placeholder]="'Issues.WriteMessagePlaceholder' | translate" />
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-primary btn-sm" id="btn-chat" (click)="addComment()" [translate]="'Issues.SendMessageButton'"></button>
|
||||
</span>
|
||||
|
|
|
@ -64,6 +64,15 @@ body{
|
|||
overflow: hidden;
|
||||
display: flex;
|
||||
}
|
||||
.myBg {
|
||||
z-index: -1;
|
||||
}
|
||||
.tint {
|
||||
z-index: -1;
|
||||
}
|
||||
img-responsive poster {
|
||||
display:block;
|
||||
}
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
|
|
@ -2,8 +2,9 @@ import { Component, OnInit } from "@angular/core";
|
|||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
import { AuthService } from "../auth/auth.service";
|
||||
import { IssuesService, NotificationService, SettingsService } from "../services";
|
||||
import { ImageService, IssuesService, NotificationService, SettingsService } from "../services";
|
||||
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { IIssues, IIssuesChat, IIssueSettings, INewIssueComments, IssueStatus } from "../interfaces";
|
||||
|
||||
@Component({
|
||||
|
@ -22,6 +23,8 @@ export class IssueDetailsComponent implements OnInit {
|
|||
public IssueStatus = IssueStatus;
|
||||
public isAdmin: boolean;
|
||||
public settings: IIssueSettings;
|
||||
public backgroundPath: any;
|
||||
public posterPath: any;
|
||||
|
||||
private issueId: number;
|
||||
|
||||
|
@ -29,7 +32,9 @@ export class IssueDetailsComponent implements OnInit {
|
|||
private route: ActivatedRoute,
|
||||
private authService: AuthService,
|
||||
private settingsService: SettingsService,
|
||||
private notificationService: NotificationService) {
|
||||
private notificationService: NotificationService,
|
||||
private imageService: ImageService,
|
||||
private sanitizer: DomSanitizer) {
|
||||
this.route.params
|
||||
.subscribe((params: any) => {
|
||||
this.issueId = parseInt(params.id);
|
||||
|
@ -56,8 +61,8 @@ export class IssueDetailsComponent implements OnInit {
|
|||
providerId: x.providerId,
|
||||
userReported: x.userReported,
|
||||
};
|
||||
this.setBackground(x);
|
||||
});
|
||||
|
||||
this.loadComments();
|
||||
}
|
||||
|
||||
|
@ -85,4 +90,26 @@ export class IssueDetailsComponent implements OnInit {
|
|||
private loadComments() {
|
||||
this.issueService.getComments(this.issueId).subscribe(x => this.comments = x);
|
||||
}
|
||||
|
||||
private setBackground(issue: any) {
|
||||
if (issue.requestType === 1) {
|
||||
this.imageService.getMovieBackground(issue.providerId).subscribe(x => {
|
||||
this.backgroundPath = this.sanitizer.bypassSecurityTrustStyle
|
||||
("url(" + x + ")");
|
||||
});
|
||||
this.imageService.getMoviePoster(issue.providerId).subscribe(x => {
|
||||
this.posterPath = x.toString();
|
||||
});
|
||||
|
||||
} else {
|
||||
this.imageService.getTvBackground(Number(issue.providerId)).subscribe(x => {
|
||||
this.backgroundPath = this.sanitizer.bypassSecurityTrustStyle
|
||||
("url(" + x + ")");
|
||||
});
|
||||
this.imageService.getTvPoster(Number(issue.providerId)).subscribe(x => {
|
||||
this.posterPath = x.toString();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
|||
import { OrderModule } from "ngx-order-pipe";
|
||||
import { PaginatorModule, SharedModule, TabViewModule } from "primeng/primeng";
|
||||
|
||||
import { IdentityService } from "../services";
|
||||
import { IdentityService, SearchService } from "../services";
|
||||
|
||||
import { AuthGuard } from "../auth/auth.guard";
|
||||
|
||||
|
@ -43,6 +43,7 @@ const routes: Routes = [
|
|||
],
|
||||
providers: [
|
||||
IdentityService,
|
||||
SearchService,
|
||||
],
|
||||
|
||||
})
|
||||
|
|
|
@ -207,7 +207,7 @@
|
|||
|
||||
|
||||
<issue-report [movie]="true" [visible]="issuesBarVisible" (visibleChange)="issuesBarVisible = $event;" [title]="issueRequest?.title"
|
||||
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" [providerId]=""></issue-report>
|
||||
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" [providerId]="issueProviderId"></issue-report>
|
||||
|
||||
|
||||
<p-sidebar [(visible)]="filterDisplay" styleClass="ui-sidebar-md side-back side-small">
|
||||
|
|
|
@ -105,4 +105,4 @@
|
|||
|
||||
|
||||
<issue-report [movie]="false" [visible]="issuesBarVisible" [title]="issueRequest?.title"
|
||||
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" (visibleChange)="issuesBarVisible = $event;"></issue-report>
|
||||
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" [providerId]="issueProviderId" (visibleChange)="issuesBarVisible = $event;"></issue-report>
|
|
@ -105,6 +105,7 @@ export class TvRequestChildrenComponent {
|
|||
this.issueRequest = req;
|
||||
this.issueCategorySelected = catId;
|
||||
this.issuesBarVisible = true;
|
||||
this.issueProviderId = req.id.toString();
|
||||
}
|
||||
|
||||
private removeRequestFromUi(key: IChildRequests) {
|
||||
|
|
|
@ -90,12 +90,6 @@ export class TvRequestsComponent implements OnInit {
|
|||
}
|
||||
|
||||
public ngOnInit() {
|
||||
|
||||
const profile = <ISonarrProfile>{name:"test",id:1 };
|
||||
const folder = <ISonarrRootFolder>{path:"testpath", id:1};
|
||||
|
||||
this.sonarrProfiles.push(profile);
|
||||
this.sonarrRootFolders.push(folder);
|
||||
this.amountToLoad = 1000;
|
||||
this.currentlyLoaded = 1000;
|
||||
this.tvRequests = [];
|
||||
|
@ -204,7 +198,7 @@ export class TvRequestsComponent implements OnInit {
|
|||
this.loadInit();
|
||||
}
|
||||
private loadBackdrop(val: TreeNode): void {
|
||||
this.imageService.getTvBanner(val.data.id).subscribe(x => {
|
||||
this.imageService.getTvBanner(val.data.tvDbId).subscribe(x => {
|
||||
val.data.background = this.sanitizer.bypassSecurityTrustStyle
|
||||
("url(" + x + ")");
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ import { NotificationService } from "../services";
|
|||
import { RequestService } from "../services";
|
||||
import { SearchService } from "../services";
|
||||
|
||||
import { INewSeasonRequests, IRequestEngineResult } from "../interfaces";
|
||||
import { INewSeasonRequests, IRequestEngineResult, ISeasonsViewModel, ITvRequestViewModel } from "../interfaces";
|
||||
import { IEpisodesRequests } from "../interfaces";
|
||||
import { ISearchTvResult } from "../interfaces";
|
||||
|
||||
|
@ -46,7 +46,22 @@ export class SeriesInformationComponent implements OnInit {
|
|||
|
||||
this.series.requested = true;
|
||||
|
||||
this.requestService.requestTv(this.series)
|
||||
const viewModel = <ITvRequestViewModel>{ firstSeason: this.series.firstSeason, latestSeason: this.series.latestSeason, requestAll: this.series.requestAll, tvDbId: this.series.id};
|
||||
viewModel.seasons = [];
|
||||
this.series.seasonRequests.forEach((season) => {
|
||||
const seasonsViewModel = <ISeasonsViewModel>{seasonNumber: season.seasonNumber, episodes: []};
|
||||
season.episodes.forEach(ep => {
|
||||
if(!this.series.latestSeason || !this.series.requestAll || !this.series.firstSeason) {
|
||||
if(ep.requested) {
|
||||
seasonsViewModel.episodes.push({episodeNumber: ep.episodeNumber});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewModel.seasons.push(seasonsViewModel);
|
||||
});
|
||||
|
||||
this.requestService.requestTv(viewModel)
|
||||
.subscribe(x => {
|
||||
this.result = x as IRequestEngineResult;
|
||||
if (this.result.result) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import { ImageService, NotificationService, RequestService, SearchService} from
|
|||
|
||||
import { TreeNode } from "primeng/primeng";
|
||||
import { IRequestEngineResult } from "../interfaces";
|
||||
import { IIssueCategory, ISearchTvResult } from "../interfaces";
|
||||
import { IIssueCategory, ISearchTvResult, ISeasonsViewModel, ITvRequestViewModel } from "../interfaces";
|
||||
|
||||
@Component({
|
||||
selector: "tv-search",
|
||||
|
@ -154,7 +154,23 @@ export class TvSearchComponent implements OnInit {
|
|||
if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) {
|
||||
searchResult.approved = true;
|
||||
}
|
||||
this.requestService.requestTv(searchResult)
|
||||
|
||||
const viewModel = <ITvRequestViewModel>{ firstSeason: searchResult.firstSeason, latestSeason: searchResult.latestSeason, requestAll: searchResult.requestAll, tvDbId: searchResult.id};
|
||||
viewModel.seasons = [];
|
||||
searchResult.seasonRequests.forEach((season) => {
|
||||
const seasonsViewModel = <ISeasonsViewModel>{seasonNumber: season.seasonNumber, episodes: []};
|
||||
season.episodes.forEach(ep => {
|
||||
if(!searchResult.latestSeason || !searchResult.requestAll || !searchResult.firstSeason) {
|
||||
if(ep.requested) {
|
||||
seasonsViewModel.episodes.push({episodeNumber: ep.episodeNumber});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewModel.seasons.push(seasonsViewModel);
|
||||
});
|
||||
|
||||
this.requestService.requestTv(viewModel)
|
||||
.subscribe(x => {
|
||||
this.result = x;
|
||||
if (this.result.result) {
|
||||
|
|
|
@ -19,11 +19,22 @@ export class ImageService extends ServiceHelpers {
|
|||
|
||||
public getTvBanner(tvdbid: number): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}tv/${tvdbid}`, {headers: this.headers});
|
||||
}
|
||||
public getMoviePoster(themoviedbid: string): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}poster/movie/${themoviedbid}`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public getMoviePoster(movieDbId: string): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}poster/movie/${movieDbId}`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public getTvPoster(tvdbid: number): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}poster/tv/${tvdbid}`, {headers: this.headers});
|
||||
return this.http.get<string>(`${this.url}poster/tv/${tvdbid}`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public getMovieBackground(movieDbId: string): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}background/movie/${movieDbId}`, { headers: this.headers });
|
||||
}
|
||||
|
||||
public getTvBackground(tvdbid: number): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}background/tv/${tvdbid}`, { headers: this.headers });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Observable } from "rxjs/Rx";
|
|||
import { TreeNode } from "primeng/primeng";
|
||||
import { IRequestEngineResult } from "../interfaces";
|
||||
import { IChildRequests, IFilter, IMovieRequestModel, IMovieRequests, IMovieUpdateModel, ITvRequests, ITvUpdateModel } from "../interfaces";
|
||||
import { ISearchTvResult } from "../interfaces";
|
||||
import { ITvRequestViewModel } from "../interfaces";
|
||||
import { ServiceHelpers } from "./service.helpers";
|
||||
|
||||
@Injectable()
|
||||
|
@ -20,7 +20,7 @@ export class RequestService extends ServiceHelpers {
|
|||
return this.http.post<IRequestEngineResult>(`${this.url}Movie/`, JSON.stringify(movie), {headers: this.headers});
|
||||
}
|
||||
|
||||
public requestTv(tv: ISearchTvResult): Observable<IRequestEngineResult> {
|
||||
public requestTv(tv: ITvRequestViewModel): Observable<IRequestEngineResult> {
|
||||
return this.http.post<IRequestEngineResult>(`${this.url}TV/`, JSON.stringify(tv), {headers: this.headers});
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<!-- <div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="enable" [(ngModel)]="settings.recentlyAddedPage" [checked]="settings.recentlyAddedPage">
|
||||
<label for="enable">Enable Recently Added Page</label>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="form-group">
|
||||
<label for="logo" class="control-label">Custom Logo</label>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<settings-menu></settings-menu>
|
||||
|
||||
<wiki [url]="'https://github.com/tidusjar/Ombi/wiki/Newsletter'"></wiki>
|
||||
<wiki [url]="'https://github.com/tidusjar/Ombi/wiki/Newsletter-Settings'"></wiki>
|
||||
<div *ngIf="settings">
|
||||
<fieldset>
|
||||
<legend>Newsletter</legend>
|
||||
|
|
|
@ -15,6 +15,8 @@ export class IssuesReportComponent {
|
|||
@Input() public issueCategory: IIssueCategory;
|
||||
@Input() public movie: boolean;
|
||||
@Input() public providerId: string;
|
||||
@Input() public background: string;
|
||||
@Input() public posterPath: string;
|
||||
|
||||
@Output() public visibleChange = new EventEmitter<boolean>();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Api.FanartTv;
|
||||
using Ombi.Store.Repository;
|
||||
using System;
|
||||
|
@ -31,7 +31,7 @@ namespace Ombi.Controllers
|
|||
private IApplicationConfigRepository Config { get; }
|
||||
private LandingPageBackground Options { get; }
|
||||
private readonly ICacheService _cache;
|
||||
|
||||
|
||||
[HttpGet("tv/{tvdbid}")]
|
||||
public async Task<string> GetTvBanner(int tvdbid)
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ namespace Ombi.Controllers
|
|||
|
||||
if (images.movieposter?.Any() ?? false)
|
||||
{
|
||||
var enImage = images.movieposter.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
var enImage = images.movieposter.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
if (enImage == null)
|
||||
{
|
||||
return images.movieposter.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
|
@ -117,6 +117,56 @@ namespace Ombi.Controllers
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
[HttpGet("background/movie/{movieDbId}")]
|
||||
public async Task<string> GetMovieBackground(string movieDbId)
|
||||
{
|
||||
var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.Get(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1));
|
||||
|
||||
var images = await FanartTvApi.GetMovieImages(movieDbId, key.Value);
|
||||
|
||||
if (images == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (images.moviebackground?.Any() ?? false)
|
||||
{
|
||||
var enImage = images.moviebackground.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
if (enImage == null)
|
||||
{
|
||||
return images.moviebackground.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
}
|
||||
return enImage;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
[HttpGet("background/tv/{tvdbid}")]
|
||||
public async Task<string> GetTvBackground(int tvdbid)
|
||||
{
|
||||
var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.Get(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1));
|
||||
|
||||
var images = await FanartTvApi.GetTvImages(tvdbid, key.Value);
|
||||
|
||||
if (images == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (images.showbackground?.Any() ?? false)
|
||||
{
|
||||
var enImage = images.showbackground.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
if (enImage == null)
|
||||
{
|
||||
return images.showbackground.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
}
|
||||
return enImage;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
[HttpGet("background")]
|
||||
public async Task<object> GetBackgroundImage()
|
||||
{
|
||||
|
@ -133,7 +183,7 @@ namespace Ombi.Controllers
|
|||
{
|
||||
var item = rand.Next(moviesArray.Length);
|
||||
var result = await FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value);
|
||||
|
||||
|
||||
while (!result.moviebackground.Any())
|
||||
{
|
||||
result = await FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value);
|
||||
|
@ -141,7 +191,7 @@ namespace Ombi.Controllers
|
|||
|
||||
movieUrl = result.moviebackground[0].url;
|
||||
}
|
||||
if(tvArray.Any())
|
||||
if (tvArray.Any())
|
||||
{
|
||||
var item = rand.Next(tvArray.Length);
|
||||
var result = await FanartTvApi.GetTvImages(tvArray[item], key.Value);
|
||||
|
@ -157,8 +207,8 @@ namespace Ombi.Controllers
|
|||
if (!string.IsNullOrEmpty(movieUrl) && !string.IsNullOrEmpty(tvUrl))
|
||||
{
|
||||
var result = rand.Next(2);
|
||||
if (result == 0) return new { url = movieUrl };
|
||||
if (result == 1) return new { url = tvUrl };
|
||||
if (result == 0) return new { url = movieUrl };
|
||||
if (result == 1) return new { url = tvUrl };
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(movieUrl))
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace Ombi.Controllers
|
|||
/// <param name="tv">The tv.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("tv")]
|
||||
public async Task<RequestEngineResult> RequestTv([FromBody] SearchTvShowViewModel tv)
|
||||
public async Task<RequestEngineResult> RequestTv([FromBody] TvRequestViewModel tv)
|
||||
{
|
||||
return await TvRequestEngine.RequestTvShow(tv);
|
||||
}
|
||||
|
|
|
@ -64,26 +64,16 @@ O:::::::OOO:::::::Om::::m m::::m m::::mb:::::bbbbbb::::::bi::::::i
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>@appName</title>
|
||||
<base href="/@baseUrl"/>
|
||||
<link rel="SHORTCUT ICON" href="~/images/favicon/favicon.ico"/>
|
||||
<link rel="icon" href="~/images/favicon/favicon.ico" type="image/ico"/>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="~/images/favicon/apple-icon-57x57.png"/>
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="~/images/favicon/apple-icon-60x60.png"/>
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="~/images/favicon/apple-icon-72x72.png"/>
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="~/images/favicon/apple-icon-76x76.png"/>
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="~/images/favicon/apple-icon-114x114.png"/>
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="~/images/favicon/apple-icon-120x120.png"/>
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="~/images/favicon/apple-icon-144x144.png"/>
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="~/images/favicon/apple-icon-152x152.png"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="~/images/favicon/apple-icon-180x180.png"/>
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="~/images/favicon/android-icon-192x192.png"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="~/images/favicon/favicon-32x32.png"/>
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="~/images/favicon/favicon-96x96.png"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="~/images/favicon/favicon-16x16.png"/>
|
||||
<link rel="manifest" href="~/images/favicon/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="msapplication-TileImage" content="~/images/favicon/ms-icon-144x144.png"/>
|
||||
<meta name="theme-color" content="#ffffff"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="~/images/favicon/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="~/images/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="~/images/favicon/favicon-16x16.png">
|
||||
<link rel="manifest" href="~/images/favicon/site.webmanifest">
|
||||
<link rel="mask-icon" href="~/images/favicon/safari-pinned-tab.svg" color="#df691a">
|
||||
<link rel="shortcut icon" href="~/images/favicon/favicon.ico">
|
||||
<meta name="msapplication-TileColor" content="#df691a">
|
||||
<meta name="msapplication-config" content="~/images/favicon/browserconfig.xml">
|
||||
<meta name="theme-color" content="#df691a">
|
||||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
|
||||
|
|
BIN
src/Ombi/wwwroot/images/favicon/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
src/Ombi/wwwroot/images/favicon/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
BIN
src/Ombi/wwwroot/images/favicon/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
|
@ -1,2 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/images/favicon/mstile-150x150.png"/>
|
||||
<TileColor>#df691a</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 738 B |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"name": "App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 4.9 KiB |
BIN
src/Ombi/wwwroot/images/favicon/mstile-150x150.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
1
src/Ombi/wwwroot/images/favicon/safari-pinned-tab.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg version="1" xmlns="http://www.w3.org/2000/svg" width="1365.333" height="1365.333" viewBox="0 0 1024.000000 1024.000000"><path d="M487.2 71c-140.4 9.8-263.6 80.9-341 196.7-39.5 59-63.1 124.3-71.8 198.8-2.5 21.1-2.5 71.9 0 93 6.5 56 19.9 101.7 43.7 150 21.9 44.5 48.5 81.2 85.3 118 47.8 47.7 105.8 83.8 168.9 105 160.4 53.9 335.7 13.4 454.3-105 36.8-36.8 63.4-73.5 85.3-118 23.8-48.3 37.2-94 43.7-150 2.5-21.1 2.5-71.9 0-93-5.2-44.4-15.1-83.6-30.9-122.2-32.3-78.8-88.7-148.4-159.2-196.6-61.7-42.1-130.7-67.4-205.5-75.2-17.9-1.9-56.3-2.7-72.8-1.5zM391 283c11.3 3.2 21.2 8.6 31.4 17.1 5 4.2 28.7 27.4 52.6 51.5 46.2 46.6 48 48.8 54.4 64.8 4.3 10.7 5.9 19.7 5.8 33.1 0 13.9-1.9 22.6-7.8 35.4l-3.7 8.2 3.8 3.9 3.8 3.9 4.6-2.3c19-9.6 43.2-12.1 63.1-6.6 9.7 2.7 22.1 8.7 29.6 14.4 3.2 2.4 27.1 25.7 52.9 51.8 41.7 42 47.5 48.2 51.4 55.1 8.8 15.7 12.8 32.1 11.7 48.7-.7 10.7-3.4 23-6.7 30.5-6.2 14.2-20 30.1-34.1 39.2-25.2 16.3-57.3 17.7-85.8 3.7l-11.5-5.7-50.1-50.1c-54.7-54.7-56.7-57.1-62.5-73.9-4-11.5-5.2-21.2-4.6-34.7.7-13.3 2.3-20.2 7.7-31.7l3.8-8.1-3.7-3.6-3.7-3.7-7.9 3.6c-27.5 12.6-61.6 10-86.2-6.5-6.6-4.5-98.4-96-103.9-103.7-10.6-14.6-15.7-31.5-15.7-51.3 0-14.6 1.6-22.4 7.3-34.6 12.5-27.1 34.7-44.6 63.5-50.3 8.4-1.7 31.9-.6 40.5 1.9zm179 66c1.9 1.9 2 3.3 2 35.2 0 32.7 0 33.2-2.2 35.5-3.1 3.3-7.7 3.1-11.1-.5l-2.7-2.8V384c0-31.9 0-32.4 2.2-34.7 2.8-3 8.9-3.2 11.8-.3zm74.1 30.9c5.6 5.6 5.3 6.1-20.3 31.8-25.6 25.6-26.9 26.5-31.9 21.7-2.1-2-2.9-3.7-2.9-6.3 0-3.4 1.5-5.1 22.3-25.7 12.2-12.2 23.1-22.7 24.2-23.3 3.3-1.7 5.5-1.3 8.6 1.8zm29.9 73.6c2.1 1.1 3.1 2.5 3.6 5.2.6 3.3.3 4-2.5 6.5L672 468h-64.4l-2.8-2.7c-3.6-3.4-3.7-7.5-.3-10.8l2.4-2.5H639c26.6 0 32.6.3 35 1.5z"/><path d="M358.4 324.5c-28.1 6.1-42.3 34.4-30.7 61 2.4 5.4 7.3 10.6 48.1 51.7 48.4 48.6 50 50 62.7 53.3 7.1 1.8 14.4 1.9 18 .3 2.5-1.1 2.3-1.4-20.8-24.7-21.3-21.5-23.5-24-24.6-28.3-3.3-13.7 6.7-26.8 20.6-26.8 2.9 0 7 .7 9.1 1.6 2.4.9 11.8 9.5 26.3 24l22.6 22.5 1.3-3.1c2.8-6.6-.7-22.3-6.9-31.6-2.3-3.4-22.5-24.3-47.8-49.4-47-46.8-48.3-47.8-61-50.5-8.1-1.7-9-1.7-16.9 0zM567.8 533.7c-1 .2-1.8.7-1.8 1.1 0 .3 13.2 13.9 29.4 30.2 28.2 28.2 29.5 29.7 31 35.1 2 6.8 1.1 12.1-3 18-2.9 4.2-8.8 8.2-13.8 9.3-1.5.4-5.4.2-8.5-.5l-5.6-1.1-30-29.9c-16.6-16.4-30.3-29.9-30.7-29.9-.3 0-1.1 1.9-1.7 4.3-1.9 7.6 1.2 20.8 6.9 29.7 4.2 6.4 90.5 92.1 96 95.2 16.7 9.5 36.8 7 51.4-6.3 13.7-12.5 17.2-33 8.5-50.8-2.8-6-7.6-11.1-48.8-52.2-48.8-48.7-49.3-49.1-61.9-51.8-5.2-1.1-14-1.3-17.4-.4z"/></svg>
|
After Width: | Height: | Size: 2.4 KiB |
19
src/Ombi/wwwroot/images/favicon/site.webmanifest
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "Ombi",
|
||||
"short_name": "Ombi",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/images/favicon/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/favicon/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#df691a",
|
||||
"background_color": "#df691a",
|
||||
"display": "standalone"
|
||||
}
|