summaryrefslogtreecommitdiff
path: root/Pages/Gallery.razor
blob: c037979e6b220c065e4c08876dc344cf304d81e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@page "/"
@page "/Gallery"
@inject ITagService tagService
@inject IFeedService feedService
@inject IUserService userService
@inject IJSRuntime jsRuntime
@implements IDisposable
@attribute [Authorize]

<PageTitle>@Title</PageTitle>

@if(Ingest && !userService.UserSessionState.ShowNsfw) {
    <div id="feed-error">
        <p><center>Ingest feed is not available unless NSFW mode is enabled!</center></p>
        <p><center><i>You must enable NSFW mode to continue...</i></center></p>
    </div>
} else if(TagId is not null && Query is not null) {
    <div id="feed-error">
        <p><center>Invalid query parameters! Both a search query and</center></p>
        <p><center>a tag ID have been specified!</center></p>
    </div>
} else {
	<div style="padding:var(--size-default-gap);">
		@foreach(var media in displayMedia) {
			// Precalculate thumbnail size to help the browser
			// lay out the images during initial page load
			int width = (int) media.CurrentUploadedFile!.Width! * 200 / (int) media.CurrentUploadedFile.Height!;
			<a href="/ViewMedia?m=@(media.Guid)">
				<img src="/media/thumb/@(media.Guid)?h=200" width=@width height="200"/>
			</a>
		}
	</div>

	<div id="canary"/>
}

<script suppress-error="BL9992">
    function registerScrollObserver(dotNetObject) {
        var scrollObserver = new IntersectionObserver(
            async (e) => {
                if(e[0].isIntersecting) {
                    await dotNetObject.invokeMethodAsync('LoadMedia', false);
                }
            },
            { threshold: [1] });
        scrollObserver.observe(document.getElementById("canary"));
    }
</script>

@code {
    [Parameter]
    [SupplyParameterFromQuery(Name = "t")]
    public Guid? TagId { get; set; }

    [Parameter]
    [SupplyParameterFromQuery(Name = "q")]
    public string? Query { get; set; }

    [Parameter]
    [SupplyParameterFromQuery]
    public bool Ingest { get; set; } = false;

    public const int PageSize = 50;

    private string Title {
        get {
            if(Query is null)
                return Ingest ? "Ingest Feed" : "Gallery";
            else
                return "Search Results";
        }
    }

    private List<Media> displayMedia;

    protected override void OnInitialized() =>
        userService.UserSessionState.OnStateChange += ShowNsfwChanged;

    protected override void OnParametersSet() => LoadMedia(true);

    protected override void OnAfterRender(bool firstRender) {
        if(firstRender)
            jsRuntime.InvokeVoidAsync(
                "registerScrollObserver",
                DotNetObjectReference.Create(this));
    }

    [JSInvokable("LoadMedia")]
    public void LoadMedia(bool initial = false) {
        Media? key = displayMedia?.Any() ?? false && !initial ? displayMedia.Last() : null;

        if(initial)
            displayMedia = new();

        if(TagId is not null && Query is null) {
            displayMedia!.AddRange(feedService.LoadChunk(
                    selectIngest: Ingest,
                    includeNsfw:  userService.UserSessionState.ShowNsfw,
                    tagId:        (Guid) TagId!,
                    key:          key,
                    count:        PageSize));
        } else if(Query is not null && TagId is null) {
            displayMedia!.AddRange(feedService.LoadChunk(
                    selectIngest: Ingest,
                    includeNsfw:  userService.UserSessionState.ShowNsfw,
                    query:        string.IsNullOrWhiteSpace(Query) ? null : Query,
                    key:          key,
                    count:        PageSize));
        } else {
            displayMedia!.AddRange(feedService.LoadChunk(
                    selectIngest: Ingest,
                    includeNsfw:  userService.UserSessionState.ShowNsfw,
                    key:          key,
                    count:        PageSize));
        }

        StateHasChanged();
    }

    private async void ShowNsfwChanged(UserSessionState userSessionState) {
        await InvokeAsync(() => {
            LoadMedia(true);
        });
    }

    public void Dispose() =>
		userService.UserSessionState.OnStateChange -= ShowNsfwChanged;
}