Fix Open on link for ERC721 tokens sourced from OpenSea don't do anything when tapped

pull/1590/head
Hwee-Boon Yar 5 years ago
parent 0e4d482f37
commit b4fb114d4a
  1. 41
      AlphaWallet/Tokens/ViewControllers/TokenInstanceViewController.swift
  2. 9
      AlphaWallet/Tokens/Views/BaseTokenCardTableViewCell.swift
  3. 41
      AlphaWallet/Tokens/Views/OpenSea/OpenSeaNonFungibleTokenCardRowView.swift
  4. 3
      AlphaWallet/UI/Views/TokenCardRowView.swift
  5. 1
      AlphaWallet/UI/Views/TokenCardRowViewProtocol.swift

@ -24,6 +24,7 @@ class TokenInstanceViewController: UIViewController, TokenVerifiableStatusViewCo
//TODO single row. Don't use table anymore //TODO single row. Don't use table anymore
private let tableView = UITableView(frame: .zero, style: .plain) private let tableView = UITableView(frame: .zero, style: .plain)
private let buttonsBar = ButtonsBar(numberOfButtons: 3) private let buttonsBar = ButtonsBar(numberOfButtons: 3)
private let cellForSizing = TokenCardTableViewCellWithoutCheckbox()
var tokenHolder: TokenHolder { var tokenHolder: TokenHolder {
return viewModel.tokenHolder return viewModel.tokenHolder
@ -208,8 +209,34 @@ extension TokenInstanceViewController: UITableViewDelegate, UITableViewDataSourc
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: tokenObject, assetDefinitionStore: assetDefinitionStore, tokenViewType: .view)
let cell = tableView.dequeueReusableCell(withIdentifier: TokenCardTableViewCellWithoutCheckbox.identifier, for: indexPath) as! TokenCardTableViewCellWithoutCheckbox let cell = tableView.dequeueReusableCell(withIdentifier: TokenCardTableViewCellWithoutCheckbox.identifier, for: indexPath) as! TokenCardTableViewCellWithoutCheckbox
configure(cell: cell)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//We don't allow user to toggle (despite it not doing anything) for non-opensea-backed tokens because it will cause TokenScript views to flash as they have to be re-rendered
switch OpenSeaBackedNonFungibleTokenHandling(token: viewModel.token, assetDefinitionStore: assetDefinitionStore, tokenViewType: .viewIconified) {
case .backedByOpenSea:
viewModel.toggleSelection(for: indexPath)
configure()
case .notBackedByOpenSea:
break
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
configure(cell: cellForSizing)
let size = cellForSizing.systemLayoutSizeFitting(UIView.layoutFittingExpandedSize)
if let rowView = cellForSizing.rowView {
return size.height + rowView.additionalHeightToCompensateForAutoLayout
} else {
return size.height
}
}
private func configure(cell: TokenCardTableViewCellWithoutCheckbox) {
let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: tokenObject, assetDefinitionStore: assetDefinitionStore, tokenViewType: .view)
let rowView: TokenCardRowViewProtocol & UIView let rowView: TokenCardRowViewProtocol & UIView
switch tokenType { switch tokenType {
case .backedByOpenSea: case .backedByOpenSea:
@ -224,18 +251,6 @@ extension TokenInstanceViewController: UITableViewDelegate, UITableViewDataSourc
cell.delegate = self cell.delegate = self
cell.rowView = rowView cell.rowView = rowView
cell.configure(viewModel: .init(tokenHolder: viewModel.tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .view), assetDefinitionStore: assetDefinitionStore) cell.configure(viewModel: .init(tokenHolder: viewModel.tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .view), assetDefinitionStore: assetDefinitionStore)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//We don't allow user to toggle (despite it not doing anything) for non-opensea-backed tokens because it will cause TokenScript views to flash as they have to be re-rendered
switch OpenSeaBackedNonFungibleTokenHandling(token: viewModel.token, assetDefinitionStore: assetDefinitionStore, tokenViewType: .viewIconified) {
case .backedByOpenSea:
viewModel.toggleSelection(for: indexPath)
configure()
case .notBackedByOpenSea:
break
}
} }
} }

@ -89,18 +89,11 @@ class BaseTokenCardTableViewCell: UITableViewCell {
rowView.translatesAutoresizingMaskIntoConstraints = false rowView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(rowView) contentView.addSubview(rowView)
//Needs to for expanded view to be laid out with correct height, but cell might be too short
let getExpandedHeightCorrectConstraint = rowView.bottomAnchor.constraint(greaterThanOrEqualTo: contentView.bottomAnchor, constant: -GroupedTable.Metric.cellSeparatorHeight)
//Gets cell height correct, compensating the constraint above
let getCellHeightCorrectConstraint = rowView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -GroupedTable.Metric.cellSeparatorHeight)
getCellHeightCorrectConstraint.priority = .fittingSizeLevel
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
rowView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), rowView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
rowView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), rowView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
rowView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: GroupedTable.Metric.cellSpacing + GroupedTable.Metric.cellSeparatorHeight), rowView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: GroupedTable.Metric.cellSpacing + GroupedTable.Metric.cellSeparatorHeight),
getExpandedHeightCorrectConstraint, rowView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -GroupedTable.Metric.cellSeparatorHeight)
getCellHeightCorrectConstraint,
]) ])
} }
} }

@ -8,6 +8,9 @@ protocol OpenSeaNonFungibleTokenCardRowViewDelegate: class {
} }
class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol { class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
private static let xMargin = CGFloat(7)
private static let yMargin = CGFloat(5)
private let mainVerticalStackView: UIStackView = [].asStackView(axis: .vertical, contentHuggingPriority: .required) private let mainVerticalStackView: UIStackView = [].asStackView(axis: .vertical, contentHuggingPriority: .required)
private let thumbnailImageView = UIImageView() private let thumbnailImageView = UIImageView()
private let bigImageBackground = UIView() private let bigImageBackground = UIView()
@ -92,6 +95,14 @@ class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
private var currentDisplayedImageUrl: URL? private var currentDisplayedImageUrl: URL?
private var checkboxRelatedConstraintsWhenShown = [NSLayoutConstraint]() private var checkboxRelatedConstraintsWhenShown = [NSLayoutConstraint]()
private var checkboxRelatedConstraintsWhenHidden = [NSLayoutConstraint]() private var checkboxRelatedConstraintsWhenHidden = [NSLayoutConstraint]()
//Hackish: To get the width of the descriptionLabel in order to calculate the correct height
private var descriptionLabelWidth: CGFloat {
if let fullWidth = viewModel?.width {
return fullWidth - OpenSeaNonFungibleTokenCardRowView.xMargin * 2 - outerHorizontalMargin
} else {
return 0
}
}
var background = UIView() var background = UIView()
var stateLabel = UILabel() var stateLabel = UILabel()
@ -108,6 +119,17 @@ class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
} }
} }
} }
var additionalHeightToCompensateForAutoLayout: CGFloat {
guard let attributedText = descriptionLabel.attributedText else { return 0 }
let rect = attributedText.boundingRect(with: .init(width: descriptionLabelWidth, height: 1000), options: .usesLineFragmentOrigin, context: nil)
let size = rect.size
//Hackish: Add a bit of allowance. Otherwise it's good for CryptoKitties, but there's no enough space for Chibi Fighters' title
if size.height > 0 {
return size.height + 10
} else {
return 0
}
}
//Just to adhere to protocol //Just to adhere to protocol
var areDetailsVisible = false var areDetailsVisible = false
@ -165,8 +187,10 @@ class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
generationStackView, generationStackView,
cooldownStackView cooldownStackView
]) ])
titleLabel.setContentCompressionResistancePriority(.required, for: .vertical)
descriptionLabel.setContentCompressionResistancePriority(.required, for: .vertical)
let col0 = [ let col0: UIStackView = [
spacers.aboveTitle, spacers.aboveTitle,
stateLabel, stateLabel,
spacers.belowState, spacers.belowState,
@ -213,11 +237,9 @@ class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
background.addSubview(mainVerticalStackView) background.addSubview(mainVerticalStackView)
// TODO extract constant. Maybe StyleLayout.sideMargin // TODO extract constant. Maybe StyleLayout.sideMargin
let xMargin = CGFloat(7) checkboxRelatedConstraintsWhenShown.append(checkboxImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: OpenSeaNonFungibleTokenCardRowView.xMargin))
let yMargin = CGFloat(5)
checkboxRelatedConstraintsWhenShown.append(checkboxImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: xMargin))
checkboxRelatedConstraintsWhenShown.append(checkboxImageView.centerYAnchor.constraint(equalTo: centerYAnchor)) checkboxRelatedConstraintsWhenShown.append(checkboxImageView.centerYAnchor.constraint(equalTo: centerYAnchor))
checkboxRelatedConstraintsWhenShown.append(background.leadingAnchor.constraint(equalTo: checkboxImageView.trailingAnchor, constant: xMargin)) checkboxRelatedConstraintsWhenShown.append(background.leadingAnchor.constraint(equalTo: checkboxImageView.trailingAnchor, constant: OpenSeaNonFungibleTokenCardRowView.xMargin))
if ScreenChecker().isNarrowScreen { if ScreenChecker().isNarrowScreen {
checkboxRelatedConstraintsWhenShown.append(checkboxImageView.widthAnchor.constraint(equalToConstant: 20)) checkboxRelatedConstraintsWhenShown.append(checkboxImageView.widthAnchor.constraint(equalToConstant: 20))
checkboxRelatedConstraintsWhenShown.append(checkboxImageView.heightAnchor.constraint(equalToConstant: 20)) checkboxRelatedConstraintsWhenShown.append(checkboxImageView.heightAnchor.constraint(equalToConstant: 20))
@ -226,7 +248,7 @@ class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
checkboxRelatedConstraintsWhenShown.append(checkboxImageView.widthAnchor.constraint(equalToConstant: 28)) checkboxRelatedConstraintsWhenShown.append(checkboxImageView.widthAnchor.constraint(equalToConstant: 28))
checkboxRelatedConstraintsWhenShown.append(checkboxImageView.heightAnchor.constraint(equalToConstant: 28)) checkboxRelatedConstraintsWhenShown.append(checkboxImageView.heightAnchor.constraint(equalToConstant: 28))
} }
checkboxRelatedConstraintsWhenHidden.append(background.leadingAnchor.constraint(equalTo: leadingAnchor, constant: xMargin)) checkboxRelatedConstraintsWhenHidden.append(background.leadingAnchor.constraint(equalTo: leadingAnchor, constant: OpenSeaNonFungibleTokenCardRowView.xMargin))
if showCheckbox { if showCheckbox {
NSLayoutConstraint.activate(checkboxRelatedConstraintsWhenShown) NSLayoutConstraint.activate(checkboxRelatedConstraintsWhenShown)
} else { } else {
@ -261,9 +283,9 @@ class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
mainVerticalStackView.anchorsConstraint(to: background, edgeInsets: .init(top: marginForBigImageView, left: 0, bottom: 0, right: 0)), mainVerticalStackView.anchorsConstraint(to: background, edgeInsets: .init(top: marginForBigImageView, left: 0, bottom: 0, right: 0)),
background.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -xMargin), background.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -OpenSeaNonFungibleTokenCardRowView.xMargin),
background.topAnchor.constraint(equalTo: topAnchor, constant: yMargin), background.topAnchor.constraint(equalTo: topAnchor, constant: OpenSeaNonFungibleTokenCardRowView.yMargin),
background.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -yMargin), background.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -OpenSeaNonFungibleTokenCardRowView.yMargin),
stateLabel.heightAnchor.constraint(equalToConstant: 22), stateLabel.heightAnchor.constraint(equalToConstant: 22),
@ -436,6 +458,7 @@ class OpenSeaNonFungibleTokenCardRowView: UIView, TokenCardRowViewProtocol {
descriptionLabel.attributedText = viewModel.descriptionWithoutConvertingHtml descriptionLabel.attributedText = viewModel.descriptionWithoutConvertingHtml
} }
} }
descriptionLabel.preferredMaxLayoutWidth = descriptionLabelWidth
titleLabel.text = viewModel.title titleLabel.text = viewModel.title

@ -68,6 +68,9 @@ class TokenCardRowView: UIView, TokenCardRowViewProtocol {
detailsRowStack?.isHidden = !areDetailsVisible detailsRowStack?.isHidden = !areDetailsVisible
} }
} }
var additionalHeightToCompensateForAutoLayout: CGFloat {
return 0
}
init(server: RPCServer, tokenView: TokenView, showCheckbox: Bool = false, assetDefinitionStore: AssetDefinitionStore) { init(server: RPCServer, tokenView: TokenView, showCheckbox: Bool = false, assetDefinitionStore: AssetDefinitionStore) {
self.server = server self.server = server

@ -9,6 +9,7 @@ protocol TokenCardRowViewProtocol {
var tokenView: TokenView { get set } var tokenView: TokenView { get set }
var showCheckbox: Bool { get set } var showCheckbox: Bool { get set }
var areDetailsVisible: Bool { get set } var areDetailsVisible: Bool { get set }
var additionalHeightToCompensateForAutoLayout: CGFloat { get }
func configure(tokenHolder: TokenHolder, tokenView: TokenView, areDetailsVisible: Bool, width: CGFloat, assetDefinitionStore: AssetDefinitionStore) func configure(tokenHolder: TokenHolder, tokenView: TokenView, areDetailsVisible: Bool, width: CGFloat, assetDefinitionStore: AssetDefinitionStore)
} }

Loading…
Cancel
Save