/* * Copyright [2019] [Doric.Pub] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // // Created by pengfei.zhou on 2019/11/15. // #import #import "DoricListNode.h" #import "DoricExtensions.h" #import "DoricListItemNode.h" @interface DoricListNode () @property(nonatomic, strong) NSMutableDictionary *tempNodes; @property(nonatomic, assign) NSUInteger itemCount; @property(nonatomic, assign) NSUInteger batchCount; @end @implementation DoricListNode - (instancetype)initWithContext:(DoricContext *)doricContext { if (self = [super initWithContext:doricContext]) { _tempNodes = [NSMutableDictionary new]; _batchCount = 15; } return self; } - (UITableView *)build { return [[UITableView new] also:^(UITableView *it) { it.dataSource = self; it.delegate = self; }]; } - (void)blendView:(UITableView *)view forPropName:(NSString *)name propValue:(id)prop { if ([@"itemCount" isEqualToString:name]) { self.itemCount = [prop unsignedIntegerValue]; } else if ([@"renderItem" isEqualToString:name]) { [self.tempNodes removeAllObjects]; [self clearSubModel]; } else if ([@"batchCount" isEqualToString:name]) { self.batchCount = [prop unsignedIntegerValue]; } else { [super blendView:view forPropName:name propValue:prop]; } } - (void)blend:(NSDictionary *)props { [super blend:props]; [self.view reloadData]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.itemCount; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSUInteger position = (NSUInteger) indexPath.row; NSDictionary *model = [self itemModelAt:position]; NSDictionary *props = model[@"props"]; NSString *reuseId = props[@"identifier"]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseId]; } DoricListItemNode *node = self.tempNodes[@(position)]; node.view = cell; [node blend:props]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSUInteger position = (NSUInteger) indexPath.row; NSDictionary *model = [self itemModelAt:position]; return 60; } - (NSDictionary *)itemModelAt:(NSUInteger)position { NSString *viewId = self.tempNodes[@(position)].viewId; if (viewId && viewId.length > 0) { return [self subModelOf:viewId]; } else { DoricAsyncResult *result = [self callJSResponse:@"renderBunchedItems", @(position), @(self.batchCount), nil]; JSValue *models = [result waitUntilResult]; NSArray *array = [models toArray]; [array enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) { NSString *thisViewId = obj[@"id"]; [self setSubModel:obj in:thisViewId]; NSUInteger pos = position + idx; DoricListItemNode *node = [[DoricListItemNode alloc] initWithContext:self.doricContext]; node.viewId = thisViewId; [node initWithSuperNode:self]; self.tempNodes[@(pos)] = node; }]; return array[0]; } } @end