<commit_before>
#import "SideToolbar.h"
#import "SideToolbarCell.h"
#import "UIKitCategories.h"
#import "BuyButtonCell.h"
#include "../../platform/platform.hpp"

typedef NS_ENUM(NSUInteger, Section)
{
  SectionTopSpace,
  SectionMenu,
  SectionBottomSpace,
  SectionBuyButton,
  SectionCount
};

@interface SideToolbar () <UITableViewDataSource, UITableViewDelegate, BuyButtonCellDelegate>

@property (nonatomic) UITableView * tableView;
@property (nonatomic) UIPanGestureRecognizer * slidePanGesture;
@property (nonatomic) UIPanGestureRecognizer * menuPanGesture;
@property (nonatomic) UIButton * buyButton;
@property (nonatomic) UIView * backgroundView;

@property (nonatomic) BOOL isMenuHidden;

@end

@implementation SideToolbar
{
  NSArray * menuTitles;
  NSArray * menuImageNames;
  NSArray * disabledInTrial;
  CGPoint slideViewOffset;
}

- (id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];

  menuTitles = @[NSLocalizedString(@"search", nil),
                 NSLocalizedString(@"maps", nil),
                 NSLocalizedString(@"bookmarks", nil),
                 NSLocalizedString(@"settings", nil),
                 NSLocalizedString(@"share_my_location", nil)];

  menuImageNames = @[@"side-toolbar-icon-search",
                     @"side-toolbar-icon-map",
                     @"side-toolbar-icon-bookmarks",
                     @"side-toolbar-icon-settings",
                     @"side-toolbar-icon-share"];

  disabledInTrial = @[@YES, @NO, @YES, @NO, @NO, @NO];

  self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin;
  [self addGestureRecognizer:self.menuPanGesture];

  [self addSubview:self.backgroundView];
  [self addSubview:self.tableView];

  return self;
}

- (void)buyButtonCellDidPressBuyButton:(BuyButtonCell *)cell
{
  [self.delegate sideToolbarDidPressBuyButton:self];
}

#pragma mark - TableView

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  if (section == SectionMenu)
    return [menuTitles count];
  else
    return 1;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
  return SectionCount;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  UITableViewCell * cell = nil;
  if (indexPath.section == SectionMenu)
  {
    cell = [tableView dequeueReusableCellWithIdentifier:@"MenuCell"];
    SideToolbarCell * customCell = (SideToolbarCell *)cell;
    if (!customCell)
      customCell = [[SideToolbarCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MenuCell"];

    if (GetPlatform().IsPro())
      customCell.disabled = NO;
    else
      customCell.disabled = [disabledInTrial[indexPath.row] boolValue];

    customCell.iconImageView.image = [UIImage imageNamed:menuImageNames[indexPath.row]];
    customCell.titleLabel.text = menuTitles[indexPath.row];

    cell = customCell;
  }
  else if (indexPath.section == SectionTopSpace || indexPath.section == SectionBottomSpace)
  {
    cell = [tableView dequeueReusableCellWithIdentifier:@"SpaceCell"];
    if (!cell)
    {
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SpaceCell"];
      cell.backgroundColor = [UIColor clearColor];
      cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
  }
  else if (indexPath.section == SectionBuyButton)
  {
    BuyButtonCell * customCell = (BuyButtonCell *)[tableView dequeueReusableCellWithIdentifier:@"BuyButtonCell"];
    if (!customCell)
    {
      customCell = [[BuyButtonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BuyButtonCell"];
      customCell.delegate = self;
    }
    cell = customCell;
  }

  return cell;
}

- (CGFloat)restSpace
{
  return self.height - [SideToolbarCell cellHeight] * [menuTitles count] - [BuyButtonCell cellHeight];
}

- (CGFloat)topSpaceRatio
{
  return IPAD ? 0.7 : 0.65;
}

- (CGFloat)bottomSpaceRatio
{
  return 1 - [self topSpaceRatio];
}

- (CGFloat)topSpaceHeight
{
  return MAX(10, [self restSpace] * [self topSpaceRatio]);
}

- (CGFloat)bottomSpaceHeight
{
  return MAX(10, [self restSpace] * [self bottomSpaceRatio]);
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  if (indexPath.section == SectionMenu)
    return [SideToolbarCell cellHeight];
  else if (indexPath.section == SectionTopSpace)
    return [self topSpaceHeight];
  else if (indexPath.section == SectionBottomSpace)
    return [self bottomSpaceHeight];
  else if (indexPath.section == SectionBuyButton)
    return [BuyButtonCell cellHeight];
  return 0;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  if (indexPath.section == SectionMenu)
  {
    [self.delegate sideToolbar:self didPressButtonAtIndex:indexPath.row];
    [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
  }
}

- (void)layoutSubviews
{
  NSTimeInterval rotationDuration = 0.3;

  if (self.isMenuHidden)
    self.hidden = YES;
  [UIView animateWithDuration:rotationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
    self.menuShift = self.isMenuHidden ? self.minimumMenuShift : self.maximumMenuShift;
  } completion:^(BOOL finished) {
    self.hidden = NO;
  }];
  CGFloat contentHeight = [self topSpaceHeight] + [SideToolbarCell cellHeight] * [menuTitles count] + [self bottomSpaceHeight] + [BuyButtonCell cellHeight];
  self.tableView.scrollEnabled = contentHeight > self.tableView.height;
  NSMutableIndexSet * indexSet = [[NSMutableIndexSet alloc] init];
  [indexSet addIndex:SectionTopSpace];
  [indexSet addIndex:SectionBottomSpace];
  [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

  for (CALayer * backgroundLayer in self.backgroundView.layer.sublayers)
  {
    NSTimeInterval delay = backgroundLayer.frame.size.height > self.height ? rotationDuration : 0;
    [self performAfterDelay:delay block:^{
      CGRect rect = backgroundLayer.frame;
      rect.size.height = self.height;
      backgroundLayer.frame = rect;
    }];
  }
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)slidePanGesture:(UIPanGestureRecognizer *)sender
{
  [self panGesture:sender];
}

- (void)menuPanGesture:(UIPanGestureRecognizer *)sender
{
  [self panGesture:sender];
}

- (void)panGesture:(UIPanGestureRecognizer *)sender
{
  self.menuShift -= [sender translationInView:self.superview].x;<commit_msg>[ios] SideToolbar first rotation glitch fix<commit_after>
#import "SideToolbar.h"
#import "SideToolbarCell.h"
#import "UIKitCategories.h"
#import "BuyButtonCell.h"
#include "../../platform/platform.hpp"

typedef NS_ENUM(NSUInteger, Section)
{
  SectionTopSpace,
  SectionMenu,
  SectionBottomSpace,
  SectionBuyButton,
  SectionCount
};

@interface SideToolbar () <UITableViewDataSource, UITableViewDelegate, BuyButtonCellDelegate>

@property (nonatomic) UITableView * tableView;
@property (nonatomic) UIPanGestureRecognizer * slidePanGesture;
@property (nonatomic) UIPanGestureRecognizer * menuPanGesture;
@property (nonatomic) UIButton * buyButton;
@property (nonatomic) UIView * backgroundView;

@property (nonatomic) BOOL isMenuHidden;

@end

@implementation SideToolbar
{
  NSArray * menuTitles;
  NSArray * menuImageNames;
  NSArray * disabledInTrial;
  CGPoint slideViewOffset;
}

- (id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];

  menuTitles = @[NSLocalizedString(@"search", nil),
                 NSLocalizedString(@"maps", nil),
                 NSLocalizedString(@"bookmarks", nil),
                 NSLocalizedString(@"settings", nil),
                 NSLocalizedString(@"share_my_location", nil)];

  menuImageNames = @[@"side-toolbar-icon-search",
                     @"side-toolbar-icon-map",
                     @"side-toolbar-icon-bookmarks",
                     @"side-toolbar-icon-settings",
                     @"side-toolbar-icon-share"];

  disabledInTrial = @[@YES, @NO, @YES, @NO, @NO, @NO];

  self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin;
  [self addGestureRecognizer:self.menuPanGesture];

  [self addSubview:self.backgroundView];
  [self addSubview:self.tableView];

  return self;
}

- (void)buyButtonCellDidPressBuyButton:(BuyButtonCell *)cell
{
  [self.delegate sideToolbarDidPressBuyButton:self];
}

#pragma mark - TableView

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  if (section == SectionMenu)
    return [menuTitles count];
  else
    return 1;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
  return SectionCount;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  UITableViewCell * cell = nil;
  if (indexPath.section == SectionMenu)
  {
    cell = [tableView dequeueReusableCellWithIdentifier:@"MenuCell"];
    SideToolbarCell * customCell = (SideToolbarCell *)cell;
    if (!customCell)
      customCell = [[SideToolbarCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MenuCell"];

    if (GetPlatform().IsPro())
      customCell.disabled = NO;
    else
      customCell.disabled = [disabledInTrial[indexPath.row] boolValue];

    customCell.iconImageView.image = [UIImage imageNamed:menuImageNames[indexPath.row]];
    customCell.titleLabel.text = menuTitles[indexPath.row];

    cell = customCell;
  }
  else if (indexPath.section == SectionTopSpace || indexPath.section == SectionBottomSpace)
  {
    cell = [tableView dequeueReusableCellWithIdentifier:@"SpaceCell"];
    if (!cell)
    {
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SpaceCell"];
      cell.backgroundColor = [UIColor clearColor];
      cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
  }
  else if (indexPath.section == SectionBuyButton)
  {
    BuyButtonCell * customCell = (BuyButtonCell *)[tableView dequeueReusableCellWithIdentifier:@"BuyButtonCell"];
    if (!customCell)
    {
      customCell = [[BuyButtonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BuyButtonCell"];
      customCell.delegate = self;
    }
    cell = customCell;
  }

  return cell;
}

- (CGFloat)restSpace
{
  return self.height - [SideToolbarCell cellHeight] * [menuTitles count] - [BuyButtonCell cellHeight];
}

- (CGFloat)topSpaceRatio
{
  return IPAD ? 0.7 : 0.65;
}

- (CGFloat)bottomSpaceRatio
{
  return 1 - [self topSpaceRatio];
}

- (CGFloat)topSpaceHeight
{
  return MAX(10, [self restSpace] * [self topSpaceRatio]);
}

- (CGFloat)bottomSpaceHeight
{
  return MAX(10, [self restSpace] * [self bottomSpaceRatio]);
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  if (indexPath.section == SectionMenu)
    return [SideToolbarCell cellHeight];
  else if (indexPath.section == SectionTopSpace)
    return [self topSpaceHeight];
  else if (indexPath.section == SectionBottomSpace)
    return [self bottomSpaceHeight];
  else if (indexPath.section == SectionBuyButton)
    return [BuyButtonCell cellHeight];
  return 0;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  if (indexPath.section == SectionMenu)
  {
    [self.delegate sideToolbar:self didPressButtonAtIndex:indexPath.row];
    [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
  }
}

- (void)layoutSubviews
{
  NSTimeInterval rotationDuration = 0.3;

  if (self.isMenuHidden)
    self.hidden = YES;
  [UIView animateWithDuration:rotationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
    self.menuShift = self.isMenuHidden ? self.minimumMenuShift : self.maximumMenuShift;
  } completion:^(BOOL finished) {
    self.hidden = NO;
  }];
  CGFloat contentHeight = [self topSpaceHeight] + [SideToolbarCell cellHeight] * [menuTitles count] + [self bottomSpaceHeight] + [BuyButtonCell cellHeight];
  self.tableView.scrollEnabled = contentHeight > self.tableView.height;
  NSMutableIndexSet * indexSet = [[NSMutableIndexSet alloc] init];
  [indexSet addIndex:SectionTopSpace];
  [indexSet addIndex:SectionBottomSpace];
  [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationTop];

  for (CALayer * backgroundLayer in self.backgroundView.layer.sublayers)
  {
    NSTimeInterval delay = backgroundLayer.frame.size.height > self.height ? rotationDuration : 0;
    [self performAfterDelay:delay block:^{
      CGRect frame = backgroundLayer.frame;
      frame.size.height = self.height;
      backgroundLayer.frame = frame;
    }];
  }
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)slidePanGesture:(UIPanGestureRecognizer *)sender
{
  [self panGesture:sender];
}

- (void)menuPanGesture:(UIPanGestureRecognizer *)sender
{
  [self panGesture:sender];
}

- (void)panGesture:(UIPanGestureRecognizer *)sender
{
  self.menuShift -= [sender translationInView:self.superview].x;
{'fraction_non_alphanumeric': 0.11731719914410094, 'fraction_numerical': 0.002361100863277503, 'mean_word_length': 4.837209302325581, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '816809', 'n_tokens_mistral': 4467, 'n_tokens_neox': 4139, 'n_words': 766}