Group months in album
parent
6feffe70ea
commit
80a76a5a48
|
@ -133,6 +133,21 @@ class ApiBase extends Controller
|
|||
return $folder;
|
||||
}
|
||||
|
||||
protected function isRecursive()
|
||||
{
|
||||
return null === $this->request->getParam('folder');
|
||||
}
|
||||
|
||||
protected function isArchive()
|
||||
{
|
||||
return null !== $this->request->getParam('archive');
|
||||
}
|
||||
|
||||
protected function isMonthView()
|
||||
{
|
||||
return null !== $this->request->getParam('monthView');
|
||||
}
|
||||
|
||||
protected function getShareToken()
|
||||
{
|
||||
return $this->request->getParam('folder_share');
|
||||
|
|
|
@ -49,25 +49,26 @@ class DaysController extends ApiBase
|
|||
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Params
|
||||
$recursive = null === $this->request->getParam('folder');
|
||||
$archive = null !== $this->request->getParam('archive');
|
||||
|
||||
// Run actual query
|
||||
try {
|
||||
$list = $this->timelineQuery->getDays(
|
||||
$folder,
|
||||
$uid,
|
||||
$recursive,
|
||||
$archive,
|
||||
$this->isRecursive(),
|
||||
$this->isArchive(),
|
||||
$this->getTransformations(true),
|
||||
);
|
||||
|
||||
// Preload some day responses
|
||||
$this->preloadDays($list, $uid, $folder, $recursive, $archive);
|
||||
if ($this->isMonthView()) {
|
||||
// Group days together into months
|
||||
$list = $this->timelineQuery->daysToMonths($list);
|
||||
} else {
|
||||
// Preload some day responses
|
||||
$this->preloadDays($list, $uid, $folder);
|
||||
}
|
||||
|
||||
// Add subfolder info if querying non-recursively
|
||||
if (!$recursive) {
|
||||
if (!$this->isRecursive()) {
|
||||
array_unshift($list, $this->getSubfoldersEntry($folder));
|
||||
}
|
||||
|
||||
|
@ -88,18 +89,18 @@ class DaysController extends ApiBase
|
|||
$uid = $this->getUid();
|
||||
|
||||
// Check for wildcard
|
||||
$day_ids = [];
|
||||
$dayIds = [];
|
||||
if ('*' === $id) {
|
||||
$day_ids = null;
|
||||
$dayIds = null;
|
||||
} else {
|
||||
// Split at commas and convert all parts to int
|
||||
$day_ids = array_map(function ($part) {
|
||||
$dayIds = array_map(function ($part) {
|
||||
return (int) $part;
|
||||
}, explode(',', $id));
|
||||
}
|
||||
|
||||
// Check if $day_ids is empty
|
||||
if (null !== $day_ids && 0 === \count($day_ids)) {
|
||||
// Check if $dayIds is empty
|
||||
if (null !== $dayIds && 0 === \count($dayIds)) {
|
||||
return new JSONResponse([], Http::STATUS_OK);
|
||||
}
|
||||
|
||||
|
@ -112,21 +113,29 @@ class DaysController extends ApiBase
|
|||
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Params
|
||||
$recursive = null === $this->request->getParam('folder');
|
||||
$archive = null !== $this->request->getParam('archive');
|
||||
// Convert to actual dayIds if month view
|
||||
if ($this->isMonthView()) {
|
||||
$dayIds = $this->timelineQuery->monthIdToDayIds($dayIds[0]);
|
||||
}
|
||||
|
||||
// Run actual query
|
||||
try {
|
||||
$list = $this->timelineQuery->getDay(
|
||||
$folder,
|
||||
$uid,
|
||||
$day_ids,
|
||||
$recursive,
|
||||
$archive,
|
||||
$dayIds,
|
||||
$this->isRecursive(),
|
||||
$this->isArchive(),
|
||||
$this->getTransformations(false),
|
||||
);
|
||||
|
||||
// Force month id for dayId for month view
|
||||
if ($this->isMonthView()) {
|
||||
foreach ($list as &$photo) {
|
||||
$photo['dayid'] = (int) $dayIds[0];
|
||||
}
|
||||
}
|
||||
|
||||
return new JSONResponse($list, Http::STATUS_OK);
|
||||
} catch (\Exception $e) {
|
||||
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
|
@ -252,13 +261,11 @@ class DaysController extends ApiBase
|
|||
/**
|
||||
* Preload a few "day" at the start of "days" response.
|
||||
*
|
||||
* @param array $days the days array
|
||||
* @param string $uid User ID or blank for public shares
|
||||
* @param null|Folder $folder the folder to search in
|
||||
* @param bool $recursive search in subfolders
|
||||
* @param bool $archive search in archive folder only
|
||||
* @param array $days the days array
|
||||
* @param string $uid User ID or blank for public shares
|
||||
* @param null|Folder $folder the folder to search in
|
||||
*/
|
||||
private function preloadDays(array &$days, string $uid, &$folder, bool $recursive, bool $archive)
|
||||
private function preloadDays(array &$days, string $uid, &$folder)
|
||||
{
|
||||
$transforms = $this->getTransformations(false);
|
||||
$preloaded = 0;
|
||||
|
@ -283,8 +290,8 @@ class DaysController extends ApiBase
|
|||
$folder,
|
||||
$uid,
|
||||
$preloadDayIds,
|
||||
$recursive,
|
||||
$archive,
|
||||
$this->isRecursive(),
|
||||
$this->isArchive(),
|
||||
$transforms,
|
||||
);
|
||||
|
||||
|
|
|
@ -78,6 +78,44 @@ trait TimelineQueryAlbums
|
|||
return $albums;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert days response to months response.
|
||||
* The dayId is used to group the days into months.
|
||||
*/
|
||||
public function daysToMonths(array &$days)
|
||||
{
|
||||
$months = [];
|
||||
foreach ($days as &$day) {
|
||||
$dayId = $day['dayid'];
|
||||
$time = $dayId * 86400;
|
||||
$monthid = strtotime(date('Ym', $time).'01') / 86400;
|
||||
|
||||
if (empty($months) || $months[\count($months) - 1]['dayid'] !== $monthid) {
|
||||
$months[] = [
|
||||
'dayid' => $monthid,
|
||||
'count' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$months[\count($months) - 1]['count'] += $day['count'];
|
||||
}
|
||||
|
||||
return $months;
|
||||
}
|
||||
|
||||
/** Convert list of month IDs to list of dayIds */
|
||||
public function monthIdToDayIds(int $monthId)
|
||||
{
|
||||
$dayIds = [];
|
||||
$firstDay = (int) $monthId;
|
||||
$lastDay = strtotime(date('Ymt', $firstDay * 86400)) / 86400;
|
||||
for ($i = $firstDay; $i <= $lastDay; ++$i) {
|
||||
$dayIds[] = (string) $i;
|
||||
}
|
||||
|
||||
return $dayIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get album if allowed. Also check if album is shared with user.
|
||||
*
|
||||
|
|
|
@ -78,7 +78,7 @@ trait TimelineQueryDays
|
|||
*
|
||||
* @param null|Folder $folder The folder to get the day from
|
||||
* @param string $uid The user id
|
||||
* @param int[] $dayid The day id
|
||||
* @param int[] $day_ids The day ids to fetch
|
||||
* @param bool $recursive If the query should be recursive
|
||||
* @param bool $archive If the query should include only the archive folder
|
||||
* @param array $queryTransforms The query transformations to apply
|
||||
|
|
|
@ -256,6 +256,10 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
return window.innerWidth <= 600;
|
||||
}
|
||||
|
||||
isMonthView() {
|
||||
return this.$route.name === "albums";
|
||||
}
|
||||
|
||||
allowBreakout() {
|
||||
return this.isMobileLayout() && !this.config_squareThumbs;
|
||||
}
|
||||
|
@ -534,6 +538,11 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
query.set("folder_share", this.$route.params.token);
|
||||
}
|
||||
|
||||
// Month view
|
||||
if (this.isMonthView()) {
|
||||
query.set("monthView", "1");
|
||||
}
|
||||
|
||||
// Create query string and append to URL
|
||||
const queryStr = query.toString();
|
||||
if (queryStr) {
|
||||
|
@ -582,7 +591,12 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
// The reason this function is separate from processDays is
|
||||
// because this call is terribly slow even on desktop
|
||||
const dateTaken = utils.dayIdToDate(head.dayId);
|
||||
const name = utils.getLongDateStr(dateTaken, true);
|
||||
let name: string;
|
||||
if (this.isMonthView()) {
|
||||
name = utils.getMonthDateStr(dateTaken);
|
||||
} else {
|
||||
name = utils.getLongDateStr(dateTaken, true);
|
||||
}
|
||||
|
||||
// Cache and return
|
||||
head.name = name;
|
||||
|
@ -782,6 +796,13 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
|
||||
// Aggregate fetch requests
|
||||
this.fetchDayQueue.push(dayId);
|
||||
|
||||
// Only single queries allowed for month vie
|
||||
if (this.isMonthView()) {
|
||||
return this.fetchDayExpire();
|
||||
}
|
||||
|
||||
// Defer for aggregation
|
||||
if (!this.fetchDayTimer) {
|
||||
this.fetchDayTimer = window.setTimeout(() => {
|
||||
this.fetchDayTimer = null;
|
||||
|
|
|
@ -51,6 +51,15 @@ export function getLongDateStr(date: Date, skipYear = false, time = false) {
|
|||
});
|
||||
}
|
||||
|
||||
/** Get month and year string */
|
||||
export function getMonthDateStr(date: Date) {
|
||||
return date.toLocaleDateString(getCanonicalLocale(), {
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
timeZone: "UTC",
|
||||
});
|
||||
}
|
||||
|
||||
/** Get text like "5 years ago" from a date */
|
||||
export function getFromNowStr(date: Date) {
|
||||
// Get fromNow in correct locale
|
||||
|
|
Loading…
Reference in New Issue