Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/Folium-iOS/Structures/LayoutManager.swift
2 views
//
//  LayoutManager.swift
//  Folium-iOS
//
//  Created by Jarrod Norwell on 15/7/2025.
//

import UIKit

struct LayoutManager {
    static let shared: LayoutManager = LayoutManager()
    
    var list: UICollectionViewCompositionalLayout {
        var configuration: UICollectionLayoutListConfiguration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
        configuration.headerMode = .supplementary
        return UICollectionViewCompositionalLayout.list(using: configuration)
    }
    
    var filter: UICollectionViewCompositionalLayout {
        .init { sectionIndex, layoutEnvironment in
            let item: NSCollectionLayoutItem = .init(layoutSize: .init(widthDimension: .estimated(100), heightDimension: .estimated(100)))
            
            let group: NSCollectionLayoutGroup = .horizontal(layoutSize: .init(widthDimension: .estimated(100), heightDimension: .estimated(100)), subitems: [item])
            group.interItemSpacing = .fixed(16)
            
            let section: NSCollectionLayoutSection = .init(group: group)
            section.orthogonalScrollingBehavior = .continuous
            section.contentInsets = .init(top: 0, leading: 20, bottom: 0, trailing: 20)
            section.interGroupSpacing = 16
            return section
        }
    }
    
    var multiplayer: UICollectionViewCompositionalLayout {
        let configuration = UICollectionViewCompositionalLayoutConfiguration()
        configuration.interSectionSpacing = 20
        
        return .init(sectionProvider: { sectionIndex, layoutEnvironment in
            let item: NSCollectionLayoutItem = .init(layoutSize: .init(widthDimension: .fractionalWidth(1),
                                                                       heightDimension: .estimated(300)))
            
            let group: NSCollectionLayoutGroup = .horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1),
                                                                               heightDimension: .estimated(300)),
                                                             subitems: [item])
            group.interItemSpacing = .fixed(20)
            
            let header: NSCollectionLayoutBoundarySupplementaryItem = .init(layoutSize: .init(widthDimension: .fractionalWidth(1),
                                                                                              heightDimension: .estimated(44)),
                                                                            elementKind: UICollectionView.elementKindSectionHeader,
                                                                            alignment: .top)
            header.pinToVisibleBounds = true
            
            let section: NSCollectionLayoutSection = .init(group: group)
            section.boundarySupplementaryItems = [header]
            section.contentInsets = .init(top: 0, leading: 20, bottom: 0, trailing: 20)
            section.interGroupSpacing = 20
            return section
        }, configuration: configuration)
    }
    
    var library: UICollectionViewCompositionalLayout {
        let configuration: UICollectionViewCompositionalLayoutConfiguration = .init()
        configuration.interSectionSpacing = 20
        
        return .init(sectionProvider: { sectionIndex, layoutEnvironment in
            switch UIDevice.current.userInterfaceIdiom {
            case .pad: iPadLibrary(layoutEnvironment, sectionIndex)
            case .phone: iPhoneLibrary(layoutEnvironment, sectionIndex)
            default:
                nil
            }
        }, configuration: configuration)
    }
    
    func iPadLibrary(_ layoutEnvironment: NSCollectionLayoutEnvironment, _ sectionIndex: Int) -> NSCollectionLayoutSection? {
        let itemCount: Int = layoutEnvironment.container.effectiveContentSize.width < UIScreen.main.bounds.height ? 4 : 5
        
        let item: NSCollectionLayoutItem = .init(layoutSize: .init(widthDimension: .fractionalWidth(1 / .init(itemCount)), heightDimension: .estimated(300)))
        
        let group: NSCollectionLayoutGroup = .horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(300)), repeatingSubitem: item, count: itemCount)
        group.interItemSpacing = .fixed(20)
        
        let header: NSCollectionLayoutBoundarySupplementaryItem = .init(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(44)),
                                                                        elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
        header.pinToVisibleBounds = true
        
        let section: NSCollectionLayoutSection = .init(group: group)
        section.boundarySupplementaryItems = [header]
        section.contentInsets = .init(top: 10, leading: 20, bottom: 0, trailing: 20)
        section.interGroupSpacing = 20
        
        return section
    }
    
    func iPhoneLibrary(_ layoutEnvironment: NSCollectionLayoutEnvironment, _ sectionIndex: Int) -> NSCollectionLayoutSection? {
        let itemCount: Int = layoutEnvironment.container.effectiveContentSize.width < UIScreen.main.bounds.height ? 2 : 4
        
        let item: NSCollectionLayoutItem = .init(layoutSize: .init(widthDimension: .fractionalWidth(1 / .init(itemCount)), heightDimension: .estimated(300)))
        
        let group: NSCollectionLayoutGroup = .horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(300)), repeatingSubitem: item, count: itemCount)
        group.interItemSpacing = .fixed(20)
        
        let header: NSCollectionLayoutBoundarySupplementaryItem = .init(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(44)),
                                                                        elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
        header.pinToVisibleBounds = true
        
        let section: NSCollectionLayoutSection = .init(group: group)
        section.boundarySupplementaryItems = [header]
        section.contentInsets = .init(top: 10, leading: 20, bottom: 0, trailing: 20)
        section.interGroupSpacing = 20
        
        return section
    }
}