big pagination update - split models into pages

This commit is contained in:
Seth Ladygo
2019-05-31 01:41:56 -07:00
parent 59faa47e61
commit 4ac28cceb4
4 changed files with 181 additions and 85 deletions

View File

@ -1,23 +1,111 @@
const MAX_PAGE_MATERIALS = 16
const MATERIALS_PER_ROW = 4
const MAX_BLOCK_SIZE = 3
function chunkify(array, size) {
let chunks = []
for (let i = 0, j = array.length; i < j; i += size) {
let slice = array.slice(i, i + size)
chunks.push(slice)
}
return chunks
}
function copyModel(model) {
if (model) {
return JSON.parse(JSON.stringify(model))
} else {
console.error('no model to copy')
}
}
function copyModels(models) {
let copies = []
if (models) {
for (let model of models) {
let copy = copyModel(model)
copies.push(copy)
}
}
return copies
}
// split models with too many materials
function splitModels(models) {
let splits = []
for (let model of models) {
if (model.size > MAX_BLOCK_SIZE) {
let chunks = chunkify(model.ids, MAX_PAGE_MATERIALS)
for (let chunk of chunks) {
let splitModel = copyModel(model)
splitModel.ids = chunk
splits.push(splitModel)
}
} else {
splits.push(copyModel(model))
}
}
return splits
}
// join adjacent models with the same model number
function joinModels(models) {
let joins = []
let lastModel = null
for (let model of models) {
model = copyModel(model)
if (lastModel) {
if (lastModel.model === model.model) {
// match - join
lastModel.ids.push(...model.ids)
// uniquify
lastModel.ids = lastModel.ids.filter((v, i, a) => a.indexOf(v) === i)
} else {
// no match - add
joins.push(model)
lastModel = model
}
} else {
// first - add
joins.push(model)
lastModel = model
}
}
return joins
}
export function paginateModels(models) {
models = joinModels(models)
for (let model of models) {
// ensure sizes
model.size = modelSize(model)
model.size = modelBlockSize(model)
}
models = splitModels(models)
for (let model of models) {
model.size = modelBlockSize(model)
}
models = copyModels(models)
let pages = []
let currentSize = 0
let currentPage = []
for (let model of models) {
if (model.size > 0) { // skip empty models
currentSize += model.size
if (currentSize > 3) {
pages.push(currentPage)
currentPage = [model]
currentSize = model.size
} else {
currentPage.push(model)
}
if (model.size < 1) {
// skip empty models
continue
}
currentSize += model.size
if (currentSize > 3) {
pages.push(currentPage)
currentPage = [model]
currentSize = model.size
} else {
currentPage.push(model)
}
}
if (currentPage.length > 0) {
@ -27,23 +115,37 @@ export function paginateModels(models) {
return pages
}
export function modelSize(model) {
export function modelBlockSize(model) {
if (!model || !model.ids) return 0
if (model.ids.length <= 4) return 1
if (model.ids.length <= 8) return 2
return 3
if (model.ids.length <= MATERIALS_PER_ROW) return 1
if (model.ids.length <= MATERIALS_PER_ROW * 2) return 2
if (model.ids.length <= MATERIALS_PER_ROW * 4) return 3
return MAX_BLOCK_SIZE + 1 // generic "too big"
}
export function sectionModels(section) {
// remove pages, return models (blocks) in order
// de-paginate, essentially
export function modelsFromSection(section, getters) {
// remove pages, return models (blocks) in order.
// combine blocks with the same model number.
let models = []
if (section && section.pages) {
for (let page of section.pages) {
models.push(...page)
for (let model of page) {
model = copyModel(model)
if (model.ids && model.ids.length > 0) {
// add extra info from a material
let material = getters.material(model.ids[0])
if (material) {
model = extendModelFromMaterial(material, model)
} else {
console.log('no material found for id', model.ids[0])
}
models.push(model)
}
}
}
}
return models
return joinModels(models)
}
export function sectionTitle(material) {