UNPKG

nativescript-sectioned-list-view

Version:
403 lines (402 loc) 17.3 kB
"use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var common = require("./list-view-common"); var utils = require("utils/utils"); var view = require("ui/core/view"); var label_1 = require("ui/label"); var formatted_string_1 = require("text/formatted-string"); var span_1 = require("text/span"); var enums_1 = require("ui/enums"); var CELLIDENTIFIER = "cell"; var HEADERIDENTIFIER = "header"; var ITEMLOADING = common.SectionedListView.itemLoadingEvent; var HEADERLOADING = common.SectionedListView.headerLoadingEvent; var LOADMOREITEMS = common.SectionedListView.loadMoreItemsEvent; var ITEMTAP = common.SectionedListView.itemTapEvent; var DEFAULT_HEIGHT = 44; global.moduleMerge(common, exports); var infinity = utils.layout.makeMeasureSpec(0, utils.layout.UNSPECIFIED); var SectionedListViewCell = (function (_super) { __extends(SectionedListViewCell, _super); function SectionedListViewCell() { _super.apply(this, arguments); } SectionedListViewCell.prototype.willMoveToSuperview = function (newSuperview) { var parent = (this.view ? this.view.parent : null); if (parent && !newSuperview) { parent._removeContainer(this); } }; Object.defineProperty(SectionedListViewCell.prototype, "view", { get: function () { return this.owner ? this.owner.get() : null; }, enumerable: true, configurable: true }); return SectionedListViewCell; }(UITableViewCell)); var SectionedListViewHeaderView = (function (_super) { __extends(SectionedListViewHeaderView, _super); function SectionedListViewHeaderView() { _super.apply(this, arguments); } SectionedListViewHeaderView.prototype.willMoveToSuperview = function (newSuperview) { var parent = (this.view ? this.view.parent : null); if (parent && !newSuperview) { parent._removeContainer(this); } }; Object.defineProperty(SectionedListViewHeaderView.prototype, "view", { get: function () { return this.owner ? this.owner.get() : null; }, enumerable: true, configurable: true }); return SectionedListViewHeaderView; }(UITableViewHeaderFooterView)); function notifyForItemAtIndex(listView, cell, view, eventName, indexPath) { var args = { eventName: eventName, object: listView, row: indexPath.row, section: indexPath.section, view: view, ios: cell, android: undefined }; listView.notify(args); return args; } function notifyForHeaderAtSection(listView, header, view, eventName, section) { var args = { eventName: eventName, object: listView, row: 0, section: section, view: view, ios: header, android: undefined }; listView.notify(args); return args; } var SectionedDataSource = (function (_super) { __extends(SectionedDataSource, _super); function SectionedDataSource() { _super.apply(this, arguments); } SectionedDataSource.initWithOwner = function (owner) { var dataSource = SectionedDataSource.new(); dataSource._owner = owner; return dataSource; }; SectionedDataSource.prototype.numberOfSectionsInTableView = function (tableView) { var owner = this._owner.get(); if (owner && owner.items && owner.items.getNoOfSections) { return (owner.items).getNoOfSections(); } return 1; }; SectionedDataSource.prototype.tableViewNumberOfRowsInSection = function (tableView, section) { var owner = this._owner.get(); if (owner && owner.items && owner.items.getNoOfItemsInSection) { return (owner.items).getNoOfItemsInSection(section); } return (owner && owner.items) ? owner.items.length : 0; }; SectionedDataSource.prototype.tableViewCellForRowAtIndexPath = function (tableView, indexPath) { var cell = (tableView.dequeueReusableCellWithIdentifier(CELLIDENTIFIER) || SectionedListViewCell.new()); var owner = this._owner.get(); if (owner) { owner._prepareCell(cell, indexPath); var cellView = cell.view; if (cellView) { var width = utils.layout.getMeasureSpecSize(owner.widthMeasureSpec); var rowHeight = owner._nativeView.rowHeight; var cellHeight = rowHeight > 0 ? rowHeight : owner.getHeight(indexPath.row); view.View.layoutChild(owner, cellView, 0, 0, width, cellHeight); } } return cell; }; SectionedDataSource.ObjCProtocols = [UITableViewDataSource]; return SectionedDataSource; }(NSObject)); var SectionedTableViewDelegateImpl = (function (_super) { __extends(SectionedTableViewDelegateImpl, _super); function SectionedTableViewDelegateImpl() { _super.apply(this, arguments); } SectionedTableViewDelegateImpl.initWithOwner = function (owner) { var delegate = SectionedTableViewDelegateImpl.new(); delegate._owner = owner; return delegate; }; SectionedTableViewDelegateImpl.prototype.tableViewWillDisplayCellForRowAtIndexPath = function (tableView, cell, indexPath) { var owner = this._owner.get(); console.log('Will display cell for row at indexpath'); if (owner && (indexPath.section == owner.items.getNoOfSections() - 1) && (indexPath.row === owner.items.getNoOfItemsInSection(indexPath.section) - 1)) { owner.notify({ eventName: LOADMOREITEMS, object: owner }); } }; SectionedTableViewDelegateImpl.prototype.tableViewWillSelectRowAtIndexPath = function (tableView, indexPath) { var cell = tableView.cellForRowAtIndexPath(indexPath); var owner = this._owner.get(); if (owner) { notifyForItemAtIndex(owner, cell, cell.view, ITEMTAP, indexPath); } return indexPath; }; SectionedTableViewDelegateImpl.prototype.tableViewDidSelectRowAtIndexPath = function (tableView, indexPath) { tableView.deselectRowAtIndexPathAnimated(indexPath, true); return indexPath; }; SectionedTableViewDelegateImpl.prototype.tableViewHeightForRowAtIndexPath = function (tableView, indexPath) { var owner = this._owner.get(); if (!owner) { return 44; } var height = undefined; if (utils.ios.MajorVersion >= 8) { height = owner.getHeight(indexPath.row); } if (utils.ios.MajorVersion < 8 || height === undefined) { var cell = this._measureCell; if (!cell) { this._measureCell = tableView.dequeueReusableCellWithIdentifier(CELLIDENTIFIER) || SectionedListViewCell.new(); cell = this._measureCell; } height = owner._prepareCell(cell, indexPath); } return height; }; SectionedTableViewDelegateImpl.ObjCProtocols = [UITableViewDelegate]; return SectionedTableViewDelegateImpl; }(NSObject)); var SectionedUITableViewRowHeightDelegateImpl = (function (_super) { __extends(SectionedUITableViewRowHeightDelegateImpl, _super); function SectionedUITableViewRowHeightDelegateImpl() { _super.apply(this, arguments); } SectionedUITableViewRowHeightDelegateImpl.initWithOwner = function (owner) { var delegate = SectionedUITableViewRowHeightDelegateImpl.new(); delegate._owner = owner; return delegate; }; SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewWillDisplayCellForRowAtIndexPath = function (tableView, cell, indexPath) { var owner = this._owner.get(); if (owner && (indexPath.section == owner.items.getNoOfSections() - 1) && (indexPath.row === owner.items.getNoOfItemsInSection(indexPath.section) - 1)) { owner.notify({ eventName: LOADMOREITEMS, object: owner }); } }; SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewWillSelectRowAtIndexPath = function (tableView, indexPath) { var cell = tableView.cellForRowAtIndexPath(indexPath); var owner = this._owner.get(); if (owner) { notifyForItemAtIndex(owner, cell, cell.view, ITEMTAP, indexPath); } return indexPath; }; SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewHeightForRowAtIndexPath = function (tableView, indexPath) { var owner = this._owner.get(); if (!owner) { return DEFAULT_HEIGHT; } return owner.rowHeight; }; SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewViewForHeaderInSection = function (tableView, section) { var headerView = (tableView.dequeueReusableHeaderFooterViewWithIdentifier(HEADERIDENTIFIER) || SectionedListViewHeaderView.new()); var owner = this._owner.get(); if (owner) { owner._prepareHeaderView(headerView, section); var cellView = headerView.view; if (cellView) { var width = utils.layout.getMeasureSpecSize(owner.widthMeasureSpec); var headerHeight = owner.headerHeight; view.View.layoutChild(owner, cellView, 0, 0, width, headerHeight); } } return headerView; }; SectionedUITableViewRowHeightDelegateImpl.prototype.tableViewHeightForHeaderInSection = function (tableView, section) { var owner = this._owner.get(); return owner.headerHeight; }; SectionedUITableViewRowHeightDelegateImpl.ObjCProtocols = [UITableViewDelegate]; return SectionedUITableViewRowHeightDelegateImpl; }(NSObject)); function onSeparatorColorPropertyChanged(data) { var bar = data.object; if (!bar.ios) { return; } var color = require("color"); if (data.newValue instanceof color.Color) { bar.ios.separatorColor = data.newValue.ios; } } common.SectionedListView.separatorColorProperty.metadata.onSetNativeValue = onSeparatorColorPropertyChanged; var SectionedListView = (function (_super) { __extends(SectionedListView, _super); function SectionedListView() { _super.call(this); this._preparingCell = false; this._isDataDirty = false; this.widthMeasureSpec = 0; this._ios = UITableView.new(); this._ios.registerClassForCellReuseIdentifier(SectionedListViewCell.class(), CELLIDENTIFIER); this._ios.autoresizingMask = UIViewAutoresizing.UIViewAutoresizingNone; this._ios.estimatedRowHeight = DEFAULT_HEIGHT; this._ios.rowHeight = UITableViewAutomaticDimension; this._ios.dataSource = this._dataSource = SectionedDataSource.initWithOwner(new WeakRef(this)); this._delegate = SectionedTableViewDelegateImpl.initWithOwner(new WeakRef(this)); this._heights = new Array(); this._map = new Map(); } SectionedListView.prototype.onLoaded = function () { _super.prototype.onLoaded.call(this); if (this._isDataDirty) { this.refresh(); } this._ios.delegate = this._delegate; }; SectionedListView.prototype.onUnloaded = function () { this._ios.delegate = null; _super.prototype.onUnloaded.call(this); }; Object.defineProperty(SectionedListView.prototype, "ios", { get: function () { return this._ios; }, enumerable: true, configurable: true }); SectionedListView.prototype.scrollToIndexPath = function (index) { if (this._ios) { this._ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), UITableViewScrollPosition.UITableViewScrollPositionTop, false); } }; SectionedListView.prototype.refresh = function () { if (this.isLoaded) { this._ios.reloadData(); this.requestLayout(); this._isDataDirty = false; } else { this._isDataDirty = true; } }; SectionedListView.prototype.getHeight = function (index) { return this._heights[index]; }; SectionedListView.prototype.setHeight = function (index, value) { this._heights[index] = value; }; SectionedListView.prototype._onRowHeightPropertyChanged = function (data) { if (data.newValue < 0) { this._nativeView.rowHeight = UITableViewAutomaticDimension; this._nativeView.estimatedRowHeight = DEFAULT_HEIGHT; this._delegate = SectionedTableViewDelegateImpl.initWithOwner(new WeakRef(this)); } else { this._nativeView.rowHeight = data.newValue; this._nativeView.estimatedRowHeight = data.newValue; this._delegate = SectionedUITableViewRowHeightDelegateImpl.initWithOwner(new WeakRef(this)); } if (this.isLoaded) { this._nativeView.delegate = this._delegate; } _super.prototype._onRowHeightPropertyChanged.call(this, data); }; SectionedListView.prototype.requestLayout = function () { if (!this._preparingCell) { _super.prototype.requestLayout.call(this); } }; SectionedListView.prototype.measure = function (widthMeasureSpec, heightMeasureSpec) { this.widthMeasureSpec = widthMeasureSpec; var changed = this._setCurrentMeasureSpecs(widthMeasureSpec, heightMeasureSpec); _super.prototype.measure.call(this, widthMeasureSpec, heightMeasureSpec); if (changed) { this._ios.reloadData(); } }; SectionedListView.prototype._layoutCell = function (cellView, indexPath) { if (cellView) { var measuredSize = view.View.measureChild(this, cellView, this.widthMeasureSpec, infinity); var height = measuredSize.measuredHeight; this.setHeight(indexPath.row, height); return height; } return 0; }; SectionedListView.prototype._prepareCell = function (cell, indexPath) { var cellHeight; try { this._preparingCell = true; var view_1 = cell.view; if (!view_1) { view_1 = this._getItemTemplateContent(indexPath.row, indexPath.section); } var args = notifyForItemAtIndex(this, cell, view_1, ITEMLOADING, indexPath); view_1 = args.view || this._getDefaultItemContent(indexPath.row); if (!cell.view) { cell.owner = new WeakRef(view_1); } else if (cell.view !== view_1) { this._removeContainer(cell); cell.view._nativeView.removeFromSuperview(); cell.owner = new WeakRef(view_1); } this._prepareItem(view_1, indexPath.row, indexPath.section); this._map.set(cell, view_1); if (view_1 && !view_1.parent && view_1._nativeView) { cell.contentView.addSubview(view_1._nativeView); this._addView(view_1); } cellHeight = this._layoutCell(view_1, indexPath); } finally { this._preparingCell = false; } return cellHeight; }; SectionedListView.prototype._prepareHeaderView = function (headerView, section) { var view = headerView.view; if (!view) { view = this._getHeaderTemplateContent(section); } var args = notifyForHeaderAtSection(this, headerView, view, HEADERLOADING, section); view = args.view; if (!view) { var defaultContent = this._getDefaultHeaderContent(section); defaultContent.marginLeft = this.ios.separatorInset.left; view = defaultContent; } if (!headerView.view) { headerView.owner = new WeakRef(view); } else if (headerView.view !== view) { this._removeContainer(headerView); headerView.view._nativeView.removeFromSuperview(); headerView.owner = new WeakRef(view); } this._prepareHeader(view, section); this._map.set(headerView, view); if (view && !view.parent && view._nativeView) { headerView.contentView.addSubview(view._nativeView); this._addView(view); } }; SectionedListView.prototype._removeContainer = function (cell) { this._removeView(cell.view); this._map.delete(cell); }; SectionedListView.prototype._getDefaultHeaderContent = function (row, section) { if (section === void 0) { section = 0; } var lbl = new label_1.Label(); var formattedString = new formatted_string_1.FormattedString(); var span = new span_1.Span(); span.fontSize = 16; span.bind({ targetProperty: "text", sourceProperty: "$value" }); span.fontAttributes = enums_1.FontAttributes.Bold; formattedString.spans.push(span); lbl.formattedText = formattedString; return lbl; }; return SectionedListView; }(common.SectionedListView)); exports.SectionedListView = SectionedListView;