explore: add new component

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/653/head
Varun Patil 2023-05-03 04:10:31 -07:00
parent aaab49e371
commit 0143148f61
8 changed files with 257 additions and 3 deletions

View File

@ -22,6 +22,7 @@ return [
['name' => 'Page#archive', 'url' => '/archive', 'verb' => 'GET'],
['name' => 'Page#thisday', 'url' => '/thisday', 'verb' => 'GET'],
['name' => 'Page#map', 'url' => '/map', 'verb' => 'GET'],
['name' => 'Page#explore', 'url' => '/explore', 'verb' => 'GET'],
// Routes with params
w(['name' => 'Page#folder', 'url' => '/folders/{path}', 'verb' => 'GET'], 'path'),

View File

@ -214,4 +214,14 @@ class PageController extends Controller
{
return $this->main();
}
/**
* @NoAdminRequired
*
* @NoCSRFRequired
*/
public function explore()
{
return $this->main();
}
}

View File

@ -0,0 +1,88 @@
<template>
<div class="cluster-hlist">
<div class="title" v-if="title">
<div class="name">{{ title }}</div>
<div class="action">
<router-link v-if="link" :to="link">{{ t('memories', 'View all') }}</router-link>
</div>
</div>
<div class="hlist">
<div class="item" v-for="item of clusters" :key="item.cluster_id">
<Cluster :data="item" :link="true" />
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import type { ICluster } from '../types';
import Cluster from './frame/Cluster.vue';
export default defineComponent({
name: 'ClusterHList',
components: {
Cluster,
},
props: {
clusters: {
type: Array as PropType<ICluster[]>,
required: true,
},
title: {
type: String,
required: false,
},
link: {
type: String,
required: false,
},
},
});
</script>
<style lang="scss" scoped>
.cluster-hlist {
width: 100%;
> .title {
padding: 4px 18px 8px 16px;
display: flex;
> .name {
font-size: 18px;
flex-grow: 1;
}
> .action {
:deep a {
color: var(--color-primary);
}
}
}
> .hlist {
width: 100%;
overflow-x: auto;
white-space: nowrap;
padding: 0 8px;
> .item {
display: inline-block;
margin: 0 2px;
height: 120px;
aspect-ratio: 1;
position: relative;
}
// Hide scrollbars
&::-webkit-scrollbar {
display: none;
}
scrollbar-width: none;
}
}
</style>

View File

@ -0,0 +1,145 @@
<template>
<div class="explore-outer">
<ClusterHList v-if="recognize.length" :title="t('memories', 'Recognize')" link="/recognize" :clusters="recognize" />
<ClusterHList
v-if="facerecognition.length"
:title="t('memories', 'Face Recognition')"
link="/facerecognition"
:clusters="facerecognition"
/>
<ClusterHList v-if="places.length" :title="t('memories', 'Places')" link="/places" :clusters="places" />
<ClusterHList v-if="tags.length" :title="t('memories', 'Tags')" link="/tags" :clusters="tags" />
<div class="link-list">
<NcButton
class="link"
v-for="category of categories"
:ariaLabel="category.name"
:key="category.name"
:to="category.link"
type="secondary"
>
<template #icon>
<component :is="category.icon" />
</template>
<template>{{ category.name }}</template>
</NcButton>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import config from '../services/static-config';
import axios from '@nextcloud/axios';
import ClusterHList from './ClusterHList.vue';
import NcButton from '@nextcloud/vue/dist/Components/NcButton';
import StarIcon from 'vue-material-design-icons/Star.vue';
import VideoIcon from 'vue-material-design-icons/PlayCircle.vue';
import ArchiveIcon from 'vue-material-design-icons/PackageDown.vue';
import CalendarIcon from 'vue-material-design-icons/Calendar.vue';
import type { ICluster, IConfig } from '../types';
import { API } from '../services/API';
import { translate as t } from '@nextcloud/l10n';
export default defineComponent({
name: 'Explore',
data: () => ({
config: {} as IConfig,
recognize: [] as ICluster[],
facerecognition: [] as ICluster[],
places: [] as ICluster[],
tags: [] as ICluster[],
categories: [
{
name: t('memories', 'Favorites'),
icon: StarIcon,
link: '/favorites',
},
{
name: t('memories', 'Videos'),
icon: VideoIcon,
link: '/videos',
},
{
name: t('memories', 'Archive'),
icon: ArchiveIcon,
link: '/archive',
},
{
name: t('memories', 'On this day'),
icon: CalendarIcon,
link: '/thisday',
},
],
}),
components: {
ClusterHList,
NcButton,
StarIcon,
},
async mounted() {
this.config = await config.getAll();
if (this.config.recognize_enabled) {
this.getRecognize();
}
if (this.config.facerecognition_enabled) {
this.getFaceRecognition();
}
if (this.config.places_gis > 0) {
this.getPlaces();
}
if (this.config.systemtags_enabled) {
this.getTags();
}
},
methods: {
async getRecognize() {
const res = await axios.get<ICluster[]>(API.FACE_LIST('recognize'));
this.recognize = res.data.slice(0, 10);
},
async getFaceRecognition() {
const res = await axios.get<ICluster[]>(API.FACE_LIST('facerecognition'));
this.facerecognition = res.data.slice(0, 10);
},
async getPlaces() {
const res = await axios.get<ICluster[]>(API.PLACE_LIST());
this.places = res.data.slice(0, 10);
},
async getTags() {
const res = await axios.get<ICluster[]>(API.TAG_LIST());
this.tags = res.data.slice(0, 10);
},
},
});
</script>
<style lang="scss" scoped>
.explore-outer {
> .link-list {
padding: 8px 10px;
> .link {
display: inline-block;
width: calc(50% - 5px);
margin: 0 5px 8px 0;
border-radius: 10px;
}
}
}
</style>

View File

@ -177,7 +177,7 @@ export default defineComponent({
},
back() {
this.$router.push({ name: 'albums' });
this.$router.go(-1);
},
async downloadAlbum() {

View File

@ -46,7 +46,7 @@ export default defineComponent({
methods: {
back() {
this.$router.push({ name: this.$route.name as string });
this.$router.go(-1);
},
},
});

View File

@ -100,7 +100,7 @@ export default defineComponent({
},
back() {
this.$router.push({ name: this.$route.name as string });
this.$router.go(-1);
},
changeShowFaceRect() {

View File

@ -3,6 +3,7 @@ import { translate as t } from '@nextcloud/l10n';
import Router from 'vue-router';
import Vue from 'vue';
import Timeline from './components/Timeline.vue';
import Explore from './components/Explore.vue';
import SplitTimeline from './components/SplitTimeline.vue';
import ClusterView from './components/ClusterView.vue';
@ -149,5 +150,14 @@ export default new Router({
rootTitle: t('memories', 'Map'),
}),
},
{
path: '/explore',
component: Explore,
name: 'explore',
props: (route) => ({
rootTitle: t('memories', 'Explore'),
}),
},
],
});