Skip to content

Commit

Permalink
Add start page (fix #109)
Browse files Browse the repository at this point in the history
  • Loading branch information
pulsejet committed Oct 25, 2022
1 parent d09db4d commit 211519d
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 12 deletions.
3 changes: 3 additions & 0 deletions lib/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -716,10 +716,13 @@ private function getRequestFolder()
try {
$folder = null;
$folderPath = $this->request->getParam('folder');
$forcedTimelinePath = $this->request->getParam('timelinePath');
$userFolder = $this->rootFolder->getUserFolder($uid);

if (null !== $folderPath) {
$folder = $userFolder->get($folderPath);
} elseif (null !== $forcedTimelinePath) {
$folder = $userFolder->get($forcedTimelinePath);
} else {
$configPath = Exif::removeExtraSlash(Exif::getPhotosPath($this->config, $uid));
$folder = $userFolder->get($configPath);
Expand Down
8 changes: 6 additions & 2 deletions lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,12 @@ public function main()

// Configuration
$uid = $user->getUid();
$timelinePath = \OCA\Memories\Util::getPhotosPath($this->config, $uid);
$this->initialState->provideInitialState('timelinePath', $timelinePath);
$this->initialState->provideInitialState('timelinePath', $this->config->getUserValue(
$uid,
Application::APPNAME,
'timelinePath',
'EMPTY'
));
$this->initialState->provideInitialState('foldersPath', $this->config->getUserValue(
$uid,
Application::APPNAME,
Expand Down
26 changes: 16 additions & 10 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<NcContent app-name="memories">
<FirstStart v-if="isFirstStart" />

<NcContent app-name="memories" v-else :class="{
'remove-gap': removeOuterGap,
}">
<NcAppNavigation>
<template id="app-memories-navigation" #list>
<NcAppNavigationItem :to="{name: 'timeline'}"
Expand Down Expand Up @@ -62,6 +66,7 @@ import { getCurrentUser } from '@nextcloud/auth';
import Timeline from './components/Timeline.vue'
import Settings from './components/Settings.vue'
import FirstStart from './components/FirstStart.vue'
import GlobalMixin from './mixins/GlobalMixin';
import UserConfig from './mixins/UserConfig';
Expand All @@ -84,6 +89,7 @@ import TagsIcon from 'vue-material-design-icons/Tag.vue';
Timeline,
Settings,
FirstStart,
ImageMultiple,
FolderIcon,
Expand All @@ -102,13 +108,13 @@ export default class App extends Mixins(GlobalMixin, UserConfig) {
return this.config_recognizeEnabled || getCurrentUser()?.isAdmin;
}
public mounted() {
// Get the content-vue element and add nextcloud version as a class to it
const contentVue = document.querySelector('#content-vue');
if (contentVue) {
const version = (<any>window.OC).config.version.split('.');
contentVue.classList.add('nextcloud-major-' + version[0]);
}
get isFirstStart() {
return this.config_timelinePath === 'EMPTY';
}
get removeOuterGap() {
const version = (<any>window.OC).config.version.split('.');
return (Number(version[0]) >= 25);
}
async beforeMount() {
Expand Down Expand Up @@ -154,8 +160,8 @@ body {
overflow: hidden;
}
// Nextcloud 25: get rid of gap and border radius at right
#content-vue.nextcloud-major-25 {
// Nextcloud 25+: get rid of gap and border radius at right
#content-vue.remove-gap {
// was var(--body-container-radius)
border-top-right-radius: 0;
border-bottom-right-radius: 0;
Expand Down
84 changes: 84 additions & 0 deletions src/assets/banner.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
176 changes: 176 additions & 0 deletions src/components/FirstStart.vue
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 211519d

Please sign in to comment.