-
Notifications
You must be signed in to change notification settings - Fork 38
Color indication for user upload limits (resolve #677) #730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -306,32 +306,61 @@ export async function find({ query, fieldSelect = {}, options = {}, populateUser | |
| } | ||
|
|
||
| export function getNewPhotosLimit(user) { | ||
| let canCreate = 0; | ||
| const pfcount = user.pfcount; | ||
| return Math.max(0, getUserPhotosLimitMax(user) - user.pfcount); | ||
| } | ||
|
|
||
| export function getNewPhotosLimitCss(user) { | ||
| const limit = getUserPhotosLimitMax(user); | ||
|
|
||
| return limit <= 10 ? 'photoLimit1' : limit <= 20 ? 'photoLimit2' : limit <= 75 ? 'photoLimit3' : ''; | ||
| } | ||
|
|
||
| export function getUserPhotosLimitMax(user) { | ||
| // return user photos limit | ||
| /* needed fields: | ||
| user.rules.photoNewLimit | ||
| user.ranks | ||
| user.pcount | ||
| */ | ||
| if (user.rules && _.isNumber(user.rules.photoNewLimit)) { | ||
| canCreate = Math.max(0, Math.min(user.rules.photoNewLimit, maxNewPhotosLimit) - pfcount); | ||
| } else if (user.ranks && (user.ranks.includes('mec_silv') || user.ranks.includes('mec_gold'))) { | ||
| // Silver and Gold metsenats have the maximum possible limit | ||
| canCreate = maxNewPhotosLimit - pfcount; | ||
| } else if (user.ranks && user.ranks.includes('mec')) { | ||
| // Metsenat has a limit of 150 | ||
| canCreate = Math.max(0, 150 - pfcount); | ||
| } else if (user.pcount < 15) { | ||
| canCreate = Math.max(0, 10 - pfcount); | ||
| } else if (user.pcount < 25) { | ||
| canCreate = Math.max(0, 15 - pfcount); | ||
| } else if (user.pcount < 50) { | ||
| canCreate = Math.max(0, 20 - pfcount); | ||
| } else if (user.pcount < 200) { | ||
| canCreate = Math.max(0, 50 - pfcount); | ||
| } else if (user.pcount < 1000) { | ||
| canCreate = Math.max(0, 75 - pfcount); | ||
| } else if (user.pcount >= 1000) { | ||
| canCreate = Math.max(0, 150 - pfcount); | ||
| } | ||
|
|
||
| return canCreate; | ||
| return Math.min(user.rules.photoNewLimit, maxNewPhotosLimit); | ||
| } | ||
|
|
||
| // Silver and Gold metsenats have the maximum possible limit | ||
| if (user.ranks && (user.ranks.includes('mec_silv') || user.ranks.includes('mec_gold'))) { | ||
| return maxNewPhotosLimit; | ||
| } | ||
|
|
||
| // Metsenat has a limit of 150 | ||
| if (user.ranks && user.ranks.includes('mec')) { | ||
| return 150; | ||
| } | ||
|
|
||
| if (user.pcount < 15) { | ||
| return 10; | ||
| } | ||
|
|
||
| if (user.pcount < 25) { | ||
| return 15; | ||
| } | ||
|
|
||
| if (user.pcount < 50) { | ||
| return 20; | ||
| } | ||
|
|
||
| if (user.pcount < 200) { | ||
| return 50; | ||
| } | ||
|
|
||
| if (user.pcount < 1000) { | ||
| return 75; | ||
| } | ||
|
|
||
| if (user.pcount >= 1000) { | ||
| return 150; | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -1508,6 +1537,70 @@ async function givePhotos({ filter, options: { skip = 0, limit = 40, random = fa | |
| Photo.find(query, fieldsSelect, { lean: true, limit }).exec(), | ||
| Photo.countDocuments(countQuery).exec(), | ||
| ]); | ||
| } else if (iAm && iAm.registered && iAm.user.role >= 5 && | ||
| (!(filter.l === null) && filter.l || _.isEqual(filter.lf, [1]))) { | ||
| //aggregate вроде работает дольше по этому используем его только если необходимо | ||
|
|
||
| let aggQuery = [ | ||
| { $lookup: { from: 'users', localField: 'user', foreignField: '_id', as: 'user_info' } }, | ||
| { $match: query }, | ||
| { $set: { photoNewLimit: { $sum: '$user_info.rules.photoNewLimit' } } }, | ||
| { $set: { pcount: { $sum: '$user_info.pcount' } } }, | ||
| { $set: { pfcount: { $sum: '$user_info.pfcount' } } }, | ||
| { $set: { ranks: { $first: '$user_info.ranks' } } }, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это не первое значение в массиве, а первый массив ranks. |
||
| { $set: { photosLimit: { $sum: { $switch: { | ||
| branches: [ | ||
| { case: { $gt: ['$photoNewLimit', 0] }, then: { $min: ['$photoNewLimit', maxNewPhotosLimit] } }, | ||
| { case: { $in: [{ $max: '$ranks' }, ['mec_silv', 'mec_gold']] }, then: maxNewPhotosLimit }, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| { case: { $in: [{ $max: '$ranks' }, ['mec']] }, then: 150 }, | ||
| { case: { $lt: ['$pcount', 15] }, then: 10 }, | ||
| { case: { $lt: ['$pcount', 25] }, then: 15 }, | ||
| { case: { $lt: ['$pcount', 50] }, then: 20 }, | ||
| { case: { $lt: ['$pcount', 200] }, then: 50 }, | ||
| { case: { $lt: ['$pcount', 1000] }, then: 75 }, | ||
| { case: { $gte: ['$pcount', 1000] }, then: 150 }, | ||
| ], | ||
| } } } } }, | ||
| ]; | ||
|
|
||
| if (_.isEqual(filter.lf, [1])) { | ||
| aggQuery = [ | ||
| ...aggQuery, | ||
| { $match: { $expr: { $gte: ['$pfcount', '$photosLimit'] } } }, | ||
| ]; | ||
| } | ||
|
|
||
| if (filter.l) { | ||
| aggQuery = [ | ||
| ...aggQuery, | ||
| { $match: { photosLimit: { $lt: Number(filter.l.max) } } }, | ||
| ]; | ||
| } | ||
|
|
||
| [photos, count] = await Promise.all([ | ||
| Photo.aggregate([ | ||
| ... aggQuery, | ||
| { $sort: { sdate: -1 } }, | ||
| { $skip: skip }, | ||
| { $limit: limit }, | ||
| { $project: { 'photosLimit': 1, 'pcount': 1, 'pfcount': 1, 'photoNewLimit': 1, 'ranks': 1, 'user_info.cid': 1, 'user_info.pfcount': 1, 'user_info.pcount': 1, 'user_info.ranks': 1, 'user_info.rules': 1, ...fieldsSelect } }, | ||
| ]), | ||
| Photo.aggregate([ | ||
| ...aggQuery, | ||
| { $count: 'photos_count' }, | ||
| ]), | ||
| ]); | ||
|
|
||
| // take count value | ||
| count = count.length ? count[0].photos_count : 0; | ||
| } else if (iAm && iAm.registered && iAm.user.role >= 5) { | ||
| //to show different colors make sence only for moderators | ||
| [photos, count] = await Promise.all([ | ||
| Photo.find(query, fieldsSelect, { lean: true, skip, limit, sort: { sdate: -1 } }) | ||
| .populate({ path: 'user', select: { pfcount: 1, pcount: 1, ranks: 1, rules: 1 } } | ||
| ).exec(), | ||
| Photo.countDocuments(query).exec(), | ||
| ]); | ||
| } else { | ||
| [photos, count] = await Promise.all([ | ||
| Photo.find(query, fieldsSelect, { lean: true, skip, limit, sort: { sdate: -1 } }).exec(), | ||
|
|
@@ -1527,6 +1620,13 @@ async function givePhotos({ filter, options: { skip = 0, limit = 40, random = fa | |
| await this.call('photo.fillPhotosProtection', { photos, theyAreMine: itsMineGallery, setMyFlag: !userId }); | ||
|
|
||
| for (const photo of photos) { | ||
| if (iAm.user.role >= 5 && photo.s <= 2) { | ||
| //set user limit for moderator view | ||
| photo.userPhotoLimitCss = getNewPhotosLimitCss(photo.user_info ? photo.user_info[0] : photo.user); | ||
| } else { | ||
| photo.userPhotoLimitCss = ''; | ||
| } | ||
|
|
||
| photo._id = undefined; | ||
| photo.user = undefined; | ||
| photo.vdate = undefined; | ||
|
|
@@ -1588,6 +1688,8 @@ async function givePhotos({ filter, options: { skip = 0, limit = 40, random = fa | |
| s: buildQueryResult.s, | ||
| y: buildQueryResult.y, | ||
| c: buildQueryResult.c, | ||
| l: buildQueryResult.l, | ||
| lf: buildQueryResult.lf, | ||
| geo: filter.geo, | ||
| }, | ||
| }; | ||
|
|
@@ -1615,7 +1717,7 @@ const givePublicNoGeoIndex = (function () { | |
| }; | ||
| }()); | ||
|
|
||
| const filterProps = { geo: [], r: [], rp: [], rs: [], re: [], s: [], t: [], y: [], c: [] }; | ||
| const filterProps = { geo: [], r: [], rp: [], rs: [], re: [], s: [], t: [], y: [], c: [], l: [], lf: [] }; | ||
| const delimeterParam = '_'; | ||
| const delimeterVal = '!'; | ||
| export function parseFilter(filterString) { | ||
|
|
@@ -1790,6 +1892,53 @@ export function parseFilter(filterString) { | |
| } | ||
| } | ||
| } | ||
| } else if (filterParam === 'l') { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут комментарии в этой части diff не помешали бы, тяжело понять логику.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Добавил |
||
| filterVal = filterVal.split(delimeterVal); | ||
|
|
||
| if (Array.isArray(filterVal) && filterVal.length === 1) { | ||
| filterVal = filterVal.map(Number).sort(); | ||
|
|
||
| // set l.max (max user limit) only if value l is choosen in link and between 1 and 9999 | ||
| if (!_.isEqual(filterVal, [0])) { | ||
| const [l0] = filterVal; | ||
| const l = {}; | ||
| let active = true; | ||
|
|
||
| if (l0 > 0 && l0 < 1e5) { | ||
| l.max = l0; | ||
| } else { | ||
| active = false; | ||
| } | ||
|
|
||
| if (active) { | ||
| result.l = l; | ||
| } | ||
| } else { | ||
| const l = {}; | ||
|
|
||
| result.l = l; | ||
| } | ||
| } | ||
| } else if (filterParam === 'lf') { | ||
| filterVal = filterVal.split(delimeterVal); | ||
|
|
||
| if (Array.isArray(filterVal) && filterVal.length) { | ||
| result.lf = []; | ||
|
|
||
| for (filterValItem of filterVal) { | ||
| if (filterValItem) { | ||
| filterValItem = Number(filterValItem); | ||
|
|
||
| if (typesSet.has(filterValItem)) { | ||
| result.lf.push(filterValItem); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!result.lf.length) { | ||
| delete result.lf; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -3163,6 +3312,16 @@ export function buildPhotosQuery(filter, forUserId, iAm, random) { | |
| result.c = filter.c; | ||
| } | ||
|
|
||
| if (filter.l) { | ||
| // добавляется напрямую в агрегативной функции | ||
| result.l = filter.l; | ||
| } | ||
|
|
||
| if (filter.lf) { | ||
| // добавляется напрямую в агрегативной функции | ||
| result.lf = filter.lf; | ||
| } | ||
|
|
||
| if (random) { | ||
| if (!query) { | ||
| query = {}; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Почему используется
$sum, там же значение переменной - число?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не очень знаток mongodb, но sum из-за того, что это агрегированный запрос.
Без
$sumне работает, а что там другое может быть ума не приложу.