Add start page (fix #109)

old-stable24
Varun Patil 2022-10-24 21:30:43 -07:00
parent 24d7afcbe8
commit bf15699265
5 changed files with 285 additions and 12 deletions

View File

@ -716,10 +716,13 @@ class ApiController extends Controller
try { try {
$folder = null; $folder = null;
$folderPath = $this->request->getParam('folder'); $folderPath = $this->request->getParam('folder');
$forcedTimelinePath = $this->request->getParam('timelinePath');
$userFolder = $this->rootFolder->getUserFolder($uid); $userFolder = $this->rootFolder->getUserFolder($uid);
if (null !== $folderPath) { if (null !== $folderPath) {
$folder = $userFolder->get($folderPath); $folder = $userFolder->get($folderPath);
} elseif (null !== $forcedTimelinePath) {
$folder = $userFolder->get($forcedTimelinePath);
} else { } else {
$configPath = Exif::removeExtraSlash(Exif::getPhotosPath($this->config, $uid)); $configPath = Exif::removeExtraSlash(Exif::getPhotosPath($this->config, $uid));
$folder = $userFolder->get($configPath); $folder = $userFolder->get($configPath);

View File

@ -65,8 +65,12 @@ class PageController extends Controller
// Configuration // Configuration
$uid = $user->getUid(); $uid = $user->getUid();
$timelinePath = \OCA\Memories\Util::getPhotosPath($this->config, $uid); $this->initialState->provideInitialState('timelinePath', $this->config->getUserValue(
$this->initialState->provideInitialState('timelinePath', $timelinePath); $uid,
Application::APPNAME,
'timelinePath',
'EMPTY'
));
$this->initialState->provideInitialState('foldersPath', $this->config->getUserValue( $this->initialState->provideInitialState('foldersPath', $this->config->getUserValue(
$uid, $uid,
Application::APPNAME, Application::APPNAME,

View File

@ -1,5 +1,9 @@
<template> <template>
<NcContent app-name="memories"> <FirstStart v-if="isFirstStart" />
<NcContent app-name="memories" v-else :class="{
'remove-gap': removeOuterGap,
}">
<NcAppNavigation> <NcAppNavigation>
<template id="app-memories-navigation" #list> <template id="app-memories-navigation" #list>
<NcAppNavigationItem :to="{name: 'timeline'}" <NcAppNavigationItem :to="{name: 'timeline'}"
@ -62,6 +66,7 @@ import { getCurrentUser } from '@nextcloud/auth';
import Timeline from './components/Timeline.vue' import Timeline from './components/Timeline.vue'
import Settings from './components/Settings.vue' import Settings from './components/Settings.vue'
import FirstStart from './components/FirstStart.vue'
import GlobalMixin from './mixins/GlobalMixin'; import GlobalMixin from './mixins/GlobalMixin';
import UserConfig from './mixins/UserConfig'; import UserConfig from './mixins/UserConfig';
@ -84,6 +89,7 @@ import TagsIcon from 'vue-material-design-icons/Tag.vue';
Timeline, Timeline,
Settings, Settings,
FirstStart,
ImageMultiple, ImageMultiple,
FolderIcon, FolderIcon,
@ -102,13 +108,13 @@ export default class App extends Mixins(GlobalMixin, UserConfig) {
return this.config_recognizeEnabled || getCurrentUser()?.isAdmin; return this.config_recognizeEnabled || getCurrentUser()?.isAdmin;
} }
public mounted() { get isFirstStart() {
// Get the content-vue element and add nextcloud version as a class to it return this.config_timelinePath === 'EMPTY';
const contentVue = document.querySelector('#content-vue'); }
if (contentVue) {
const version = (<any>window.OC).config.version.split('.'); get removeOuterGap() {
contentVue.classList.add('nextcloud-major-' + version[0]); const version = (<any>window.OC).config.version.split('.');
} return (Number(version[0]) >= 25);
} }
async beforeMount() { async beforeMount() {
@ -154,8 +160,8 @@ body {
overflow: hidden; overflow: hidden;
} }
// Nextcloud 25: get rid of gap and border radius at right // Nextcloud 25+: get rid of gap and border radius at right
#content-vue.nextcloud-major-25 { #content-vue.remove-gap {
// was var(--body-container-radius) // was var(--body-container-radius)
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="85.098495mm"
height="22.8346mm"
viewBox="0 0 85.098495 22.8346"
version="1.1"
id="svg5"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="banner.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="2.0208096"
inkscape:cx="129.40358"
inkscape:cy="137.3212"
inkscape:window-width="1920"
inkscape:window-height="991"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-49.278513,-55.204782)">
<g
aria-label="Memories"
id="text1244"
style="font-size:25.4px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;stroke-width:0.264583">
<path
d="m 67.160113,61.300782 c 0,4.190999 -2.6416,8.635999 -2.6416,13.004799 0,2.54 1.5494,3.7338 2.921,3.7338 3.657599,0 6.121399,-8.2804 6.807199,-10.5664 0.127,-0.381 -0.0508,-0.508 -0.4826,-0.508 -0.3556,0 -0.4064,0.1016 -0.5334,0.4318 -1.143,2.7432 -3.6068,8.89 -5.130799,8.89 -0.381,0 -1.0668,-0.3556 -1.0668,-1.8034 0,-4.2418 2.590799,-7.62 2.590799,-12.649199 0,-1.2954 -0.254,-3.2258 -2.057399,-3.2258 -2.3876,0 -5.2324,3.5814 -6.4516,6.197599 0.4064,-1.650999 1.2954,-4.775199 1.2954,-6.680199 0,-1.7526 -0.7366,-2.921 -1.8542,-2.921 -3.048,0 -6.731,9.474199 -7.8994,11.963399 0.5334,-2.1336 2.3368,-8.432799 2.3368,-10.083799 0,-0.889 -0.4826,-1.6764 -1.0414,-1.6764 -0.7874,0 -1.651,1.651 -2.3622,4.572 -0.4318,1.7018 -1.1684,5.410199 -1.651,8.381999 -0.4064,2.5146 -0.6604,3.683 -0.6604,4.8006 0,0.6858 0.3302,0.7874 0.7874,0.7874 0.5588,0 0.9652,-0.1524 1.3462,-0.508 1.0414,-0.9906 1.1176,-2.921 1.651,-4.4704 1.0668,-3.0734 5.5118,-11.125199 6.5024,-11.125199 0.2286,0 0.2286,0.4318 0.2286,0.508 0,2.9464 -2.2352,8.331199 -2.2352,11.937999 0,0 0,0.7366 0.635,0.7366 0.2794,0 0.635,-0.127 0.9398,-0.3556 0.6096,-0.4572 0.7366,-1.0668 1.0922,-1.9558 1.4732,-3.81 5.08,-8.229599 6.477,-8.229599 0.4826,0 0.4572,0.4318 0.4572,0.8128 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7590" />
<path
d="m 74.830891,72.400581 c 2.5146,0 5.461,-3.048 5.461,-5.0546 0,-0.0762 0,-0.127 -0.0254,-0.2032 -0.127,-0.1524 -0.2794,-0.254 -0.4826,-0.254 -0.6604,1.0414 -2.7686,4.064 -4.1656,4.064 -0.7874,0 -1.1176,-0.9906 -1.1176,-1.651 v -0.127 c 1.778,-0.1016 3.4544,-2.3368 3.4544,-4.0386 0,-0.9906 -0.5334,-1.549399 -1.5494,-1.549399 -2.7432,0 -4.1656,3.479799 -4.1656,5.791199 0,1.27 1.0414,3.0226 2.5908,3.0226 z m 1.8542,-6.985 c 0,0.7112 -1.2954,2.6924 -2.0828,2.7432 0.0508,-0.6858 0.9398,-3.302 1.8034,-3.302 0.2794,0 0.2794,0.381 0.2794,0.5588 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7592" />
<path
d="m 81.714249,62.113582 c -2.032,0 -2.6416,6.908799 -2.6416,8.508999 0,0.635 0.0508,1.778 0.9144,1.778 1.4224,0 2.1844,-1.3208 2.5654,-2.5146 0.3048,-0.9906 1.9558,-6.502399 2.794,-6.603999 0.2286,0.3556 0.2286,1.142999 0.2286,1.574799 0,1.6002 -0.1524,3.175 -0.1524,4.7752 0,0.5842 -0.0254,1.8288 0.8382,1.8288 1.27,0 3.4036,-6.8834 4.5212,-7.0612 0.127,0.3302 0.1524,0.6604 0.1524,0.9906 0,1.905 -0.5334,3.7338 -0.5334,5.6388 0,0.8382 0.1016,2.4638 1.27,2.4638 1.0922,0 4.699,-5.207 4.8514,-6.35 -0.1016,-0.1524 -0.3048,-0.254 -0.4826,-0.254 -0.3556,0 -2.9972,4.2164 -3.683,4.318 -0.0762,-0.0508 -0.1016,-0.1524 -0.1016,-0.2032 0,-0.6858 0.2794,-1.4732 0.4318,-2.159 0.3048,-1.3716 0.6096,-2.794 0.6096,-4.2164 0,-0.9144 -0.4572,-2.260599 -1.5748,-2.260599 -1.9812,0 -3.6322,3.505199 -4.3688,5.029199 0.0254,-1.0414 0.2032,-2.0828 0.2032,-3.1496 0,-1.015999 -0.1016,-2.997199 -1.524,-2.997199 -2.1082,0 -3.8862,5.257799 -4.572,6.908799 0.1524,-1.6764 0.9144,-3.2766 0.9144,-4.978399 0,-0.508 0.0254,-1.0668 -0.6604,-1.0668 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7594" />
<path
d="m 97.640031,74.254781 c 1.905,0 3.555999,-1.9558 4.292599,-4.3434 1.5494,-0.1778 3.683,-1.7272 3.683,-2.6924 0,-0.2286 -0.127,-0.4572 -0.3048,-0.508 -0.7874,0.635 -2.159,1.397 -3.0226,1.6256 0.0508,-0.3302 0.0508,-0.6604 0.0508,-0.9906 0,-2.5146 -1.3462,-4.775199 -2.870199,-4.775199 -1.2446,0 -2.6416,1.498599 -2.6416,2.819399 0,0.0508 0,0.127 0,0.1778 -1.2446,1.016 -1.9558,2.6924 -1.9558,4.572 0,2.3876 1.1684,4.1148 2.7686,4.1148 z m 3.149599,-6.1976 c -1.092199,-0.6096 -2.311399,-1.8796 -2.311399,-2.6416 0,-0.4572 0.4826,-0.9906 0.9398,-0.9906 0.736599,0 1.396999,1.4478 1.396999,3.048 0,0.2032 0,0.381 -0.0254,0.5842 z m -0.2794,1.651 c -0.4318,1.6256 -1.244599,3.0226 -2.209799,3.0226 -0.6858,0 -1.3208,-1.1176 -1.3208,-2.3368 0,-0.9652 0.4064,-2.1844 0.8382,-2.7432 0.7112,0.889 1.7272,1.6764 2.692399,2.0574 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7596" />
<path
d="m 107.24121,75.524781 c 1.8034,0 6.4262,-6.6548 6.5532,-8.382 0.0254,-0.2794 -0.2794,-0.254 -0.4826,-0.254 -0.4572,0.7112 -4.1402,6.2738 -4.9276,6.2738 -0.1778,0 -0.1524,-0.254 -0.1524,-0.381 0.127,-1.4224 1.27,-2.8702 1.397,-4.3688 0.1524,-1.5748 -1.0922,-1.6002 -2.3622,-2.032 0.6096,-0.5588 1.1684,-1.651 1.2446,-2.4384 0.0762,-0.939799 -0.4826,-2.387599 -1.5748,-2.387599 -1.8034,0 -2.4638,1.8288 -2.5908,3.301999 -0.2032,2.54 1.6764,2.7178 3.5306,3.302 -0.0254,0.4318 -0.635,1.7018 -0.8382,2.2098 -0.4064,1.0922 -0.8128,2.2352 -0.9144,3.3782 -0.0762,0.9144 0.0254,1.778 1.1176,1.778 z m -0.2794,-11.43 c -0.0508,0.508 -0.3048,1.6764 -0.6858,2.032 -0.381,-0.2032 -0.4318,-0.8636 -0.4064,-1.27 0.0508,-0.3302 0.2032,-1.727199 0.7112,-1.727199 0.3556,0 0.4064,0.711199 0.381,0.965199 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7598" />
<path
d="m 115.31839,62.570782 c 0.8636,0 1.2954,-0.9906 1.2954,-1.7272 0,-0.508 -0.1778,-1.1684 -0.8128,-1.1684 -1.0414,0 -1.4478,0.9144 -1.4478,1.7018 0,0.5334 0.381,1.1938 0.9652,1.1938 z m -0.9906,10.159999 c 1.5494,0 4.6228,-4.191 4.6228,-5.461 0,-0.2286 -0.0508,-0.381 -0.3048,-0.381 -0.9398,0 -2.9464,4.064 -3.6576,4.064 -0.381,0 -0.4064,-0.5842 -0.4064,-0.8382 0,-3.0988 1.2192,-4.2418 1.2192,-5.3594 0,-0.6604 -0.381,-0.8128 -0.9906,-0.8128 -1.3208,0 -2.1844,3.302 -2.1844,5.461 0,1.0668 0.254,3.3274 1.7018,3.3274 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7600" />
<path
d="m 120.04276,72.400581 c 2.5146,0 5.461,-3.048 5.461,-5.0546 0,-0.0762 0,-0.127 -0.0254,-0.2032 -0.127,-0.1524 -0.2794,-0.254 -0.4826,-0.254 -0.6604,1.0414 -2.7686,4.064 -4.1656,4.064 -0.7874,0 -1.1176,-0.9906 -1.1176,-1.651 v -0.127 c 1.778,-0.1016 3.4544,-2.3368 3.4544,-4.0386 0,-0.9906 -0.5334,-1.549399 -1.5494,-1.549399 -2.7432,0 -4.1656,3.479799 -4.1656,5.791199 0,1.27 1.0414,3.0226 2.5908,3.0226 z m 1.8542,-6.985 c 0,0.7112 -1.2954,2.6924 -2.0828,2.7432 0.0508,-0.6858 0.9398,-3.302 1.8034,-3.302 0.2794,0 0.2794,0.381 0.2794,0.5588 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7602" />
<path
d="m 127.07852,70.647981 c -1.7272,1.3208 -3.048,2.8448 -3.048,4.191 0,1.4986 1.143,2.5908 2.6162,2.5908 2.286,0 4.7752,-2.1844 4.7752,-4.2418 0,-1.397 -0.5588,-2.3368 -1.3208,-3.048 1.7018,-1.0414 3.429,-1.9812 4.2672,-2.7432 0.0508,-0.254 -0.127,-0.5334 -0.381,-0.4826 -0.9398,0.2286 -2.9718,1.143 -4.953,2.3876 -1.2192,-0.8382 -2.4384,-1.397 -2.4384,-2.4892 0,-1.0668 1.0922,-3.0734 2.3114,-3.0734 0.5842,0 0.9906,0.3556 0.9906,1.0668 0,0.5842 -0.3048,1.1176 -0.3048,1.7018 0,0.3302 0.2032,0.5842 0.5334,0.5842 0.9144,0 1.4478,-1.1684 1.4478,-1.9304 0,-1.752599 -0.9398,-2.692399 -2.6924,-2.692399 -2.5908,0 -4.3942,2.133599 -4.3942,4.648199 0,1.9558 1.2954,2.8194 2.5908,3.5306 z m -1.2446,3.81 c 0,-1.0414 1.0668,-2.1082 2.4638,-3.1242 0.762,0.4826 1.3462,1.0414 1.3462,1.9812 0,0.9398 -1.3462,2.3876 -2.5146,2.3876 -0.762,0 -1.2954,-0.5842 -1.2954,-1.2446 z"
style="font-family:'Lofty Goals';-inkscape-font-specification:'Lofty Goals'"
id="path7604" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,176 @@
<template>
<NcContent app-name="memories">
<NcAppContent>
<div class="outer fill-block" :class="{ show }">
<div class="title">
<img :src="banner" />
</div>
<div class="text">
{{ t('memories', 'A better photos experience awaits you') }} <br/>
{{ t('memories', 'Choose the root folder of your timeline to begin') }}
</div>
<div class="admin-text" v-if="isAdmin">
{{ t('memories', 'If you just installed Memories, run:') }}
<br/>
<code>occ memories:index</code>
</div>
<div class="error" v-if="error">
{{ error }}
</div>
<div class="info" v-if="info">
{{ info }} <br/>
<NcButton @click="finish" class="button" type="primary">
{{ t('memories', 'Continue to Memories') }}
</NcButton>
</div>
<NcButton @click="begin" class="button" v-if="info">
{{ t('memories', 'Choose again') }}
</NcButton>
<NcButton @click="begin" class="button" type="primary" v-else>
{{ t('memories', 'Click here to start') }}
</NcButton>
<div class="footer">
{{ t('memories', 'You can always change this later in settings') }}
</div>
</div>
</NcAppContent>
</NcContent>
</template>
<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator';
import { NcContent, NcAppContent, NcButton } from '@nextcloud/vue';
import { getFilePickerBuilder } from '@nextcloud/dialogs'
import { generateUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth';
import axios from '@nextcloud/axios'
import GlobalMixin from '../mixins/GlobalMixin';
import UserConfig from '../mixins/UserConfig';
import banner from "../assets/banner.svg";
import { IDay } from '../types';
@Component({
components: {
NcContent,
NcAppContent,
NcButton,
},
})
export default class FirstStart extends Mixins(GlobalMixin, UserConfig) {
banner = banner;
error = '';
info = ''
show = false;
chosenPath = '';
mounted() {
window.setTimeout(() => {
this.show = true;
}, 300);
}
get isAdmin() {
return getCurrentUser().isAdmin;
}
async begin() {
const path = await this.chooseFolder(this.t('memories', 'Choose the root of your timeline'), '/');
// Get folder days
this.error = '';
this.info = '';
const query = new URLSearchParams();
query.set('timelinePath', path);
let url = generateUrl('/apps/memories/api/days?' + query.toString());
const res = await axios.get<IDay[]>(url);
// Check response
if (res.status !== 200) {
this.error = this.t('memories', 'The selected folder does not seem to be valid. Try again.');
return;
}
// Count total photos
const total = res.data.reduce((acc, day) => acc + day.count, 0);
this.info = this.t('memories', 'Found {total} photos in {path}', { total, path });
this.chosenPath = path;
}
async finish() {
this.show = false;
await new Promise(resolve => setTimeout(resolve, 500));
this.config_timelinePath = this.chosenPath;
await this.updateSetting('timelinePath');
}
async chooseFolder(title: string, initial: string) {
const picker = getFilePickerBuilder(title)
.setMultiSelect(false)
.setModal(true)
.setType(1)
.addMimeTypeFilter('httpd/unix-directory')
.allowDirectories()
.startAt(initial)
.build();
return await picker.pick();
}
}
</script>
<style lang="scss" scoped>
.outer {
padding: 20px;
text-align: center;
transition: opacity 1s ease;
opacity: 0;
&.show { opacity: 1; }
.title {
font-size: 2.8em;
line-height: 1.1em;
font-family: cursive;
font-weight: 500;
margin-top: 10px;
margin-bottom: 20px;
width: 100%;
filter: var(--background-invert-if-dark);
> img {
max-width: calc(100vw - 40px);
}
}
.admin-text {
margin-top: 10px;
}
.error {
color: red;
}
.info {
margin-top: 10px;
font-weight: bold;
}
.button {
display: inline-block;
margin: 15px;
}
.footer {
font-size: 0.8em;
}
}
</style>