diff --git a/.gitignore b/.gitignore index 330d167..5466cb2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore +.DS_Store + ## User settings xcuserdata/ diff --git a/backend/database.json b/backend/database.json new file mode 100644 index 0000000..2e937ba --- /dev/null +++ b/backend/database.json @@ -0,0 +1,126 @@ +{ + "now_showing": [ + { + "name": "The AB Cafe", + "band": "X Band", + "latitude": -6.175110, + "longitude": 106.865036, + "start_time": 1594218718, + "end_time": 1594233118, + "registered": 0 + }, + { + "name": "123 Venue", + "band": "X Band", + "latitude": -6.162945, + "longitude": 106.866098, + "start_time": 1594218718, + "end_time": 1594233118, + "registered": 1 + }, + { + "name": "ABC Cafe", + "band": "X Band", + "latitude": -6.161644, + "longitude": 106.875944, + "start_time": 1594301518, + "end_time": 1594305118, + "registered": 0 + }, + { + "name": "The 123 Cafe", + "band": "X Band", + "latitude": -6.161644, + "longitude": 106.875944, + "start_time": 1594294318, + "end_time": 1594297918, + "registered": 0 + } + ], + "video": { + "Rock": [ + { + "name": "My New Song", + "musician": "TheBee Band" + } + ], + "Punk": [ + { + "name": "This time", + "musician": "ABand" + } + ] + }, + "musician": { + "soloist": [ + { + "id": 1, + "name": "artist" + }, + { + "id": 2, + "name": "Brandon George" + }, + { + "id": 3, + "name": "Livia Gouse" + }, + { + "id": 4, + "name": "Terry" + }, + { + "id": 5, + "name": "Carla" + }, + { + "id": 6, + "name": "Charlie" + } + ] + }, + "user": [ + { + "id": 1, + "email": "artist@artist.com", + "password": "asdasdad", + "role": "musician" + }, + { + "id": 2, + "email": "brandon@george.com", + "password": "123123", + "role": "Guitarist" + }, + { + "id": 3, + "email": "livia@gouse.com", + "password": "qweqwe", + "role": "Vocalist" + }, + { + "id": 4, + "email": "terry@asd.com", + "password": "zxczxc", + "role": "Vocalist" + }, + { + "id": 5, + "email": "carla@123.com", + "password": "poipoi", + "role": "Guitarist" + }, + { + "id": 6, + "email": "charlie@zxc.com", + "password": "098098", + "role": "Violin" + }, + { + "id": 3, + "email": "livia@gouse.com", + "password": "qweqwe", + "role": "Vocalist" + } + ] +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3.xcodeproj/project.pbxproj b/frontend/mobile/CommunityMC3.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d00be53 --- /dev/null +++ b/frontend/mobile/CommunityMC3.xcodeproj/project.pbxproj @@ -0,0 +1,2045 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 79E4D2F6736D4B440235FF24 /* Pods_CommunityMC3Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53088E5DFD64AC02E18FE20F /* Pods_CommunityMC3Tests.framework */; }; + A11A9FE724C94A58008D7867 /* albumListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A9FD624C94A58008D7867 /* albumListTableViewCell.swift */; }; + A11A9FE824C94A58008D7867 /* albumTitleTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A11A9FD724C94A58008D7867 /* albumTitleTableViewCell.xib */; }; + A11A9FE924C94A58008D7867 /* albumTitleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A9FD824C94A58008D7867 /* albumTitleTableViewCell.swift */; }; + A11A9FEA24C94A58008D7867 /* albumListTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A11A9FD924C94A58008D7867 /* albumListTableViewCell.xib */; }; + A11A9FEB24C94A58008D7867 /* UploadFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A9FDA24C94A58008D7867 /* UploadFileView.swift */; }; + A11A9FEC24C94A58008D7867 /* GenreTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A9FDC24C94A58008D7867 /* GenreTableViewCell.swift */; }; + A11A9FED24C94A58008D7867 /* GenreTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A11A9FDD24C94A58008D7867 /* GenreTableViewCell.xib */; }; + A11A9FEE24C94A58008D7867 /* descTitleTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A11A9FDF24C94A58008D7867 /* descTitleTableViewCell.xib */; }; + A11A9FEF24C94A58008D7867 /* descTitleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A9FE024C94A58008D7867 /* descTitleTableViewCell.swift */; }; + A11A9FF024C94A58008D7867 /* UploadFileView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A11A9FE124C94A58008D7867 /* UploadFileView.storyboard */; }; + A11A9FF124C94A58008D7867 /* UploadTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A9FE324C94A58008D7867 /* UploadTableViewCell.swift */; }; + A11A9FF224C94A58008D7867 /* UploadTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A11A9FE424C94A58008D7867 /* UploadTableViewCell.xib */; }; + A11A9FF324C94A58008D7867 /* AddCoverTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A9FE524C94A58008D7867 /* AddCoverTableViewCell.swift */; }; + A11A9FF424C94A58008D7867 /* AddCoverTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A11A9FE624C94A58008D7867 /* AddCoverTableViewCell.xib */; }; + A121CE9E24C96C6D00E1D48B /* SmallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A121CE9C24C96C6D00E1D48B /* SmallViewController.swift */; }; + A121CE9F24C96C6D00E1D48B /* SmallViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A121CE9D24C96C6D00E1D48B /* SmallViewController.storyboard */; }; + A124876724CD0BE400030723 /* SelectViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A124876924CD0BE400030723 /* SelectViewCell.xib */; }; + A124876A24CD0BEE00030723 /* SelectFileView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A124876C24CD0BEE00030723 /* SelectFileView.storyboard */; }; + A124877324CD2AC500030723 /* MainTabController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A124877224CD2AC500030723 /* MainTabController.swift */; }; + A125311E24CE89C30038B215 /* UIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A125311D24CE89C30038B215 /* UIImageExtension.swift */; }; + A12F370424D23C02002F31E0 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12F370324D23C02002F31E0 /* Utilities.swift */; }; + A134D29E24C8EA41009A054F /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D29D24C8EA41009A054F /* FileManager.swift */; }; + A134D2A024C907B4009A054F /* Featured+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D29F24C907B4009A054F /* Featured+Extension.swift */; }; + A134D2A324C908F3009A054F /* Album+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D2A224C908F3009A054F /* Album+Extension.swift */; }; + A134D2A524C91B99009A054F /* Favourites+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D2A424C91B99009A054F /* Favourites+Extension.swift */; }; + A134D2A724C91BAB009A054F /* Photos+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D2A624C91BAB009A054F /* Photos+Extension.swift */; }; + A134D2A924C91BBC009A054F /* Track+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D2A824C91BBC009A054F /* Track+Extension.swift */; }; + A134D2AB24C91BC9009A054F /* UploadedData+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D2AA24C91BC9009A054F /* UploadedData+Extension.swift */; }; + A134D2AD24C91BD4009A054F /* UserData+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D2AC24C91BD4009A054F /* UserData+Extension.swift */; }; + A134D2AF24C91BDB009A054F /* Videos+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A134D2AE24C91BDB009A054F /* Videos+Extension.swift */; }; + A136C2A324D9CADA0078F37E /* GenreProfileCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A136C2A124D9CADA0078F37E /* GenreProfileCollectionViewCell.swift */; }; + A136C2A424D9CADA0078F37E /* GenreProfileCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A136C2A224D9CADA0078F37E /* GenreProfileCollectionViewCell.xib */; }; + A136C2A624D9CE5F0078F37E /* GenreProfileController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A136C2A524D9CE5F0078F37E /* GenreProfileController.swift */; }; + A136C2AA24D9D9BB0078F37E /* SwitchAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A136C2A824D9D9BB0078F37E /* SwitchAccountTableViewCell.swift */; }; + A136C2AB24D9D9BB0078F37E /* SwitchAccountTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A136C2A924D9D9BB0078F37E /* SwitchAccountTableViewCell.xib */; }; + A136C2AE24D9DA100078F37E /* AddAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A136C2AC24D9DA100078F37E /* AddAccountTableViewCell.swift */; }; + A136C2AF24D9DA100078F37E /* AddAccountTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A136C2AD24D9DA100078F37E /* AddAccountTableViewCell.xib */; }; + A136C2B124D9DA4A0078F37E /* AccountController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A136C2B024D9DA4A0078F37E /* AccountController.swift */; }; + A1432F5524C69958007656B1 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1432F5424C69958007656B1 /* ImagePicker.swift */; }; + A14B626324D09B8A0015223C /* Favourites.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A14B626224D09B890015223C /* Favourites.storyboard */; }; + A14B626524D09B910015223C /* FavouritesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A14B626424D09B910015223C /* FavouritesView.swift */; }; + A14B626824D0D3830015223C /* CloudKitUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = A14B626724D0D3830015223C /* CloudKitUtil.swift */; }; + A1503D3A24C4B79900AE317E /* LoginScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1503D3924C4B79900AE317E /* LoginScreen.storyboard */; }; + A1503D3C24C4BA9B00AE317E /* LoginController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1503D3B24C4BA9B00AE317E /* LoginController.swift */; }; + A15C4D1024C502EF00ED0C0E /* Search.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A15C4D0F24C502EF00ED0C0E /* Search.storyboard */; }; + A15C4D1924C5038C00ED0C0E /* DB_Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = A15C4D1724C5038C00ED0C0E /* DB_Model.xcdatamodeld */; }; + A15C4D1B24C5300A00ED0C0E /* Explorer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A15C4D1A24C5300A00ED0C0E /* Explorer.storyboard */; }; + A15C4D2224C5367400ED0C0E /* TrendingNowCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15C4D2024C5367400ED0C0E /* TrendingNowCell.swift */; }; + A15C4D2324C5367400ED0C0E /* TrendingNowCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A15C4D2124C5367400ED0C0E /* TrendingNowCell.xib */; }; + A15C4D2624C5370C00ED0C0E /* HeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15C4D2424C5370C00ED0C0E /* HeaderCell.swift */; }; + A15C4D2724C5370C00ED0C0E /* HeaderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A15C4D2524C5370C00ED0C0E /* HeaderCell.xib */; }; + A15C4D2E24C543B100ED0C0E /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A15C4D2D24C543B100ED0C0E /* CloudKit.framework */; }; + A165069024C7DCE4005822E7 /* RegisterController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A165068F24C7DCE4005822E7 /* RegisterController.swift */; }; + A165069224C7DD46005822E7 /* SettingScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A165069124C7DD46005822E7 /* SettingScreen.storyboard */; }; + A1689CEB24C7A6D300A49732 /* SelectFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1689CEA24C7A6D300A49732 /* SelectFileView.swift */; }; + A1689D3424C7B14000A49732 /* SelectViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1689D3224C7B14000A49732 /* SelectViewCell.swift */; }; + A1689D3724C7B5F200A49732 /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1689D3624C7B5F200A49732 /* DataManager.swift */; }; + A1689D3924C7D67700A49732 /* AlertViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1689D3824C7D67700A49732 /* AlertViewHelper.swift */; }; + A1689D3B24C7D76500A49732 /* CoreDataHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1689D3A24C7D76500A49732 /* CoreDataHelper.swift */; }; + A169E8A624CA9226000D815F /* UploadController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A169E8A524CA9226000D815F /* UploadController.swift */; }; + A16B44A324B2FBF300053D6C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A16B44A224B2FBF300053D6C /* AppDelegate.swift */; }; + A16B44A524B2FBF300053D6C /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A16B44A424B2FBF300053D6C /* SceneDelegate.swift */; }; + A16B44A724B2FBF300053D6C /* ExplorerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A16B44A624B2FBF300053D6C /* ExplorerView.swift */; }; + A16B44A924B2FBF300053D6C /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A16B44A824B2FBF300053D6C /* SearchView.swift */; }; + A16B44AC24B2FBF300053D6C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A16B44AA24B2FBF300053D6C /* Main.storyboard */; }; + A16B44AE24B2FBF600053D6C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A16B44AD24B2FBF600053D6C /* Assets.xcassets */; }; + A16B44B124B2FBF600053D6C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A16B44AF24B2FBF600053D6C /* LaunchScreen.storyboard */; }; + A16B44BC24B2FBF700053D6C /* CommunityMC3Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A16B44BB24B2FBF700053D6C /* CommunityMC3Tests.swift */; }; + A16B44C724B2FBF700053D6C /* CommunityMC3UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A16B44C624B2FBF700053D6C /* CommunityMC3UITests.swift */; }; + A17C3C6924CCA3C500153493 /* Constant.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17C3C6824CCA3C500153493 /* Constant.swift */; }; + A1824D9A24C7E3E200C68182 /* Account+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1824D9924C7E3E200C68182 /* Account+Extension.swift */; }; + A1824D9C24C7E45600C68182 /* UIViewControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1824D9B24C7E45600C68182 /* UIViewControllerExtension.swift */; }; + A183FBDD24DB31DF00FD248C /* GenreProfileTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A183FBDB24DB31DF00FD248C /* GenreProfileTableViewCell.swift */; }; + A183FBDE24DB31DF00FD248C /* GenreProfileTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A183FBDC24DB31DF00FD248C /* GenreProfileTableViewCell.xib */; }; + A194A9E524DDA25900C9E87D /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A194A9E424DDA25900C9E87D /* StringExtension.swift */; }; + A194A9E724DDA87B00C9E87D /* UIViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A194A9E624DDA87B00C9E87D /* UIViewExtension.swift */; }; + A19ACB6E24D0FB45009027B1 /* AlbumSelectorVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A19ACB6D24D0FB45009027B1 /* AlbumSelectorVC.swift */; }; + A19C320224C89FF100A4506F /* FileSystemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A19C320124C89FF100A4506F /* FileSystemManager.swift */; }; + A19C320424C8A7AC00A4506F /* DocumentTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A19C320324C8A7AC00A4506F /* DocumentTableViewController.swift */; }; + A1A96B3324BFF12700EF12AB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1A96B3524BFF12700EF12AB /* Localizable.strings */; }; + A1A96B3824C050F100EF12AB /* SettingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A96B3724C050F100EF12AB /* SettingController.swift */; }; + A1DFB56024E0921F00059286 /* ForgotPasswordController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1DFB55F24E0921F00059286 /* ForgotPasswordController.swift */; }; + A1E3FFEE24C6A84500CA2228 /* Test.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1E3FFED24C6A84500CA2228 /* Test.storyboard */; }; + A1E76E3E24CE1ADD00D9415B /* UploadFileHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E76E3C24CE1ADC00D9415B /* UploadFileHeaderCell.swift */; }; + A1E76E3F24CE1ADD00D9415B /* UploadFileHeaderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1E76E3D24CE1ADD00D9415B /* UploadFileHeaderCell.xib */; }; + B703FE1024D025C8001AD48E /* ArtistSearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B703FE0E24D025C8001AD48E /* ArtistSearchCell.swift */; }; + B703FE1124D025C8001AD48E /* ArtistSearchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B703FE0F24D025C8001AD48E /* ArtistSearchCell.xib */; }; + B703FE1824D025E8001AD48E /* VideoSearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B703FE1624D025E8001AD48E /* VideoSearchCell.swift */; }; + B703FE1924D025E8001AD48E /* VideoSearchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B703FE1724D025E8001AD48E /* VideoSearchCell.xib */; }; + B703FE1C24D02654001AD48E /* PlaylistSearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B703FE1A24D02654001AD48E /* PlaylistSearchCell.swift */; }; + B703FE1D24D02654001AD48E /* PlaylistSearchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B703FE1B24D02654001AD48E /* PlaylistSearchCell.xib */; }; + B733E7F624CA7B3700460E23 /* UserProfileView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B733E7F524CA7B3700460E23 /* UserProfileView.storyboard */; }; + B733E7F824CA7B6100460E23 /* UserProfileVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B733E7F724CA7B6100460E23 /* UserProfileVC.swift */; }; + B73C835F24C7F89C0047B4EC /* FeaturedArtistView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B73C835E24C7F89C0047B4EC /* FeaturedArtistView.storyboard */; }; + B73C836124C7F8AC0047B4EC /* FeaturedArtistVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73C836024C7F8AC0047B4EC /* FeaturedArtistVC.swift */; }; + B73C836324C7F8BC0047B4EC /* FeaturedVideosView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B73C836224C7F8BC0047B4EC /* FeaturedVideosView.storyboard */; }; + B73C836524C7F8CC0047B4EC /* FeaturedVideosVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73C836424C7F8CC0047B4EC /* FeaturedVideosVC.swift */; }; + B74C59FB24C6E38D00C978F3 /* FeaturedVideosCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B74C59F924C6E38D00C978F3 /* FeaturedVideosCell.swift */; }; + B74C59FC24C6E38D00C978F3 /* FeaturedVideosCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B74C59FA24C6E38D00C978F3 /* FeaturedVideosCell.xib */; }; + B74C5A0024C7070200C978F3 /* TrendingNowList.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B74C59FF24C7070200C978F3 /* TrendingNowList.storyboard */; }; + B74C5A0224C711FA00C978F3 /* NotificationsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B74C5A0124C711FA00C978F3 /* NotificationsVC.swift */; }; + B74C5A0424C713DD00C978F3 /* Notifications.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B74C5A0324C713DD00C978F3 /* Notifications.storyboard */; }; + B74C5A0624C714AF00C978F3 /* TrendingNowVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B74C5A0524C714AF00C978F3 /* TrendingNowVC.swift */; }; + B758B53C24C7EFA200826CC5 /* LatestMusicView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B758B53B24C7EFA200826CC5 /* LatestMusicView.storyboard */; }; + B758B53E24C7F33900826CC5 /* LatestMusicVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B758B53D24C7F33900826CC5 /* LatestMusicVC.swift */; }; + B786384F24CEC2F600952CF3 /* FirstPageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B786384E24CEC2F600952CF3 /* FirstPageVC.swift */; }; + B786385124CEC30A00952CF3 /* SecondPageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B786385024CEC30A00952CF3 /* SecondPageVC.swift */; }; + B786385424CEC41A00952CF3 /* ShowcaseHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B786385224CEC41A00952CF3 /* ShowcaseHeaderCell.swift */; }; + B786385524CEC41A00952CF3 /* ShowcaseHeaderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B786385324CEC41A00952CF3 /* ShowcaseHeaderCell.xib */; }; + B786385B24CEEB8700952CF3 /* MusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B786385924CEEB8700952CF3 /* MusicTableViewCell.swift */; }; + B786385C24CEEB8700952CF3 /* MusicTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B786385A24CEEB8700952CF3 /* MusicTableViewCell.xib */; }; + B786386324CEEBA100952CF3 /* VideosTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B786386124CEEBA100952CF3 /* VideosTableViewCell.swift */; }; + B786386424CEEBA100952CF3 /* VideosTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B786386224CEEBA100952CF3 /* VideosTableViewCell.xib */; }; + B786386A24CEEC8500952CF3 /* ShowcaseVideoView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B786386924CEEC8500952CF3 /* ShowcaseVideoView.storyboard */; }; + B786386C24CEEC9900952CF3 /* ShowcasePhotosView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B786386B24CEEC9900952CF3 /* ShowcasePhotosView.storyboard */; }; + B786386E24CEECA400952CF3 /* ShowcaseMusicView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B786386D24CEECA400952CF3 /* ShowcaseMusicView.storyboard */; }; + B786387024CEECC300952CF3 /* ShowcaseVideosVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B786386F24CEECC300952CF3 /* ShowcaseVideosVC.swift */; }; + B786387224CEECD500952CF3 /* ShowcasePhotosVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B786387124CEECD500952CF3 /* ShowcasePhotosVC.swift */; }; + B798B3DF24DB31F6009472F4 /* CarouselViewController_.swift in Sources */ = {isa = PBXBuildFile; fileRef = B798B3D924DB31F5009472F4 /* CarouselViewController_.swift */; }; + B798B3E024DB31F6009472F4 /* CarouselPageViewController_.swift in Sources */ = {isa = PBXBuildFile; fileRef = B798B3DA24DB31F5009472F4 /* CarouselPageViewController_.swift */; }; + B798B3E124DB31F6009472F4 /* OnboardingScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B798B3DB24DB31F5009472F4 /* OnboardingScreen.storyboard */; }; + B798B3E224DB31F6009472F4 /* CarouselItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = B798B3DD24DB31F5009472F4 /* CarouselItem.xib */; }; + B798B3E324DB31F6009472F4 /* CarouselItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B798B3DE24DB31F5009472F4 /* CarouselItem.swift */; }; + B7B6F3BB24CFD133008BA503 /* PhotosCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7B6F3B924CFD133008BA503 /* PhotosCollectionCell.swift */; }; + B7B6F3BC24CFD133008BA503 /* PhotosCollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7B6F3BA24CFD133008BA503 /* PhotosCollectionCell.xib */; }; + B7BD5E3624D12465005918B7 /* MusicSearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7BD5E3424D12465005918B7 /* MusicSearchCell.swift */; }; + B7BD5E3724D12465005918B7 /* MusicSearchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7BD5E3524D12465005918B7 /* MusicSearchCell.xib */; }; + B7BEA4FB24D1466500AAB5C7 /* AboutHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7BEA4F924D1466400AAB5C7 /* AboutHeaderCell.swift */; }; + B7BEA4FC24D1466500AAB5C7 /* AboutHeaderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7BEA4FA24D1466500AAB5C7 /* AboutHeaderCell.xib */; }; + B7BEA4FF24D146C300AAB5C7 /* MusicGenreInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7BEA4FD24D146C300AAB5C7 /* MusicGenreInfoCell.swift */; }; + B7BEA50024D146C300AAB5C7 /* MusicGenreInfoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7BEA4FE24D146C300AAB5C7 /* MusicGenreInfoCell.xib */; }; + B7BEA50324D146E900AAB5C7 /* ContactInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7BEA50124D146E900AAB5C7 /* ContactInfoCell.swift */; }; + B7BEA50424D146E900AAB5C7 /* ContactInfoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7BEA50224D146E900AAB5C7 /* ContactInfoCell.xib */; }; + B7BEA50724D146F500AAB5C7 /* SocialMediaCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7BEA50524D146F500AAB5C7 /* SocialMediaCell.swift */; }; + B7BEA50824D146F500AAB5C7 /* SocialMediaCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7BEA50624D146F500AAB5C7 /* SocialMediaCell.xib */; }; + B7C7302724CE944700B922B8 /* CarouselPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7C7302624CE944700B922B8 /* CarouselPageViewController.swift */; }; + B7D0470524D070EA004A4D9C /* SearchHeaderSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D0470324D070EA004A4D9C /* SearchHeaderSection.swift */; }; + B7D0470624D070EA004A4D9C /* SearchHeaderSection.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7D0470424D070EA004A4D9C /* SearchHeaderSection.xib */; }; + B7D4B86324CEFEDB00FD30B2 /* ShowcaseMusicVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D4B86224CEFEDB00FD30B2 /* ShowcaseMusicVC.swift */; }; + B7D4B86624CF076900FD30B2 /* PhotosTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D4B86424CF076900FD30B2 /* PhotosTableViewCell.swift */; }; + B7D4B86724CF076900FD30B2 /* PhotosTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7D4B86524CF076900FD30B2 /* PhotosTableViewCell.xib */; }; + B7DAF5DB24C6919D00FC6EFB /* DiscoverNewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DAF5D924C6919D00FC6EFB /* DiscoverNewCell.swift */; }; + B7DAF5DC24C6919D00FC6EFB /* DiscoverNewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7DAF5DA24C6919D00FC6EFB /* DiscoverNewCell.xib */; }; + B7DAF5DF24C698B400FC6EFB /* LatestMusicCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DAF5DD24C698B400FC6EFB /* LatestMusicCell.swift */; }; + B7DAF5E024C698B400FC6EFB /* LatestMusicCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7DAF5DE24C698B400FC6EFB /* LatestMusicCell.xib */; }; + B7DAF5E324C6A6EE00FC6EFB /* FeaturedArtistCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DAF5E124C6A6EE00FC6EFB /* FeaturedArtistCell.swift */; }; + B7DAF5E424C6A6EE00FC6EFB /* FeaturedArtistCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7DAF5E224C6A6EE00FC6EFB /* FeaturedArtistCell.xib */; }; + B7DAF5E724C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DAF5E524C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.swift */; }; + B7DAF5E824C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7DAF5E624C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.xib */; }; + B7ECE0D224D01E9E008C4422 /* SearchContainerPageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7ECE0D124D01E9E008C4422 /* SearchContainerPageVC.swift */; }; + B7ECE0D424D0211C008C4422 /* AllSearchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7ECE0D324D0211C008C4422 /* AllSearchVC.swift */; }; + B7ECE0D624D02128008C4422 /* ArtistSearchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7ECE0D524D02128008C4422 /* ArtistSearchVC.swift */; }; + B7ECE0D824D02133008C4422 /* MusicSearchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7ECE0D724D02133008C4422 /* MusicSearchVC.swift */; }; + B7ECE0DA24D02143008C4422 /* VideoSearchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7ECE0D924D02143008C4422 /* VideoSearchVC.swift */; }; + B7ECE0DC24D0214F008C4422 /* PlaylistSearchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7ECE0DB24D0214F008C4422 /* PlaylistSearchVC.swift */; }; + DB40C396718E660BA2F0A63A /* Pods_CommunityMC3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AB1B9EC24CFFDF03E9A31BF /* Pods_CommunityMC3.framework */; }; + EA1BF07A24CA9A9C00CE1B8F /* MusicGenreCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1BF07824CA9A9C00CE1B8F /* MusicGenreCell.swift */; }; + EA1BF07B24CA9A9C00CE1B8F /* MusicGenreCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA1BF07924CA9A9C00CE1B8F /* MusicGenreCell.xib */; }; + EA1BF07F24CA9EAD00CE1B8F /* MusicListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1BF07D24CA9EAD00CE1B8F /* MusicListCell.swift */; }; + EA1BF08024CA9EAD00CE1B8F /* MusicListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA1BF07E24CA9EAD00CE1B8F /* MusicListCell.xib */; }; + EA2D793724CFC725005998B4 /* FavoritesMenuCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2D793524CFC725005998B4 /* FavoritesMenuCell.swift */; }; + EA2D793824CFC725005998B4 /* FavoritesMenuCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA2D793624CFC725005998B4 /* FavoritesMenuCell.xib */; }; + EA2D793C24CFD651005998B4 /* FavoriteTracksCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2D793A24CFD651005998B4 /* FavoriteTracksCell.swift */; }; + EA2D793D24CFD651005998B4 /* FavoriteTracksCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA2D793B24CFD651005998B4 /* FavoriteTracksCell.xib */; }; + EA2D793F24CFD66A005998B4 /* FavoriteTracksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2D793E24CFD66A005998B4 /* FavoriteTracksView.swift */; }; + EA2D794124CFF4B1005998B4 /* FavoriteTracksView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EA2D794024CFF4B1005998B4 /* FavoriteTracksView.storyboard */; }; + EA2D794524CFFCB0005998B4 /* FavoritesVideo.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EA2D794424CFFCB0005998B4 /* FavoritesVideo.storyboard */; }; + EA2D794724CFFD4F005998B4 /* FavoriteVideosView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2D794624CFFD4F005998B4 /* FavoriteVideosView.swift */; }; + EA2D794A24CFFD92005998B4 /* FavoriteVideosCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2D794824CFFD92005998B4 /* FavoriteVideosCell.swift */; }; + EA2D794B24CFFD92005998B4 /* FavoriteVideosCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA2D794924CFFD92005998B4 /* FavoriteVideosCell.xib */; }; + EA4A31C824CAB075003DCDA4 /* HeaderCellRandomSpotlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4A31C624CAB075003DCDA4 /* HeaderCellRandomSpotlight.swift */; }; + EA4A31C924CAB075003DCDA4 /* HeaderCellRandomSpotlight.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA4A31C724CAB075003DCDA4 /* HeaderCellRandomSpotlight.xib */; }; + EA4A31CC24CAB2B6003DCDA4 /* VideoListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4A31CA24CAB2B6003DCDA4 /* VideoListCell.swift */; }; + EA4A31CD24CAB2B6003DCDA4 /* VideoListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA4A31CB24CAB2B6003DCDA4 /* VideoListCell.xib */; }; + EA6173F424DD02F500F18DCB /* TrackManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6173F324DD02F500F18DCB /* TrackManager.swift */; }; + EA62938824DA827D00FDABB5 /* EditRandomizerContextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA62938624DA827D00FDABB5 /* EditRandomizerContextCell.swift */; }; + EA62938924DA827D00FDABB5 /* EditRandomizerContextCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA62938724DA827D00FDABB5 /* EditRandomizerContextCell.xib */; }; + EA62938B24DA834E00FDABB5 /* EditRandomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA62938A24DA834E00FDABB5 /* EditRandomizerViewController.swift */; }; + EA63453524D925510045328C /* UploadPanelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA63453424D925510045328C /* UploadPanelViewController.swift */; }; + EA63453824D92A5B0045328C /* UploadPanelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA63453624D92A5B0045328C /* UploadPanelCell.swift */; }; + EA63453924D92A5B0045328C /* UploadPanelCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA63453724D92A5B0045328C /* UploadPanelCell.xib */; }; + EA650D5524C557680093EEE6 /* TrackPlayer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EA650D5424C557680093EEE6 /* TrackPlayer.storyboard */; }; + EA65FF4E24DBC93200B3FAE1 /* StartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA65FF4D24DBC93200B3FAE1 /* StartViewController.swift */; }; + EA65FF5024DBC94500B3FAE1 /* MiniTrackPlayerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA65FF4F24DBC94500B3FAE1 /* MiniTrackPlayerController.swift */; }; + EA71357C24CE9A140073A8EA /* yorushika.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = EA71357924CE9A140073A8EA /* yorushika.mp3 */; }; + EA71357D24CE9A140073A8EA /* dishes.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = EA71357A24CE9A140073A8EA /* dishes.mp3 */; }; + EA71357E24CE9A140073A8EA /* tiara.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = EA71357B24CE9A140073A8EA /* tiara.mp3 */; }; + EA88AAA024D1128D007488F9 /* FavoriteArtist.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EA88AA9F24D1128D007488F9 /* FavoriteArtist.storyboard */; }; + EA88AAA224D11482007488F9 /* FavoriteArtistsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA88AAA124D11482007488F9 /* FavoriteArtistsView.swift */; }; + EA88AAA524D114FC007488F9 /* FavoriteArtistsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA88AAA324D114FC007488F9 /* FavoriteArtistsCell.swift */; }; + EA88AAA624D114FC007488F9 /* FavoriteArtistsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA88AAA424D114FC007488F9 /* FavoriteArtistsCell.xib */; }; + EA88AAA824D11EC1007488F9 /* FavoriteAlbums.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EA88AAA724D11EC1007488F9 /* FavoriteAlbums.storyboard */; }; + EA88AAAA24D11FF8007488F9 /* FavoriteAlbumsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA88AAA924D11FF8007488F9 /* FavoriteAlbumsView.swift */; }; + EA88AAAD24D12412007488F9 /* FavoriteAlbumsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA88AAAB24D12412007488F9 /* FavoriteAlbumsCell.swift */; }; + EA88AAAE24D12412007488F9 /* FavoriteAlbumsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EA88AAAC24D12412007488F9 /* FavoriteAlbumsCell.xib */; }; + EADBB5A524C560F300CD2C92 /* TrackPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADBB5A424C560F300CD2C92 /* TrackPlayerViewController.swift */; }; + EADBB5AA24C5BB5000CD2C92 /* VideoPlayer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EADBB5A924C5BB5000CD2C92 /* VideoPlayer.storyboard */; }; + EADBB5AC24C5BB6E00CD2C92 /* VideoPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADBB5AB24C5BB6E00CD2C92 /* VideoPlayerViewController.swift */; }; + EAE65B3424C7E69B008B453D /* RandomSpotlight.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EAE65B3324C7E69B008B453D /* RandomSpotlight.storyboard */; }; + EAE65B3624C7E964008B453D /* RandomSpotlightViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE65B3524C7E964008B453D /* RandomSpotlightViewController.swift */; }; + FC7318F0AA643896222FB2CB /* Pods_CommunityMC3_CommunityMC3UITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 86B7D30FBAD836876D4CFDB6 /* Pods_CommunityMC3_CommunityMC3UITests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + A16B44B824B2FBF700053D6C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A16B449724B2FBF200053D6C /* Project object */; + proxyType = 1; + remoteGlobalIDString = A16B449E24B2FBF200053D6C; + remoteInfo = CommunityMC3; + }; + A16B44C324B2FBF700053D6C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A16B449724B2FBF200053D6C /* Project object */; + proxyType = 1; + remoteGlobalIDString = A16B449E24B2FBF200053D6C; + remoteInfo = CommunityMC3; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 019A560054AEFAF9141EE53F /* Pods-CommunityMC3.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CommunityMC3.debug.xcconfig"; path = "Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.debug.xcconfig"; sourceTree = ""; }; + 30DFE041381608564EB18E8D /* Pods-CommunityMC3Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CommunityMC3Tests.debug.xcconfig"; path = "Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.debug.xcconfig"; sourceTree = ""; }; + 4AB1B9EC24CFFDF03E9A31BF /* Pods_CommunityMC3.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CommunityMC3.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 53088E5DFD64AC02E18FE20F /* Pods_CommunityMC3Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CommunityMC3Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5609308099ECFB57AB0C371F /* Pods-CommunityMC3.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CommunityMC3.release.xcconfig"; path = "Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.release.xcconfig"; sourceTree = ""; }; + 64E3FBC18FCDD9176F27A578 /* Pods-CommunityMC3Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CommunityMC3Tests.release.xcconfig"; path = "Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.release.xcconfig"; sourceTree = ""; }; + 86B7D30FBAD836876D4CFDB6 /* Pods_CommunityMC3_CommunityMC3UITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CommunityMC3_CommunityMC3UITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8A8733AF0E9CC638EA6B0781 /* Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig"; path = "Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig"; sourceTree = ""; }; + A11A9FD624C94A58008D7867 /* albumListTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = albumListTableViewCell.swift; sourceTree = ""; }; + A11A9FD724C94A58008D7867 /* albumTitleTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = albumTitleTableViewCell.xib; sourceTree = ""; }; + A11A9FD824C94A58008D7867 /* albumTitleTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = albumTitleTableViewCell.swift; sourceTree = ""; }; + A11A9FD924C94A58008D7867 /* albumListTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = albumListTableViewCell.xib; sourceTree = ""; }; + A11A9FDA24C94A58008D7867 /* UploadFileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadFileView.swift; sourceTree = ""; }; + A11A9FDC24C94A58008D7867 /* GenreTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenreTableViewCell.swift; sourceTree = ""; }; + A11A9FDD24C94A58008D7867 /* GenreTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GenreTableViewCell.xib; sourceTree = ""; }; + A11A9FDF24C94A58008D7867 /* descTitleTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = descTitleTableViewCell.xib; sourceTree = ""; }; + A11A9FE024C94A58008D7867 /* descTitleTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = descTitleTableViewCell.swift; sourceTree = ""; }; + A11A9FE124C94A58008D7867 /* UploadFileView.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = UploadFileView.storyboard; sourceTree = ""; }; + A11A9FE324C94A58008D7867 /* UploadTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadTableViewCell.swift; sourceTree = ""; }; + A11A9FE424C94A58008D7867 /* UploadTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UploadTableViewCell.xib; sourceTree = ""; }; + A11A9FE524C94A58008D7867 /* AddCoverTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddCoverTableViewCell.swift; sourceTree = ""; }; + A11A9FE624C94A58008D7867 /* AddCoverTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AddCoverTableViewCell.xib; sourceTree = ""; }; + A121CE9C24C96C6D00E1D48B /* SmallViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmallViewController.swift; sourceTree = ""; }; + A121CE9D24C96C6D00E1D48B /* SmallViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SmallViewController.storyboard; sourceTree = ""; }; + A124876824CD0BE400030723 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SelectViewCell.xib; sourceTree = ""; }; + A124876B24CD0BEE00030723 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/SelectFileView.storyboard; sourceTree = ""; }; + A124877224CD2AC500030723 /* MainTabController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabController.swift; sourceTree = ""; }; + A125311D24CE89C30038B215 /* UIImageExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = ""; }; + A12F370324D23C02002F31E0 /* Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = ""; }; + A134D29D24C8EA41009A054F /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = ""; }; + A134D29F24C907B4009A054F /* Featured+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Featured+Extension.swift"; path = "CommunityMC3/Data/Featured+Extension.swift"; sourceTree = SOURCE_ROOT; }; + A134D2A224C908F3009A054F /* Album+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Album+Extension.swift"; sourceTree = ""; }; + A134D2A424C91B99009A054F /* Favourites+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Favourites+Extension.swift"; sourceTree = ""; }; + A134D2A624C91BAB009A054F /* Photos+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Photos+Extension.swift"; sourceTree = ""; }; + A134D2A824C91BBC009A054F /* Track+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Track+Extension.swift"; sourceTree = ""; }; + A134D2AA24C91BC9009A054F /* UploadedData+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UploadedData+Extension.swift"; sourceTree = ""; }; + A134D2AC24C91BD4009A054F /* UserData+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserData+Extension.swift"; sourceTree = ""; }; + A134D2AE24C91BDB009A054F /* Videos+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Videos+Extension.swift"; sourceTree = ""; }; + A136C2A124D9CADA0078F37E /* GenreProfileCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenreProfileCollectionViewCell.swift; sourceTree = ""; }; + A136C2A224D9CADA0078F37E /* GenreProfileCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GenreProfileCollectionViewCell.xib; sourceTree = ""; }; + A136C2A524D9CE5F0078F37E /* GenreProfileController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenreProfileController.swift; sourceTree = ""; }; + A136C2A824D9D9BB0078F37E /* SwitchAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchAccountTableViewCell.swift; sourceTree = ""; }; + A136C2A924D9D9BB0078F37E /* SwitchAccountTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SwitchAccountTableViewCell.xib; sourceTree = ""; }; + A136C2AC24D9DA100078F37E /* AddAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountTableViewCell.swift; sourceTree = ""; }; + A136C2AD24D9DA100078F37E /* AddAccountTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AddAccountTableViewCell.xib; sourceTree = ""; }; + A136C2B024D9DA4A0078F37E /* AccountController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountController.swift; sourceTree = ""; }; + A1432F5424C69958007656B1 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; + A14B626224D09B890015223C /* Favourites.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Favourites.storyboard; sourceTree = ""; }; + A14B626424D09B910015223C /* FavouritesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FavouritesView.swift; sourceTree = ""; }; + A14B626724D0D3830015223C /* CloudKitUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudKitUtil.swift; sourceTree = ""; }; + A1503D3924C4B79900AE317E /* LoginScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LoginScreen.storyboard; sourceTree = ""; }; + A1503D3B24C4BA9B00AE317E /* LoginController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginController.swift; sourceTree = ""; }; + A15C4D0F24C502EF00ED0C0E /* Search.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Search.storyboard; sourceTree = ""; }; + A15C4D1824C5038C00ED0C0E /* DB_Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = DB_Model.xcdatamodel; sourceTree = ""; }; + A15C4D1A24C5300A00ED0C0E /* Explorer.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Explorer.storyboard; sourceTree = ""; }; + A15C4D2024C5367400ED0C0E /* TrendingNowCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingNowCell.swift; sourceTree = ""; }; + A15C4D2124C5367400ED0C0E /* TrendingNowCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TrendingNowCell.xib; sourceTree = ""; }; + A15C4D2424C5370C00ED0C0E /* HeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderCell.swift; sourceTree = ""; }; + A15C4D2524C5370C00ED0C0E /* HeaderCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HeaderCell.xib; sourceTree = ""; }; + A15C4D2D24C543B100ED0C0E /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; }; + A165068F24C7DCE4005822E7 /* RegisterController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RegisterController.swift; sourceTree = ""; }; + A165069124C7DD46005822E7 /* SettingScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SettingScreen.storyboard; sourceTree = ""; }; + A1689CEA24C7A6D300A49732 /* SelectFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectFileView.swift; sourceTree = ""; }; + A1689D3224C7B14000A49732 /* SelectViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectViewCell.swift; sourceTree = ""; }; + A1689D3624C7B5F200A49732 /* DataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataManager.swift; sourceTree = ""; }; + A1689D3824C7D67700A49732 /* AlertViewHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertViewHelper.swift; sourceTree = ""; }; + A1689D3A24C7D76500A49732 /* CoreDataHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataHelper.swift; sourceTree = ""; }; + A169E8A524CA9226000D815F /* UploadController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadController.swift; sourceTree = ""; }; + A16B449F24B2FBF200053D6C /* Allegro.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Allegro.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A16B44A224B2FBF300053D6C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + A16B44A424B2FBF300053D6C /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + A16B44A624B2FBF300053D6C /* ExplorerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExplorerView.swift; sourceTree = ""; }; + A16B44A824B2FBF300053D6C /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = ""; }; + A16B44AB24B2FBF300053D6C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + A16B44AD24B2FBF600053D6C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + A16B44B024B2FBF600053D6C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + A16B44B224B2FBF600053D6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A16B44B724B2FBF700053D6C /* CommunityMC3Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CommunityMC3Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + A16B44BB24B2FBF700053D6C /* CommunityMC3Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommunityMC3Tests.swift; sourceTree = ""; }; + A16B44BD24B2FBF700053D6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A16B44C224B2FBF700053D6C /* CommunityMC3UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CommunityMC3UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + A16B44C624B2FBF700053D6C /* CommunityMC3UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommunityMC3UITests.swift; sourceTree = ""; }; + A16B44C824B2FBF700053D6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A17C3C6824CCA3C500153493 /* Constant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constant.swift; sourceTree = ""; }; + A1824D9924C7E3E200C68182 /* Account+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Account+Extension.swift"; path = "CommunityMC3/Data/Account+Extension.swift"; sourceTree = SOURCE_ROOT; }; + A1824D9B24C7E45600C68182 /* UIViewControllerExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtension.swift; sourceTree = ""; }; + A183FBDB24DB31DF00FD248C /* GenreProfileTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenreProfileTableViewCell.swift; sourceTree = ""; }; + A183FBDC24DB31DF00FD248C /* GenreProfileTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GenreProfileTableViewCell.xib; sourceTree = ""; }; + A194A9E424DDA25900C9E87D /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = ""; }; + A194A9E624DDA87B00C9E87D /* UIViewExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtension.swift; sourceTree = ""; }; + A19ACB6D24D0FB45009027B1 /* AlbumSelectorVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumSelectorVC.swift; sourceTree = ""; }; + A19C320124C89FF100A4506F /* FileSystemManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemManager.swift; sourceTree = ""; }; + A19C320324C8A7AC00A4506F /* DocumentTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentTableViewController.swift; sourceTree = ""; }; + A1A96B2F24BFEFD400EF12AB /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Main.strings; sourceTree = ""; }; + A1A96B3024BFEFD400EF12AB /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/LaunchScreen.strings; sourceTree = ""; }; + A1A96B3424BFF12700EF12AB /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = ""; }; + A1A96B3624BFF14400EF12AB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + A1A96B3724C050F100EF12AB /* SettingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingController.swift; sourceTree = ""; }; + A1CF317024C4B9E000E38E53 /* CommunityMC3.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CommunityMC3.entitlements; sourceTree = ""; }; + A1DFB55F24E0921F00059286 /* ForgotPasswordController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForgotPasswordController.swift; sourceTree = ""; }; + A1E3FFED24C6A84500CA2228 /* Test.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Test.storyboard; sourceTree = ""; }; + A1E76E3C24CE1ADC00D9415B /* UploadFileHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadFileHeaderCell.swift; sourceTree = ""; }; + A1E76E3D24CE1ADD00D9415B /* UploadFileHeaderCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UploadFileHeaderCell.xib; sourceTree = ""; }; + B703FE0E24D025C8001AD48E /* ArtistSearchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistSearchCell.swift; sourceTree = ""; }; + B703FE0F24D025C8001AD48E /* ArtistSearchCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ArtistSearchCell.xib; sourceTree = ""; }; + B703FE1624D025E8001AD48E /* VideoSearchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoSearchCell.swift; sourceTree = ""; }; + B703FE1724D025E8001AD48E /* VideoSearchCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VideoSearchCell.xib; sourceTree = ""; }; + B703FE1A24D02654001AD48E /* PlaylistSearchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistSearchCell.swift; sourceTree = ""; }; + B703FE1B24D02654001AD48E /* PlaylistSearchCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PlaylistSearchCell.xib; sourceTree = ""; }; + B733E7F524CA7B3700460E23 /* UserProfileView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = UserProfileView.storyboard; sourceTree = ""; }; + B733E7F724CA7B6100460E23 /* UserProfileVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileVC.swift; sourceTree = ""; }; + B73C835E24C7F89C0047B4EC /* FeaturedArtistView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FeaturedArtistView.storyboard; sourceTree = ""; }; + B73C836024C7F8AC0047B4EC /* FeaturedArtistVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedArtistVC.swift; sourceTree = ""; }; + B73C836224C7F8BC0047B4EC /* FeaturedVideosView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FeaturedVideosView.storyboard; sourceTree = ""; }; + B73C836424C7F8CC0047B4EC /* FeaturedVideosVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedVideosVC.swift; sourceTree = ""; }; + B74C59F924C6E38D00C978F3 /* FeaturedVideosCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedVideosCell.swift; sourceTree = ""; }; + B74C59FA24C6E38D00C978F3 /* FeaturedVideosCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FeaturedVideosCell.xib; sourceTree = ""; }; + B74C59FF24C7070200C978F3 /* TrendingNowList.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TrendingNowList.storyboard; sourceTree = ""; }; + B74C5A0124C711FA00C978F3 /* NotificationsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsVC.swift; sourceTree = ""; }; + B74C5A0324C713DD00C978F3 /* Notifications.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Notifications.storyboard; sourceTree = ""; }; + B74C5A0524C714AF00C978F3 /* TrendingNowVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingNowVC.swift; sourceTree = ""; }; + B758B53B24C7EFA200826CC5 /* LatestMusicView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LatestMusicView.storyboard; sourceTree = ""; }; + B758B53D24C7F33900826CC5 /* LatestMusicVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestMusicVC.swift; sourceTree = ""; }; + B786384E24CEC2F600952CF3 /* FirstPageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstPageVC.swift; sourceTree = ""; }; + B786385024CEC30A00952CF3 /* SecondPageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondPageVC.swift; sourceTree = ""; }; + B786385224CEC41A00952CF3 /* ShowcaseHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowcaseHeaderCell.swift; sourceTree = ""; }; + B786385324CEC41A00952CF3 /* ShowcaseHeaderCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShowcaseHeaderCell.xib; sourceTree = ""; }; + B786385924CEEB8700952CF3 /* MusicTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicTableViewCell.swift; sourceTree = ""; }; + B786385A24CEEB8700952CF3 /* MusicTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicTableViewCell.xib; sourceTree = ""; }; + B786386124CEEBA100952CF3 /* VideosTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosTableViewCell.swift; sourceTree = ""; }; + B786386224CEEBA100952CF3 /* VideosTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VideosTableViewCell.xib; sourceTree = ""; }; + B786386924CEEC8500952CF3 /* ShowcaseVideoView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ShowcaseVideoView.storyboard; sourceTree = ""; }; + B786386B24CEEC9900952CF3 /* ShowcasePhotosView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ShowcasePhotosView.storyboard; sourceTree = ""; }; + B786386D24CEECA400952CF3 /* ShowcaseMusicView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ShowcaseMusicView.storyboard; sourceTree = ""; }; + B786386F24CEECC300952CF3 /* ShowcaseVideosVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowcaseVideosVC.swift; sourceTree = ""; }; + B786387124CEECD500952CF3 /* ShowcasePhotosVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowcasePhotosVC.swift; sourceTree = ""; }; + B798B3D924DB31F5009472F4 /* CarouselViewController_.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarouselViewController_.swift; sourceTree = ""; }; + B798B3DA24DB31F5009472F4 /* CarouselPageViewController_.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarouselPageViewController_.swift; sourceTree = ""; }; + B798B3DB24DB31F5009472F4 /* OnboardingScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = OnboardingScreen.storyboard; sourceTree = ""; }; + B798B3DD24DB31F5009472F4 /* CarouselItem.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CarouselItem.xib; sourceTree = ""; }; + B798B3DE24DB31F5009472F4 /* CarouselItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarouselItem.swift; sourceTree = ""; }; + B7B6F3B924CFD133008BA503 /* PhotosCollectionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotosCollectionCell.swift; sourceTree = ""; }; + B7B6F3BA24CFD133008BA503 /* PhotosCollectionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PhotosCollectionCell.xib; sourceTree = ""; }; + B7BD5E3424D12465005918B7 /* MusicSearchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicSearchCell.swift; sourceTree = ""; }; + B7BD5E3524D12465005918B7 /* MusicSearchCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicSearchCell.xib; sourceTree = ""; }; + B7BEA4F924D1466400AAB5C7 /* AboutHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutHeaderCell.swift; sourceTree = ""; }; + B7BEA4FA24D1466500AAB5C7 /* AboutHeaderCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutHeaderCell.xib; sourceTree = ""; }; + B7BEA4FD24D146C300AAB5C7 /* MusicGenreInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicGenreInfoCell.swift; sourceTree = ""; }; + B7BEA4FE24D146C300AAB5C7 /* MusicGenreInfoCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicGenreInfoCell.xib; sourceTree = ""; }; + B7BEA50124D146E900AAB5C7 /* ContactInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactInfoCell.swift; sourceTree = ""; }; + B7BEA50224D146E900AAB5C7 /* ContactInfoCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ContactInfoCell.xib; sourceTree = ""; }; + B7BEA50524D146F500AAB5C7 /* SocialMediaCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialMediaCell.swift; sourceTree = ""; }; + B7BEA50624D146F500AAB5C7 /* SocialMediaCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SocialMediaCell.xib; sourceTree = ""; }; + B7C7302624CE944700B922B8 /* CarouselPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselPageViewController.swift; sourceTree = ""; }; + B7D0470324D070EA004A4D9C /* SearchHeaderSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHeaderSection.swift; sourceTree = ""; }; + B7D0470424D070EA004A4D9C /* SearchHeaderSection.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SearchHeaderSection.xib; sourceTree = ""; }; + B7D4B86224CEFEDB00FD30B2 /* ShowcaseMusicVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowcaseMusicVC.swift; sourceTree = ""; }; + B7D4B86424CF076900FD30B2 /* PhotosTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotosTableViewCell.swift; sourceTree = ""; }; + B7D4B86524CF076900FD30B2 /* PhotosTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PhotosTableViewCell.xib; sourceTree = ""; }; + B7DAF5D924C6919D00FC6EFB /* DiscoverNewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoverNewCell.swift; sourceTree = ""; }; + B7DAF5DA24C6919D00FC6EFB /* DiscoverNewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DiscoverNewCell.xib; sourceTree = ""; }; + B7DAF5DD24C698B400FC6EFB /* LatestMusicCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestMusicCell.swift; sourceTree = ""; }; + B7DAF5DE24C698B400FC6EFB /* LatestMusicCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LatestMusicCell.xib; sourceTree = ""; }; + B7DAF5E124C6A6EE00FC6EFB /* FeaturedArtistCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedArtistCell.swift; sourceTree = ""; }; + B7DAF5E224C6A6EE00FC6EFB /* FeaturedArtistCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FeaturedArtistCell.xib; sourceTree = ""; }; + B7DAF5E524C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedArtistCollectionCell.swift; sourceTree = ""; }; + B7DAF5E624C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FeaturedArtistCollectionCell.xib; sourceTree = ""; }; + B7ECE0D124D01E9E008C4422 /* SearchContainerPageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchContainerPageVC.swift; sourceTree = ""; }; + B7ECE0D324D0211C008C4422 /* AllSearchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllSearchVC.swift; sourceTree = ""; }; + B7ECE0D524D02128008C4422 /* ArtistSearchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistSearchVC.swift; sourceTree = ""; }; + B7ECE0D724D02133008C4422 /* MusicSearchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicSearchVC.swift; sourceTree = ""; }; + B7ECE0D924D02143008C4422 /* VideoSearchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoSearchVC.swift; sourceTree = ""; }; + B7ECE0DB24D0214F008C4422 /* PlaylistSearchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistSearchVC.swift; sourceTree = ""; }; + B99D5A48E4347EB77E44214C /* Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig"; path = "Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig"; sourceTree = ""; }; + EA1BF07824CA9A9C00CE1B8F /* MusicGenreCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicGenreCell.swift; sourceTree = ""; }; + EA1BF07924CA9A9C00CE1B8F /* MusicGenreCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicGenreCell.xib; sourceTree = ""; }; + EA1BF07D24CA9EAD00CE1B8F /* MusicListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicListCell.swift; sourceTree = ""; }; + EA1BF07E24CA9EAD00CE1B8F /* MusicListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicListCell.xib; sourceTree = ""; }; + EA2D793524CFC725005998B4 /* FavoritesMenuCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesMenuCell.swift; sourceTree = ""; }; + EA2D793624CFC725005998B4 /* FavoritesMenuCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavoritesMenuCell.xib; sourceTree = ""; }; + EA2D793A24CFD651005998B4 /* FavoriteTracksCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteTracksCell.swift; sourceTree = ""; }; + EA2D793B24CFD651005998B4 /* FavoriteTracksCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavoriteTracksCell.xib; sourceTree = ""; }; + EA2D793E24CFD66A005998B4 /* FavoriteTracksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteTracksView.swift; sourceTree = ""; }; + EA2D794024CFF4B1005998B4 /* FavoriteTracksView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FavoriteTracksView.storyboard; sourceTree = ""; }; + EA2D794424CFFCB0005998B4 /* FavoritesVideo.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FavoritesVideo.storyboard; sourceTree = ""; }; + EA2D794624CFFD4F005998B4 /* FavoriteVideosView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteVideosView.swift; sourceTree = ""; }; + EA2D794824CFFD92005998B4 /* FavoriteVideosCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteVideosCell.swift; sourceTree = ""; }; + EA2D794924CFFD92005998B4 /* FavoriteVideosCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavoriteVideosCell.xib; sourceTree = ""; }; + EA4A31C624CAB075003DCDA4 /* HeaderCellRandomSpotlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderCellRandomSpotlight.swift; sourceTree = ""; }; + EA4A31C724CAB075003DCDA4 /* HeaderCellRandomSpotlight.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HeaderCellRandomSpotlight.xib; sourceTree = ""; }; + EA4A31CA24CAB2B6003DCDA4 /* VideoListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoListCell.swift; sourceTree = ""; }; + EA4A31CB24CAB2B6003DCDA4 /* VideoListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VideoListCell.xib; sourceTree = ""; }; + EA6173F324DD02F500F18DCB /* TrackManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackManager.swift; sourceTree = ""; }; + EA62938624DA827D00FDABB5 /* EditRandomizerContextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRandomizerContextCell.swift; sourceTree = ""; }; + EA62938724DA827D00FDABB5 /* EditRandomizerContextCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EditRandomizerContextCell.xib; sourceTree = ""; }; + EA62938A24DA834E00FDABB5 /* EditRandomizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRandomizerViewController.swift; sourceTree = ""; }; + EA63453424D925510045328C /* UploadPanelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadPanelViewController.swift; sourceTree = ""; }; + EA63453624D92A5B0045328C /* UploadPanelCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadPanelCell.swift; sourceTree = ""; }; + EA63453724D92A5B0045328C /* UploadPanelCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UploadPanelCell.xib; sourceTree = ""; }; + EA650D5424C557680093EEE6 /* TrackPlayer.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TrackPlayer.storyboard; sourceTree = ""; }; + EA65FF4D24DBC93200B3FAE1 /* StartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartViewController.swift; sourceTree = ""; }; + EA65FF4F24DBC94500B3FAE1 /* MiniTrackPlayerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MiniTrackPlayerController.swift; sourceTree = ""; }; + EA71357924CE9A140073A8EA /* yorushika.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = yorushika.mp3; sourceTree = ""; }; + EA71357A24CE9A140073A8EA /* dishes.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = dishes.mp3; sourceTree = ""; }; + EA71357B24CE9A140073A8EA /* tiara.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = tiara.mp3; sourceTree = ""; }; + EA88AA9F24D1128D007488F9 /* FavoriteArtist.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FavoriteArtist.storyboard; sourceTree = ""; }; + EA88AAA124D11482007488F9 /* FavoriteArtistsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteArtistsView.swift; sourceTree = ""; }; + EA88AAA324D114FC007488F9 /* FavoriteArtistsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteArtistsCell.swift; sourceTree = ""; }; + EA88AAA424D114FC007488F9 /* FavoriteArtistsCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavoriteArtistsCell.xib; sourceTree = ""; }; + EA88AAA724D11EC1007488F9 /* FavoriteAlbums.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FavoriteAlbums.storyboard; sourceTree = ""; }; + EA88AAA924D11FF8007488F9 /* FavoriteAlbumsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteAlbumsView.swift; sourceTree = ""; }; + EA88AAAB24D12412007488F9 /* FavoriteAlbumsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteAlbumsCell.swift; sourceTree = ""; }; + EA88AAAC24D12412007488F9 /* FavoriteAlbumsCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavoriteAlbumsCell.xib; sourceTree = ""; }; + EADBB5A424C560F300CD2C92 /* TrackPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackPlayerViewController.swift; sourceTree = ""; }; + EADBB5A924C5BB5000CD2C92 /* VideoPlayer.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = VideoPlayer.storyboard; sourceTree = ""; }; + EADBB5AB24C5BB6E00CD2C92 /* VideoPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerViewController.swift; sourceTree = ""; }; + EAE65B3324C7E69B008B453D /* RandomSpotlight.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = RandomSpotlight.storyboard; sourceTree = ""; }; + EAE65B3524C7E964008B453D /* RandomSpotlightViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomSpotlightViewController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A16B449C24B2FBF200053D6C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A15C4D2E24C543B100ED0C0E /* CloudKit.framework in Frameworks */, + DB40C396718E660BA2F0A63A /* Pods_CommunityMC3.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A16B44B424B2FBF700053D6C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 79E4D2F6736D4B440235FF24 /* Pods_CommunityMC3Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A16B44BF24B2FBF700053D6C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FC7318F0AA643896222FB2CB /* Pods_CommunityMC3_CommunityMC3UITests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3786B3E651FA0AF4F9A31D9C /* Pods */ = { + isa = PBXGroup; + children = ( + 019A560054AEFAF9141EE53F /* Pods-CommunityMC3.debug.xcconfig */, + 5609308099ECFB57AB0C371F /* Pods-CommunityMC3.release.xcconfig */, + 8A8733AF0E9CC638EA6B0781 /* Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig */, + B99D5A48E4347EB77E44214C /* Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig */, + 30DFE041381608564EB18E8D /* Pods-CommunityMC3Tests.debug.xcconfig */, + 64E3FBC18FCDD9176F27A578 /* Pods-CommunityMC3Tests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + A11A9FD424C94A58008D7867 /* UploadFileView */ = { + isa = PBXGroup; + children = ( + A1E76E4124CE1F9200D9415B /* UploadFileHeaderCell */, + A11A9FE224C94A58008D7867 /* Upload track */, + A11A9FD524C94A58008D7867 /* Album */, + A11A9FDB24C94A58008D7867 /* Genre */, + A11A9FDE24C94A58008D7867 /* Description */, + A11A9FE124C94A58008D7867 /* UploadFileView.storyboard */, + A11A9FDA24C94A58008D7867 /* UploadFileView.swift */, + ); + path = UploadFileView; + sourceTree = ""; + }; + A11A9FD524C94A58008D7867 /* Album */ = { + isa = PBXGroup; + children = ( + A11A9FD624C94A58008D7867 /* albumListTableViewCell.swift */, + A11A9FD724C94A58008D7867 /* albumTitleTableViewCell.xib */, + A11A9FD824C94A58008D7867 /* albumTitleTableViewCell.swift */, + A11A9FD924C94A58008D7867 /* albumListTableViewCell.xib */, + A19ACB6D24D0FB45009027B1 /* AlbumSelectorVC.swift */, + ); + path = "Album "; + sourceTree = ""; + }; + A11A9FDB24C94A58008D7867 /* Genre */ = { + isa = PBXGroup; + children = ( + A11A9FDC24C94A58008D7867 /* GenreTableViewCell.swift */, + A11A9FDD24C94A58008D7867 /* GenreTableViewCell.xib */, + ); + path = Genre; + sourceTree = ""; + }; + A11A9FDE24C94A58008D7867 /* Description */ = { + isa = PBXGroup; + children = ( + A11A9FDF24C94A58008D7867 /* descTitleTableViewCell.xib */, + A11A9FE024C94A58008D7867 /* descTitleTableViewCell.swift */, + ); + path = Description; + sourceTree = ""; + }; + A11A9FE224C94A58008D7867 /* Upload track */ = { + isa = PBXGroup; + children = ( + A11A9FE324C94A58008D7867 /* UploadTableViewCell.swift */, + A11A9FE424C94A58008D7867 /* UploadTableViewCell.xib */, + A11A9FE524C94A58008D7867 /* AddCoverTableViewCell.swift */, + A11A9FE624C94A58008D7867 /* AddCoverTableViewCell.xib */, + ); + path = "Upload track"; + sourceTree = ""; + }; + A121CE9B24C96C6D00E1D48B /* BonsaiTest */ = { + isa = PBXGroup; + children = ( + A121CE9C24C96C6D00E1D48B /* SmallViewController.swift */, + A121CE9D24C96C6D00E1D48B /* SmallViewController.storyboard */, + ); + path = BonsaiTest; + sourceTree = ""; + }; + A124877124CD2A3600030723 /* Main Storyboard */ = { + isa = PBXGroup; + children = ( + A16B44AA24B2FBF300053D6C /* Main.storyboard */, + A124877224CD2AC500030723 /* MainTabController.swift */, + EA65FF4D24DBC93200B3FAE1 /* StartViewController.swift */, + EA65FF4F24DBC94500B3FAE1 /* MiniTrackPlayerController.swift */, + ); + path = "Main Storyboard"; + sourceTree = ""; + }; + A12F370224D1C3BB002F31E0 /* Recovered References */ = { + isa = PBXGroup; + children = ( + ); + name = "Recovered References"; + sourceTree = ""; + }; + A1313E1224CA6DCB000DA7A7 /* NotificationView */ = { + isa = PBXGroup; + children = ( + B74C5A0324C713DD00C978F3 /* Notifications.storyboard */, + B74C5A0124C711FA00C978F3 /* NotificationsVC.swift */, + ); + path = NotificationView; + sourceTree = ""; + }; + A134D2A124C908D3009A054F /* Data */ = { + isa = PBXGroup; + children = ( + A1824D9924C7E3E200C68182 /* Account+Extension.swift */, + A134D2A224C908F3009A054F /* Album+Extension.swift */, + A134D29F24C907B4009A054F /* Featured+Extension.swift */, + A134D2A424C91B99009A054F /* Favourites+Extension.swift */, + A134D2A624C91BAB009A054F /* Photos+Extension.swift */, + A134D2A824C91BBC009A054F /* Track+Extension.swift */, + A134D2AA24C91BC9009A054F /* UploadedData+Extension.swift */, + A134D2AC24C91BD4009A054F /* UserData+Extension.swift */, + A134D2AE24C91BDB009A054F /* Videos+Extension.swift */, + A17C3C6824CCA3C500153493 /* Constant.swift */, + ); + path = Data; + sourceTree = ""; + }; + A136C29E24D9C9FA0078F37E /* GenreCollectionView */ = { + isa = PBXGroup; + children = ( + A136C2A124D9CADA0078F37E /* GenreProfileCollectionViewCell.swift */, + A136C2A224D9CADA0078F37E /* GenreProfileCollectionViewCell.xib */, + ); + path = GenreCollectionView; + sourceTree = ""; + }; + A136C2A724D9D95A0078F37E /* SwitchAccountTableView */ = { + isa = PBXGroup; + children = ( + A136C2A824D9D9BB0078F37E /* SwitchAccountTableViewCell.swift */, + A136C2A924D9D9BB0078F37E /* SwitchAccountTableViewCell.xib */, + A136C2AC24D9DA100078F37E /* AddAccountTableViewCell.swift */, + A136C2AD24D9DA100078F37E /* AddAccountTableViewCell.xib */, + ); + path = SwitchAccountTableView; + sourceTree = ""; + }; + A1432F5324C69879007656B1 /* Utilities */ = { + isa = PBXGroup; + children = ( + A1432F5424C69958007656B1 /* ImagePicker.swift */, + A1689D3A24C7D76500A49732 /* CoreDataHelper.swift */, + A1689D3824C7D67700A49732 /* AlertViewHelper.swift */, + A1824D9B24C7E45600C68182 /* UIViewControllerExtension.swift */, + A19C320124C89FF100A4506F /* FileSystemManager.swift */, + A125311D24CE89C30038B215 /* UIImageExtension.swift */, + A14B626724D0D3830015223C /* CloudKitUtil.swift */, + A12F370324D23C02002F31E0 /* Utilities.swift */, + A194A9E424DDA25900C9E87D /* StringExtension.swift */, + A194A9E624DDA87B00C9E87D /* UIViewExtension.swift */, + ); + path = Utilities; + sourceTree = ""; + }; + A14B626624D09D5D0015223C /* Test File */ = { + isa = PBXGroup; + children = ( + EA71357A24CE9A140073A8EA /* dishes.mp3 */, + EA71357B24CE9A140073A8EA /* tiara.mp3 */, + EA71357924CE9A140073A8EA /* yorushika.mp3 */, + ); + path = "Test File"; + sourceTree = ""; + }; + A15C4D1424C5032700ED0C0E /* Favourites View */ = { + isa = PBXGroup; + children = ( + EA2D793924CFD5AD005998B4 /* FavoritesDetailCell */, + EA2D793424CFC6DE005998B4 /* FavoriteMenuCell */, + EA2D794224CFFC54005998B4 /* Storyboards */, + EA2D794324CFFC65005998B4 /* ViewControllers */, + ); + path = "Favourites View"; + sourceTree = ""; + }; + A15C4D1524C5033800ED0C0E /* SearchView */ = { + isa = PBXGroup; + children = ( + B7ECE0E124D0219E008C4422 /* Playlist Search */, + B7ECE0E024D02188008C4422 /* Video Search */, + B7ECE0DF24D02176008C4422 /* Music Search */, + B7ECE0DE24D0216F008C4422 /* Artist Search */, + B7ECE0DD24D02160008C4422 /* All Search */, + A15C4D0F24C502EF00ED0C0E /* Search.storyboard */, + A16B44A824B2FBF300053D6C /* SearchView.swift */, + B7ECE0D124D01E9E008C4422 /* SearchContainerPageVC.swift */, + ); + path = SearchView; + sourceTree = ""; + }; + A15C4D1624C5034A00ED0C0E /* Explorer View */ = { + isa = PBXGroup; + children = ( + B7A0BADF24C6D4BA00292AA3 /* Trending Now */, + B7A0BADD24C6D4B100292AA3 /* Discover New */, + B7A0BADC24C6D49600292AA3 /* Latest Music */, + B7A0BAE024C6D4D200292AA3 /* Featured Artists */, + B74C59F824C6E35B00C978F3 /* Featured Videos */, + A15C4D1A24C5300A00ED0C0E /* Explorer.storyboard */, + A16B44A624B2FBF300053D6C /* ExplorerView.swift */, + A15C4D2424C5370C00ED0C0E /* HeaderCell.swift */, + A15C4D2524C5370C00ED0C0E /* HeaderCell.xib */, + ); + path = "Explorer View"; + sourceTree = ""; + }; + A15C4D2C24C543B100ED0C0E /* Frameworks */ = { + isa = PBXGroup; + children = ( + A15C4D2D24C543B100ED0C0E /* CloudKit.framework */, + 4AB1B9EC24CFFDF03E9A31BF /* Pods_CommunityMC3.framework */, + 86B7D30FBAD836876D4CFDB6 /* Pods_CommunityMC3_CommunityMC3UITests.framework */, + 53088E5DFD64AC02E18FE20F /* Pods_CommunityMC3Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + A1689CE724C7A69300A49732 /* SelectFile View */ = { + isa = PBXGroup; + children = ( + A124876C24CD0BEE00030723 /* SelectFileView.storyboard */, + A1689CEA24C7A6D300A49732 /* SelectFileView.swift */, + A1689D3224C7B14000A49732 /* SelectViewCell.swift */, + A124876924CD0BE400030723 /* SelectViewCell.xib */, + ); + path = "SelectFile View"; + sourceTree = ""; + }; + A1689D3D24C7D7EE00A49732 /* Manager */ = { + isa = PBXGroup; + children = ( + A1689D3624C7B5F200A49732 /* DataManager.swift */, + A134D29D24C8EA41009A054F /* FileManager.swift */, + EA6173F324DD02F500F18DCB /* TrackManager.swift */, + ); + path = Manager; + sourceTree = ""; + }; + A16B449624B2FBF200053D6C = { + isa = PBXGroup; + children = ( + A16B44A124B2FBF300053D6C /* CommunityMC3 */, + A16B44BA24B2FBF700053D6C /* CommunityMC3Tests */, + A16B44C524B2FBF700053D6C /* CommunityMC3UITests */, + A16B44A024B2FBF200053D6C /* Products */, + A15C4D2C24C543B100ED0C0E /* Frameworks */, + 3786B3E651FA0AF4F9A31D9C /* Pods */, + A12F370224D1C3BB002F31E0 /* Recovered References */, + ); + sourceTree = ""; + }; + A16B44A024B2FBF200053D6C /* Products */ = { + isa = PBXGroup; + children = ( + A16B449F24B2FBF200053D6C /* Allegro.app */, + A16B44B724B2FBF700053D6C /* CommunityMC3Tests.xctest */, + A16B44C224B2FBF700053D6C /* CommunityMC3UITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + A16B44A124B2FBF300053D6C /* CommunityMC3 */ = { + isa = PBXGroup; + children = ( + B798B3D824DB31DF009472F4 /* OnboardingScreen */, + A14B626624D09D5D0015223C /* Test File */, + B733E7F424CA7AFC00460E23 /* Profile View */, + EAE65B3224C7E214008B453D /* RandomSpotlightView */, + A121CE9B24C96C6D00E1D48B /* BonsaiTest */, + A11A9FD424C94A58008D7867 /* UploadFileView */, + A1689CE724C7A69300A49732 /* SelectFile View */, + A1E3FFEF24C6A8CB00CA2228 /* Cloud */, + A1432F5324C69879007656B1 /* Utilities */, + A1689D3D24C7D7EE00A49732 /* Manager */, + A134D2A124C908D3009A054F /* Data */, + EADBB5A824C5BB2F00CD2C92 /* VideoPlayer View */, + EA14E8FE24C557090021DF77 /* TrackPlayer View */, + A1C0EBB424C54EED008D8D8F /* Setting View */, + A1C0EBB324C54ED9008D8D8F /* Login View */, + A15C4D1424C5032700ED0C0E /* Favourites View */, + A15C4D1524C5033800ED0C0E /* SearchView */, + A1313E1224CA6DCB000DA7A7 /* NotificationView */, + A15C4D1624C5034A00ED0C0E /* Explorer View */, + A16B44A224B2FBF300053D6C /* AppDelegate.swift */, + A16B44A424B2FBF300053D6C /* SceneDelegate.swift */, + A124877124CD2A3600030723 /* Main Storyboard */, + A16B44AD24B2FBF600053D6C /* Assets.xcassets */, + A16B44AF24B2FBF600053D6C /* LaunchScreen.storyboard */, + A16B44B224B2FBF600053D6C /* Info.plist */, + A1A96B3524BFF12700EF12AB /* Localizable.strings */, + A15C4D1724C5038C00ED0C0E /* DB_Model.xcdatamodeld */, + A1CF317024C4B9E000E38E53 /* CommunityMC3.entitlements */, + ); + path = CommunityMC3; + sourceTree = ""; + }; + A16B44BA24B2FBF700053D6C /* CommunityMC3Tests */ = { + isa = PBXGroup; + children = ( + A16B44BB24B2FBF700053D6C /* CommunityMC3Tests.swift */, + A16B44BD24B2FBF700053D6C /* Info.plist */, + ); + path = CommunityMC3Tests; + sourceTree = ""; + }; + A16B44C524B2FBF700053D6C /* CommunityMC3UITests */ = { + isa = PBXGroup; + children = ( + A16B44C624B2FBF700053D6C /* CommunityMC3UITests.swift */, + A16B44C824B2FBF700053D6C /* Info.plist */, + ); + path = CommunityMC3UITests; + sourceTree = ""; + }; + A183FBDA24DB31B800FD248C /* GenreTableView */ = { + isa = PBXGroup; + children = ( + A183FBDB24DB31DF00FD248C /* GenreProfileTableViewCell.swift */, + A183FBDC24DB31DF00FD248C /* GenreProfileTableViewCell.xib */, + ); + path = GenreTableView; + sourceTree = ""; + }; + A1C0EBB324C54ED9008D8D8F /* Login View */ = { + isa = PBXGroup; + children = ( + A165068F24C7DCE4005822E7 /* RegisterController.swift */, + A1503D3924C4B79900AE317E /* LoginScreen.storyboard */, + A1503D3B24C4BA9B00AE317E /* LoginController.swift */, + A1DFB55F24E0921F00059286 /* ForgotPasswordController.swift */, + ); + path = "Login View"; + sourceTree = ""; + }; + A1C0EBB424C54EED008D8D8F /* Setting View */ = { + isa = PBXGroup; + children = ( + A183FBDA24DB31B800FD248C /* GenreTableView */, + A136C29E24D9C9FA0078F37E /* GenreCollectionView */, + A165069124C7DD46005822E7 /* SettingScreen.storyboard */, + A1A96B3724C050F100EF12AB /* SettingController.swift */, + A136C2A524D9CE5F0078F37E /* GenreProfileController.swift */, + ); + path = "Setting View"; + sourceTree = ""; + }; + A1E3FFEF24C6A8CB00CA2228 /* Cloud */ = { + isa = PBXGroup; + children = ( + A169E8A524CA9226000D815F /* UploadController.swift */, + A1E3FFED24C6A84500CA2228 /* Test.storyboard */, + A19C320324C8A7AC00A4506F /* DocumentTableViewController.swift */, + ); + path = Cloud; + sourceTree = ""; + }; + A1E76E4124CE1F9200D9415B /* UploadFileHeaderCell */ = { + isa = PBXGroup; + children = ( + A1E76E3C24CE1ADC00D9415B /* UploadFileHeaderCell.swift */, + A1E76E3D24CE1ADD00D9415B /* UploadFileHeaderCell.xib */, + ); + path = UploadFileHeaderCell; + sourceTree = ""; + }; + B733E7F424CA7AFC00460E23 /* Profile View */ = { + isa = PBXGroup; + children = ( + A136C2A724D9D95A0078F37E /* SwitchAccountTableView */, + EA63453324D925060045328C /* UploadPanel */, + B786384C24CEC28200952CF3 /* FirstPage Content */, + B786384D24CEC2B500952CF3 /* SecondPage Content */, + B733E7F524CA7B3700460E23 /* UserProfileView.storyboard */, + B733E7F724CA7B6100460E23 /* UserProfileVC.swift */, + B7C7302624CE944700B922B8 /* CarouselPageViewController.swift */, + A136C2B024D9DA4A0078F37E /* AccountController.swift */, + ); + path = "Profile View"; + sourceTree = ""; + }; + B74C59F824C6E35B00C978F3 /* Featured Videos */ = { + isa = PBXGroup; + children = ( + B74C59F924C6E38D00C978F3 /* FeaturedVideosCell.swift */, + B74C59FA24C6E38D00C978F3 /* FeaturedVideosCell.xib */, + B73C836224C7F8BC0047B4EC /* FeaturedVideosView.storyboard */, + B73C836424C7F8CC0047B4EC /* FeaturedVideosVC.swift */, + ); + path = "Featured Videos"; + sourceTree = ""; + }; + B786384C24CEC28200952CF3 /* FirstPage Content */ = { + isa = PBXGroup; + children = ( + B7BEA4F824D1460200AAB5C7 /* Social Media */, + B7BEA4F724D1460000AAB5C7 /* Contact Information */, + B7BEA4F624D145FC00AAB5C7 /* Music Genre */, + B786384E24CEC2F600952CF3 /* FirstPageVC.swift */, + B7BEA4F924D1466400AAB5C7 /* AboutHeaderCell.swift */, + B7BEA4FA24D1466500AAB5C7 /* AboutHeaderCell.xib */, + ); + path = "FirstPage Content"; + sourceTree = ""; + }; + B786384D24CEC2B500952CF3 /* SecondPage Content */ = { + isa = PBXGroup; + children = ( + B786385824CEEB6D00952CF3 /* Videos */, + B786385724CEEB6400952CF3 /* Photos */, + B786385624CEEB5900952CF3 /* Music */, + B786385024CEC30A00952CF3 /* SecondPageVC.swift */, + B786385224CEC41A00952CF3 /* ShowcaseHeaderCell.swift */, + B786385324CEC41A00952CF3 /* ShowcaseHeaderCell.xib */, + ); + path = "SecondPage Content"; + sourceTree = ""; + }; + B786385624CEEB5900952CF3 /* Music */ = { + isa = PBXGroup; + children = ( + B786385924CEEB8700952CF3 /* MusicTableViewCell.swift */, + B786385A24CEEB8700952CF3 /* MusicTableViewCell.xib */, + B786386D24CEECA400952CF3 /* ShowcaseMusicView.storyboard */, + B7D4B86224CEFEDB00FD30B2 /* ShowcaseMusicVC.swift */, + ); + path = Music; + sourceTree = ""; + }; + B786385724CEEB6400952CF3 /* Photos */ = { + isa = PBXGroup; + children = ( + B786386B24CEEC9900952CF3 /* ShowcasePhotosView.storyboard */, + B786387124CEECD500952CF3 /* ShowcasePhotosVC.swift */, + B7D4B86424CF076900FD30B2 /* PhotosTableViewCell.swift */, + B7D4B86524CF076900FD30B2 /* PhotosTableViewCell.xib */, + B7B6F3B924CFD133008BA503 /* PhotosCollectionCell.swift */, + B7B6F3BA24CFD133008BA503 /* PhotosCollectionCell.xib */, + ); + path = Photos; + sourceTree = ""; + }; + B786385824CEEB6D00952CF3 /* Videos */ = { + isa = PBXGroup; + children = ( + B786386124CEEBA100952CF3 /* VideosTableViewCell.swift */, + B786386224CEEBA100952CF3 /* VideosTableViewCell.xib */, + B786386924CEEC8500952CF3 /* ShowcaseVideoView.storyboard */, + B786386F24CEECC300952CF3 /* ShowcaseVideosVC.swift */, + ); + path = Videos; + sourceTree = ""; + }; + B798B3D824DB31DF009472F4 /* OnboardingScreen */ = { + isa = PBXGroup; + children = ( + B798B3DC24DB31F5009472F4 /* item */, + B798B3DA24DB31F5009472F4 /* CarouselPageViewController_.swift */, + B798B3D924DB31F5009472F4 /* CarouselViewController_.swift */, + B798B3DB24DB31F5009472F4 /* OnboardingScreen.storyboard */, + ); + path = OnboardingScreen; + sourceTree = ""; + }; + B798B3DC24DB31F5009472F4 /* item */ = { + isa = PBXGroup; + children = ( + B798B3DD24DB31F5009472F4 /* CarouselItem.xib */, + B798B3DE24DB31F5009472F4 /* CarouselItem.swift */, + ); + path = item; + sourceTree = ""; + }; + B7A0BADC24C6D49600292AA3 /* Latest Music */ = { + isa = PBXGroup; + children = ( + B7DAF5DD24C698B400FC6EFB /* LatestMusicCell.swift */, + B7DAF5DE24C698B400FC6EFB /* LatestMusicCell.xib */, + B758B53B24C7EFA200826CC5 /* LatestMusicView.storyboard */, + B758B53D24C7F33900826CC5 /* LatestMusicVC.swift */, + ); + path = "Latest Music"; + sourceTree = ""; + }; + B7A0BADD24C6D4B100292AA3 /* Discover New */ = { + isa = PBXGroup; + children = ( + B7DAF5D924C6919D00FC6EFB /* DiscoverNewCell.swift */, + B7DAF5DA24C6919D00FC6EFB /* DiscoverNewCell.xib */, + ); + path = "Discover New"; + sourceTree = ""; + }; + B7A0BADF24C6D4BA00292AA3 /* Trending Now */ = { + isa = PBXGroup; + children = ( + A15C4D2024C5367400ED0C0E /* TrendingNowCell.swift */, + A15C4D2124C5367400ED0C0E /* TrendingNowCell.xib */, + B74C59FF24C7070200C978F3 /* TrendingNowList.storyboard */, + B74C5A0524C714AF00C978F3 /* TrendingNowVC.swift */, + ); + path = "Trending Now"; + sourceTree = ""; + }; + B7A0BAE024C6D4D200292AA3 /* Featured Artists */ = { + isa = PBXGroup; + children = ( + B7DAF5E124C6A6EE00FC6EFB /* FeaturedArtistCell.swift */, + B7DAF5E224C6A6EE00FC6EFB /* FeaturedArtistCell.xib */, + B7DAF5E524C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.swift */, + B7DAF5E624C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.xib */, + B73C835E24C7F89C0047B4EC /* FeaturedArtistView.storyboard */, + B73C836024C7F8AC0047B4EC /* FeaturedArtistVC.swift */, + ); + path = "Featured Artists"; + sourceTree = ""; + }; + B7BEA4F624D145FC00AAB5C7 /* Music Genre */ = { + isa = PBXGroup; + children = ( + B7BEA4FD24D146C300AAB5C7 /* MusicGenreInfoCell.swift */, + B7BEA4FE24D146C300AAB5C7 /* MusicGenreInfoCell.xib */, + ); + path = "Music Genre"; + sourceTree = ""; + }; + B7BEA4F724D1460000AAB5C7 /* Contact Information */ = { + isa = PBXGroup; + children = ( + B7BEA50124D146E900AAB5C7 /* ContactInfoCell.swift */, + B7BEA50224D146E900AAB5C7 /* ContactInfoCell.xib */, + ); + path = "Contact Information"; + sourceTree = ""; + }; + B7BEA4F824D1460200AAB5C7 /* Social Media */ = { + isa = PBXGroup; + children = ( + B7BEA50524D146F500AAB5C7 /* SocialMediaCell.swift */, + B7BEA50624D146F500AAB5C7 /* SocialMediaCell.xib */, + ); + path = "Social Media"; + sourceTree = ""; + }; + B7ECE0DD24D02160008C4422 /* All Search */ = { + isa = PBXGroup; + children = ( + B7ECE0D324D0211C008C4422 /* AllSearchVC.swift */, + B7D0470324D070EA004A4D9C /* SearchHeaderSection.swift */, + B7D0470424D070EA004A4D9C /* SearchHeaderSection.xib */, + ); + path = "All Search"; + sourceTree = ""; + }; + B7ECE0DE24D0216F008C4422 /* Artist Search */ = { + isa = PBXGroup; + children = ( + B7ECE0D524D02128008C4422 /* ArtistSearchVC.swift */, + B703FE0E24D025C8001AD48E /* ArtistSearchCell.swift */, + B703FE0F24D025C8001AD48E /* ArtistSearchCell.xib */, + ); + path = "Artist Search"; + sourceTree = ""; + }; + B7ECE0DF24D02176008C4422 /* Music Search */ = { + isa = PBXGroup; + children = ( + B7ECE0D724D02133008C4422 /* MusicSearchVC.swift */, + B7BD5E3424D12465005918B7 /* MusicSearchCell.swift */, + B7BD5E3524D12465005918B7 /* MusicSearchCell.xib */, + ); + path = "Music Search"; + sourceTree = ""; + }; + B7ECE0E024D02188008C4422 /* Video Search */ = { + isa = PBXGroup; + children = ( + B7ECE0D924D02143008C4422 /* VideoSearchVC.swift */, + B703FE1624D025E8001AD48E /* VideoSearchCell.swift */, + B703FE1724D025E8001AD48E /* VideoSearchCell.xib */, + ); + path = "Video Search"; + sourceTree = ""; + }; + B7ECE0E124D0219E008C4422 /* Playlist Search */ = { + isa = PBXGroup; + children = ( + B7ECE0DB24D0214F008C4422 /* PlaylistSearchVC.swift */, + B703FE1A24D02654001AD48E /* PlaylistSearchCell.swift */, + B703FE1B24D02654001AD48E /* PlaylistSearchCell.xib */, + ); + path = "Playlist Search"; + sourceTree = ""; + }; + EA14E8FE24C557090021DF77 /* TrackPlayer View */ = { + isa = PBXGroup; + children = ( + EA650D5424C557680093EEE6 /* TrackPlayer.storyboard */, + EADBB5A424C560F300CD2C92 /* TrackPlayerViewController.swift */, + ); + path = "TrackPlayer View"; + sourceTree = ""; + }; + EA1BF07C24CA9DEF00CE1B8F /* RandomSpotlightCell */ = { + isa = PBXGroup; + children = ( + EA1BF07824CA9A9C00CE1B8F /* MusicGenreCell.swift */, + EA1BF07924CA9A9C00CE1B8F /* MusicGenreCell.xib */, + EA1BF07D24CA9EAD00CE1B8F /* MusicListCell.swift */, + EA1BF07E24CA9EAD00CE1B8F /* MusicListCell.xib */, + EA4A31CA24CAB2B6003DCDA4 /* VideoListCell.swift */, + EA4A31CB24CAB2B6003DCDA4 /* VideoListCell.xib */, + ); + path = RandomSpotlightCell; + sourceTree = ""; + }; + EA2D793424CFC6DE005998B4 /* FavoriteMenuCell */ = { + isa = PBXGroup; + children = ( + EA2D793524CFC725005998B4 /* FavoritesMenuCell.swift */, + EA2D793624CFC725005998B4 /* FavoritesMenuCell.xib */, + ); + path = FavoriteMenuCell; + sourceTree = ""; + }; + EA2D793924CFD5AD005998B4 /* FavoritesDetailCell */ = { + isa = PBXGroup; + children = ( + EA2D793A24CFD651005998B4 /* FavoriteTracksCell.swift */, + EA2D793B24CFD651005998B4 /* FavoriteTracksCell.xib */, + EA2D794824CFFD92005998B4 /* FavoriteVideosCell.swift */, + EA2D794924CFFD92005998B4 /* FavoriteVideosCell.xib */, + EA88AAA324D114FC007488F9 /* FavoriteArtistsCell.swift */, + EA88AAA424D114FC007488F9 /* FavoriteArtistsCell.xib */, + EA88AAAB24D12412007488F9 /* FavoriteAlbumsCell.swift */, + EA88AAAC24D12412007488F9 /* FavoriteAlbumsCell.xib */, + ); + path = FavoritesDetailCell; + sourceTree = ""; + }; + EA2D794224CFFC54005998B4 /* Storyboards */ = { + isa = PBXGroup; + children = ( + A14B626224D09B890015223C /* Favourites.storyboard */, + EA2D794024CFF4B1005998B4 /* FavoriteTracksView.storyboard */, + EA2D794424CFFCB0005998B4 /* FavoritesVideo.storyboard */, + EA88AA9F24D1128D007488F9 /* FavoriteArtist.storyboard */, + EA88AAA724D11EC1007488F9 /* FavoriteAlbums.storyboard */, + ); + path = Storyboards; + sourceTree = ""; + }; + EA2D794324CFFC65005998B4 /* ViewControllers */ = { + isa = PBXGroup; + children = ( + A14B626424D09B910015223C /* FavouritesView.swift */, + EA2D793E24CFD66A005998B4 /* FavoriteTracksView.swift */, + EA2D794624CFFD4F005998B4 /* FavoriteVideosView.swift */, + EA88AAA124D11482007488F9 /* FavoriteArtistsView.swift */, + EA88AAA924D11FF8007488F9 /* FavoriteAlbumsView.swift */, + ); + path = ViewControllers; + sourceTree = ""; + }; + EA62937824DA632700FDABB5 /* EditRandomizerTableCell */ = { + isa = PBXGroup; + children = ( + EA62938624DA827D00FDABB5 /* EditRandomizerContextCell.swift */, + EA62938724DA827D00FDABB5 /* EditRandomizerContextCell.xib */, + ); + path = EditRandomizerTableCell; + sourceTree = ""; + }; + EA62937D24DA650600FDABB5 /* HeaderCell */ = { + isa = PBXGroup; + children = ( + EA4A31C624CAB075003DCDA4 /* HeaderCellRandomSpotlight.swift */, + EA4A31C724CAB075003DCDA4 /* HeaderCellRandomSpotlight.xib */, + ); + path = HeaderCell; + sourceTree = ""; + }; + EA63453324D925060045328C /* UploadPanel */ = { + isa = PBXGroup; + children = ( + EA63453424D925510045328C /* UploadPanelViewController.swift */, + EA63453624D92A5B0045328C /* UploadPanelCell.swift */, + EA63453724D92A5B0045328C /* UploadPanelCell.xib */, + ); + path = UploadPanel; + sourceTree = ""; + }; + EADBB5A824C5BB2F00CD2C92 /* VideoPlayer View */ = { + isa = PBXGroup; + children = ( + EADBB5A924C5BB5000CD2C92 /* VideoPlayer.storyboard */, + EADBB5AB24C5BB6E00CD2C92 /* VideoPlayerViewController.swift */, + ); + path = "VideoPlayer View"; + sourceTree = ""; + }; + EAE65B3224C7E214008B453D /* RandomSpotlightView */ = { + isa = PBXGroup; + children = ( + EA62937D24DA650600FDABB5 /* HeaderCell */, + EA62937824DA632700FDABB5 /* EditRandomizerTableCell */, + EAE65B3324C7E69B008B453D /* RandomSpotlight.storyboard */, + EAE65B3524C7E964008B453D /* RandomSpotlightViewController.swift */, + EA62938A24DA834E00FDABB5 /* EditRandomizerViewController.swift */, + EA1BF07C24CA9DEF00CE1B8F /* RandomSpotlightCell */, + ); + path = RandomSpotlightView; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A16B449E24B2FBF200053D6C /* Allegro */ = { + isa = PBXNativeTarget; + buildConfigurationList = A16B44CB24B2FBF700053D6C /* Build configuration list for PBXNativeTarget "Allegro" */; + buildPhases = ( + 3542EBCB9805E4C1C03E5E05 /* [CP] Check Pods Manifest.lock */, + A16B449B24B2FBF200053D6C /* Sources */, + A16B449C24B2FBF200053D6C /* Frameworks */, + A16B449D24B2FBF200053D6C /* Resources */, + 1B09A17A7DCD79E90656E7AB /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Allegro; + productName = CommunityMC3; + productReference = A16B449F24B2FBF200053D6C /* Allegro.app */; + productType = "com.apple.product-type.application"; + }; + A16B44B624B2FBF700053D6C /* CommunityMC3Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A16B44CE24B2FBF700053D6C /* Build configuration list for PBXNativeTarget "CommunityMC3Tests" */; + buildPhases = ( + 28B66CAF998F934A91BA6918 /* [CP] Check Pods Manifest.lock */, + A16B44B324B2FBF700053D6C /* Sources */, + A16B44B424B2FBF700053D6C /* Frameworks */, + A16B44B524B2FBF700053D6C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + A16B44B924B2FBF700053D6C /* PBXTargetDependency */, + ); + name = CommunityMC3Tests; + productName = CommunityMC3Tests; + productReference = A16B44B724B2FBF700053D6C /* CommunityMC3Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + A16B44C124B2FBF700053D6C /* CommunityMC3UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A16B44D124B2FBF700053D6C /* Build configuration list for PBXNativeTarget "CommunityMC3UITests" */; + buildPhases = ( + C5D0ECC29E7CF2DCCE19DCC5 /* [CP] Check Pods Manifest.lock */, + A16B44BE24B2FBF700053D6C /* Sources */, + A16B44BF24B2FBF700053D6C /* Frameworks */, + A16B44C024B2FBF700053D6C /* Resources */, + 7FA5ACDB89B9AA35B4B0EDE9 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + A16B44C424B2FBF700053D6C /* PBXTargetDependency */, + ); + name = CommunityMC3UITests; + productName = CommunityMC3UITests; + productReference = A16B44C224B2FBF700053D6C /* CommunityMC3UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A16B449724B2FBF200053D6C /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1130; + LastUpgradeCheck = 1200; + ORGANIZATIONNAME = "Apple Developer Academy"; + TargetAttributes = { + A16B449E24B2FBF200053D6C = { + CreatedOnToolsVersion = 11.3.1; + }; + A16B44B624B2FBF700053D6C = { + CreatedOnToolsVersion = 11.3.1; + TestTargetID = A16B449E24B2FBF200053D6C; + }; + A16B44C124B2FBF700053D6C = { + CreatedOnToolsVersion = 11.3.1; + TestTargetID = A16B449E24B2FBF200053D6C; + }; + }; + }; + buildConfigurationList = A16B449A24B2FBF200053D6C /* Build configuration list for PBXProject "CommunityMC3" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + id, + ); + mainGroup = A16B449624B2FBF200053D6C; + productRefGroup = A16B44A024B2FBF200053D6C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A16B449E24B2FBF200053D6C /* Allegro */, + A16B44B624B2FBF700053D6C /* CommunityMC3Tests */, + A16B44C124B2FBF700053D6C /* CommunityMC3UITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A16B449D24B2FBF200053D6C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B7BEA50424D146E900AAB5C7 /* ContactInfoCell.xib in Resources */, + A124876724CD0BE400030723 /* SelectViewCell.xib in Resources */, + A15C4D2724C5370C00ED0C0E /* HeaderCell.xib in Resources */, + A1E76E3F24CE1ADD00D9415B /* UploadFileHeaderCell.xib in Resources */, + EA2D794524CFFCB0005998B4 /* FavoritesVideo.storyboard in Resources */, + B758B53C24C7EFA200826CC5 /* LatestMusicView.storyboard in Resources */, + B7BEA50024D146C300AAB5C7 /* MusicGenreInfoCell.xib in Resources */, + A183FBDE24DB31DF00FD248C /* GenreProfileTableViewCell.xib in Resources */, + B74C59FC24C6E38D00C978F3 /* FeaturedVideosCell.xib in Resources */, + EA1BF08024CA9EAD00CE1B8F /* MusicListCell.xib in Resources */, + A136C2A424D9CADA0078F37E /* GenreProfileCollectionViewCell.xib in Resources */, + A16B44B124B2FBF600053D6C /* LaunchScreen.storyboard in Resources */, + A11A9FF424C94A58008D7867 /* AddCoverTableViewCell.xib in Resources */, + A1A96B3324BFF12700EF12AB /* Localizable.strings in Resources */, + A15C4D1B24C5300A00ED0C0E /* Explorer.storyboard in Resources */, + A1E3FFEE24C6A84500CA2228 /* Test.storyboard in Resources */, + A11A9FEE24C94A58008D7867 /* descTitleTableViewCell.xib in Resources */, + B733E7F624CA7B3700460E23 /* UserProfileView.storyboard in Resources */, + EA63453924D92A5B0045328C /* UploadPanelCell.xib in Resources */, + B786385C24CEEB8700952CF3 /* MusicTableViewCell.xib in Resources */, + EA88AAA624D114FC007488F9 /* FavoriteArtistsCell.xib in Resources */, + A121CE9F24C96C6D00E1D48B /* SmallViewController.storyboard in Resources */, + A11A9FE824C94A58008D7867 /* albumTitleTableViewCell.xib in Resources */, + A14B626324D09B8A0015223C /* Favourites.storyboard in Resources */, + A11A9FF024C94A58008D7867 /* UploadFileView.storyboard in Resources */, + B73C836324C7F8BC0047B4EC /* FeaturedVideosView.storyboard in Resources */, + EA2D794B24CFFD92005998B4 /* FavoriteVideosCell.xib in Resources */, + EA88AAA824D11EC1007488F9 /* FavoriteAlbums.storyboard in Resources */, + A16B44AE24B2FBF600053D6C /* Assets.xcassets in Resources */, + B786386424CEEBA100952CF3 /* VideosTableViewCell.xib in Resources */, + A136C2AB24D9D9BB0078F37E /* SwitchAccountTableViewCell.xib in Resources */, + B7BD5E3724D12465005918B7 /* MusicSearchCell.xib in Resources */, + B703FE1D24D02654001AD48E /* PlaylistSearchCell.xib in Resources */, + B786385524CEC41A00952CF3 /* ShowcaseHeaderCell.xib in Resources */, + EA1BF07B24CA9A9C00CE1B8F /* MusicGenreCell.xib in Resources */, + A1503D3A24C4B79900AE317E /* LoginScreen.storyboard in Resources */, + EA4A31C924CAB075003DCDA4 /* HeaderCellRandomSpotlight.xib in Resources */, + A136C2AF24D9DA100078F37E /* AddAccountTableViewCell.xib in Resources */, + B786386A24CEEC8500952CF3 /* ShowcaseVideoView.storyboard in Resources */, + EADBB5AA24C5BB5000CD2C92 /* VideoPlayer.storyboard in Resources */, + A11A9FF224C94A58008D7867 /* UploadTableViewCell.xib in Resources */, + EA88AAAE24D12412007488F9 /* FavoriteAlbumsCell.xib in Resources */, + B7BEA50824D146F500AAB5C7 /* SocialMediaCell.xib in Resources */, + B7DAF5E024C698B400FC6EFB /* LatestMusicCell.xib in Resources */, + B7BEA4FC24D1466500AAB5C7 /* AboutHeaderCell.xib in Resources */, + A11A9FEA24C94A58008D7867 /* albumListTableViewCell.xib in Resources */, + B7DAF5E824C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.xib in Resources */, + B7DAF5E424C6A6EE00FC6EFB /* FeaturedArtistCell.xib in Resources */, + B7B6F3BC24CFD133008BA503 /* PhotosCollectionCell.xib in Resources */, + EA71357E24CE9A140073A8EA /* tiara.mp3 in Resources */, + B798B3E124DB31F6009472F4 /* OnboardingScreen.storyboard in Resources */, + B7D0470624D070EA004A4D9C /* SearchHeaderSection.xib in Resources */, + B74C5A0024C7070200C978F3 /* TrendingNowList.storyboard in Resources */, + A16B44AC24B2FBF300053D6C /* Main.storyboard in Resources */, + EAE65B3424C7E69B008B453D /* RandomSpotlight.storyboard in Resources */, + EA4A31CD24CAB2B6003DCDA4 /* VideoListCell.xib in Resources */, + EA71357C24CE9A140073A8EA /* yorushika.mp3 in Resources */, + B703FE1924D025E8001AD48E /* VideoSearchCell.xib in Resources */, + A165069224C7DD46005822E7 /* SettingScreen.storyboard in Resources */, + A15C4D2324C5367400ED0C0E /* TrendingNowCell.xib in Resources */, + EA71357D24CE9A140073A8EA /* dishes.mp3 in Resources */, + B786386E24CEECA400952CF3 /* ShowcaseMusicView.storyboard in Resources */, + B73C835F24C7F89C0047B4EC /* FeaturedArtistView.storyboard in Resources */, + EA88AAA024D1128D007488F9 /* FavoriteArtist.storyboard in Resources */, + A11A9FED24C94A58008D7867 /* GenreTableViewCell.xib in Resources */, + EA2D793D24CFD651005998B4 /* FavoriteTracksCell.xib in Resources */, + B7DAF5DC24C6919D00FC6EFB /* DiscoverNewCell.xib in Resources */, + B74C5A0424C713DD00C978F3 /* Notifications.storyboard in Resources */, + B7D4B86724CF076900FD30B2 /* PhotosTableViewCell.xib in Resources */, + B798B3E224DB31F6009472F4 /* CarouselItem.xib in Resources */, + A15C4D1024C502EF00ED0C0E /* Search.storyboard in Resources */, + B786386C24CEEC9900952CF3 /* ShowcasePhotosView.storyboard in Resources */, + EA650D5524C557680093EEE6 /* TrackPlayer.storyboard in Resources */, + EA62938924DA827D00FDABB5 /* EditRandomizerContextCell.xib in Resources */, + B703FE1124D025C8001AD48E /* ArtistSearchCell.xib in Resources */, + EA2D794124CFF4B1005998B4 /* FavoriteTracksView.storyboard in Resources */, + EA2D793824CFC725005998B4 /* FavoritesMenuCell.xib in Resources */, + A124876A24CD0BEE00030723 /* SelectFileView.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A16B44B524B2FBF700053D6C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A16B44C024B2FBF700053D6C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 1B09A17A7DCD79E90656E7AB /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 28B66CAF998F934A91BA6918 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-CommunityMC3Tests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3542EBCB9805E4C1C03E5E05 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-CommunityMC3-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 7FA5ACDB89B9AA35B4B0EDE9 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + C5D0ECC29E7CF2DCCE19DCC5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-CommunityMC3-CommunityMC3UITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A16B449B24B2FBF200053D6C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A14B626824D0D3830015223C /* CloudKitUtil.swift in Sources */, + EAE65B3624C7E964008B453D /* RandomSpotlightViewController.swift in Sources */, + A121CE9E24C96C6D00E1D48B /* SmallViewController.swift in Sources */, + EA1BF07A24CA9A9C00CE1B8F /* MusicGenreCell.swift in Sources */, + B786387024CEECC300952CF3 /* ShowcaseVideosVC.swift in Sources */, + B7ECE0D424D0211C008C4422 /* AllSearchVC.swift in Sources */, + B7D0470524D070EA004A4D9C /* SearchHeaderSection.swift in Sources */, + B7DAF5E724C6AA4A00FC6EFB /* FeaturedArtistCollectionCell.swift in Sources */, + EA2D793F24CFD66A005998B4 /* FavoriteTracksView.swift in Sources */, + B74C5A0624C714AF00C978F3 /* TrendingNowVC.swift in Sources */, + EA2D794724CFFD4F005998B4 /* FavoriteVideosView.swift in Sources */, + B73C836124C7F8AC0047B4EC /* FeaturedArtistVC.swift in Sources */, + A194A9E524DDA25900C9E87D /* StringExtension.swift in Sources */, + B7ECE0DC24D0214F008C4422 /* PlaylistSearchVC.swift in Sources */, + A136C2A324D9CADA0078F37E /* GenreProfileCollectionViewCell.swift in Sources */, + B74C5A0224C711FA00C978F3 /* NotificationsVC.swift in Sources */, + B703FE1824D025E8001AD48E /* VideoSearchCell.swift in Sources */, + B7BEA50724D146F500AAB5C7 /* SocialMediaCell.swift in Sources */, + A1A96B3824C050F100EF12AB /* SettingController.swift in Sources */, + EA2D793C24CFD651005998B4 /* FavoriteTracksCell.swift in Sources */, + A136C2A624D9CE5F0078F37E /* GenreProfileController.swift in Sources */, + A1824D9C24C7E45600C68182 /* UIViewControllerExtension.swift in Sources */, + EA63453824D92A5B0045328C /* UploadPanelCell.swift in Sources */, + A1689CEB24C7A6D300A49732 /* SelectFileView.swift in Sources */, + B74C59FB24C6E38D00C978F3 /* FeaturedVideosCell.swift in Sources */, + EA62938824DA827D00FDABB5 /* EditRandomizerContextCell.swift in Sources */, + A134D2AF24C91BDB009A054F /* Videos+Extension.swift in Sources */, + B7BD5E3624D12465005918B7 /* MusicSearchCell.swift in Sources */, + A15C4D2224C5367400ED0C0E /* TrendingNowCell.swift in Sources */, + A1432F5524C69958007656B1 /* ImagePicker.swift in Sources */, + B798B3DF24DB31F6009472F4 /* CarouselViewController_.swift in Sources */, + A136C2AA24D9D9BB0078F37E /* SwitchAccountTableViewCell.swift in Sources */, + A11A9FEF24C94A58008D7867 /* descTitleTableViewCell.swift in Sources */, + A134D2A924C91BBC009A054F /* Track+Extension.swift in Sources */, + A134D2A524C91B99009A054F /* Favourites+Extension.swift in Sources */, + EA88AAA224D11482007488F9 /* FavoriteArtistsView.swift in Sources */, + A11A9FF124C94A58008D7867 /* UploadTableViewCell.swift in Sources */, + EA4A31CC24CAB2B6003DCDA4 /* VideoListCell.swift in Sources */, + EA2D794A24CFFD92005998B4 /* FavoriteVideosCell.swift in Sources */, + B7ECE0DA24D02143008C4422 /* VideoSearchVC.swift in Sources */, + A124877324CD2AC500030723 /* MainTabController.swift in Sources */, + B7DAF5E324C6A6EE00FC6EFB /* FeaturedArtistCell.swift in Sources */, + B703FE1024D025C8001AD48E /* ArtistSearchCell.swift in Sources */, + B786385B24CEEB8700952CF3 /* MusicTableViewCell.swift in Sources */, + A16B44A924B2FBF300053D6C /* SearchView.swift in Sources */, + B73C836524C7F8CC0047B4EC /* FeaturedVideosVC.swift in Sources */, + B7BEA50324D146E900AAB5C7 /* ContactInfoCell.swift in Sources */, + A11A9FEC24C94A58008D7867 /* GenreTableViewCell.swift in Sources */, + B7D4B86624CF076900FD30B2 /* PhotosTableViewCell.swift in Sources */, + B7C7302724CE944700B922B8 /* CarouselPageViewController.swift in Sources */, + A16B44A724B2FBF300053D6C /* ExplorerView.swift in Sources */, + A134D2AD24C91BD4009A054F /* UserData+Extension.swift in Sources */, + B733E7F824CA7B6100460E23 /* UserProfileVC.swift in Sources */, + EA88AAAD24D12412007488F9 /* FavoriteAlbumsCell.swift in Sources */, + B798B3E324DB31F6009472F4 /* CarouselItem.swift in Sources */, + A17C3C6924CCA3C500153493 /* Constant.swift in Sources */, + A134D2A724C91BAB009A054F /* Photos+Extension.swift in Sources */, + B7B6F3BB24CFD133008BA503 /* PhotosCollectionCell.swift in Sources */, + A15C4D2624C5370C00ED0C0E /* HeaderCell.swift in Sources */, + A136C2B124D9DA4A0078F37E /* AccountController.swift in Sources */, + EA88AAAA24D11FF8007488F9 /* FavoriteAlbumsView.swift in Sources */, + B703FE1C24D02654001AD48E /* PlaylistSearchCell.swift in Sources */, + B7ECE0D624D02128008C4422 /* ArtistSearchVC.swift in Sources */, + A1E76E3E24CE1ADD00D9415B /* UploadFileHeaderCell.swift in Sources */, + A11A9FE924C94A58008D7867 /* albumTitleTableViewCell.swift in Sources */, + A134D29E24C8EA41009A054F /* FileManager.swift in Sources */, + A194A9E724DDA87B00C9E87D /* UIViewExtension.swift in Sources */, + B786385124CEC30A00952CF3 /* SecondPageVC.swift in Sources */, + A11A9FE724C94A58008D7867 /* albumListTableViewCell.swift in Sources */, + A1689D3924C7D67700A49732 /* AlertViewHelper.swift in Sources */, + EA4A31C824CAB075003DCDA4 /* HeaderCellRandomSpotlight.swift in Sources */, + B7D4B86324CEFEDB00FD30B2 /* ShowcaseMusicVC.swift in Sources */, + B786387224CEECD500952CF3 /* ShowcasePhotosVC.swift in Sources */, + A1689D3724C7B5F200A49732 /* DataManager.swift in Sources */, + A12F370424D23C02002F31E0 /* Utilities.swift in Sources */, + A136C2AE24D9DA100078F37E /* AddAccountTableViewCell.swift in Sources */, + A134D2A024C907B4009A054F /* Featured+Extension.swift in Sources */, + A11A9FF324C94A58008D7867 /* AddCoverTableViewCell.swift in Sources */, + A16B44A324B2FBF300053D6C /* AppDelegate.swift in Sources */, + B758B53E24C7F33900826CC5 /* LatestMusicVC.swift in Sources */, + EA63453524D925510045328C /* UploadPanelViewController.swift in Sources */, + B786386324CEEBA100952CF3 /* VideosTableViewCell.swift in Sources */, + A134D2AB24C91BC9009A054F /* UploadedData+Extension.swift in Sources */, + A1689D3424C7B14000A49732 /* SelectViewCell.swift in Sources */, + A19C320424C8A7AC00A4506F /* DocumentTableViewController.swift in Sources */, + EA88AAA524D114FC007488F9 /* FavoriteArtistsCell.swift in Sources */, + A183FBDD24DB31DF00FD248C /* GenreProfileTableViewCell.swift in Sources */, + EA65FF4E24DBC93200B3FAE1 /* StartViewController.swift in Sources */, + A11A9FEB24C94A58008D7867 /* UploadFileView.swift in Sources */, + A1689D3B24C7D76500A49732 /* CoreDataHelper.swift in Sources */, + B7ECE0D824D02133008C4422 /* MusicSearchVC.swift in Sources */, + A19C320224C89FF100A4506F /* FileSystemManager.swift in Sources */, + A125311E24CE89C30038B215 /* UIImageExtension.swift in Sources */, + A16B44A524B2FBF300053D6C /* SceneDelegate.swift in Sources */, + A134D2A324C908F3009A054F /* Album+Extension.swift in Sources */, + A1DFB56024E0921F00059286 /* ForgotPasswordController.swift in Sources */, + EA65FF5024DBC94500B3FAE1 /* MiniTrackPlayerController.swift in Sources */, + A15C4D1924C5038C00ED0C0E /* DB_Model.xcdatamodeld in Sources */, + A19ACB6E24D0FB45009027B1 /* AlbumSelectorVC.swift in Sources */, + B7BEA4FB24D1466500AAB5C7 /* AboutHeaderCell.swift in Sources */, + EA6173F424DD02F500F18DCB /* TrackManager.swift in Sources */, + B7BEA4FF24D146C300AAB5C7 /* MusicGenreInfoCell.swift in Sources */, + B798B3E024DB31F6009472F4 /* CarouselPageViewController_.swift in Sources */, + EA1BF07F24CA9EAD00CE1B8F /* MusicListCell.swift in Sources */, + B7ECE0D224D01E9E008C4422 /* SearchContainerPageVC.swift in Sources */, + B7DAF5DB24C6919D00FC6EFB /* DiscoverNewCell.swift in Sources */, + EADBB5AC24C5BB6E00CD2C92 /* VideoPlayerViewController.swift in Sources */, + EA2D793724CFC725005998B4 /* FavoritesMenuCell.swift in Sources */, + A1824D9A24C7E3E200C68182 /* Account+Extension.swift in Sources */, + A1503D3C24C4BA9B00AE317E /* LoginController.swift in Sources */, + B786385424CEC41A00952CF3 /* ShowcaseHeaderCell.swift in Sources */, + A169E8A624CA9226000D815F /* UploadController.swift in Sources */, + B7DAF5DF24C698B400FC6EFB /* LatestMusicCell.swift in Sources */, + B786384F24CEC2F600952CF3 /* FirstPageVC.swift in Sources */, + EADBB5A524C560F300CD2C92 /* TrackPlayerViewController.swift in Sources */, + EA62938B24DA834E00FDABB5 /* EditRandomizerViewController.swift in Sources */, + A14B626524D09B910015223C /* FavouritesView.swift in Sources */, + A165069024C7DCE4005822E7 /* RegisterController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A16B44B324B2FBF700053D6C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A16B44BC24B2FBF700053D6C /* CommunityMC3Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A16B44BE24B2FBF700053D6C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A16B44C724B2FBF700053D6C /* CommunityMC3UITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + A16B44B924B2FBF700053D6C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = A16B449E24B2FBF200053D6C /* Allegro */; + targetProxy = A16B44B824B2FBF700053D6C /* PBXContainerItemProxy */; + }; + A16B44C424B2FBF700053D6C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = A16B449E24B2FBF200053D6C /* Allegro */; + targetProxy = A16B44C324B2FBF700053D6C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + A124876924CD0BE400030723 /* SelectViewCell.xib */ = { + isa = PBXVariantGroup; + children = ( + A124876824CD0BE400030723 /* Base */, + ); + name = SelectViewCell.xib; + sourceTree = ""; + }; + A124876C24CD0BEE00030723 /* SelectFileView.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A124876B24CD0BEE00030723 /* Base */, + ); + name = SelectFileView.storyboard; + sourceTree = ""; + }; + A16B44AA24B2FBF300053D6C /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A16B44AB24B2FBF300053D6C /* Base */, + A1A96B2F24BFEFD400EF12AB /* id */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + A16B44AF24B2FBF600053D6C /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A16B44B024B2FBF600053D6C /* Base */, + A1A96B3024BFEFD400EF12AB /* id */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + A1A96B3524BFF12700EF12AB /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + A1A96B3424BFF12700EF12AB /* id */, + A1A96B3624BFF14400EF12AB /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + A16B44C924B2FBF700053D6C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + A16B44CA24B2FBF700053D6C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + A16B44CC24B2FBF700053D6C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 019A560054AEFAF9141EE53F /* Pods-CommunityMC3.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = CommunityMC3/CommunityMC3.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 7; + DEVELOPMENT_TEAM = 7D734D7EN3; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/CommunityMC3/libs", + ); + INFOPLIST_FILE = CommunityMC3/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0.0; + PRODUCT_BUNDLE_IDENTIFIER = ada.mc3.music; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = MusicCommunity; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + A16B44CD24B2FBF700053D6C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5609308099ECFB57AB0C371F /* Pods-CommunityMC3.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = CommunityMC3/CommunityMC3.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 7; + DEVELOPMENT_TEAM = 7D734D7EN3; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/CommunityMC3/libs", + ); + INFOPLIST_FILE = CommunityMC3/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0.0; + PRODUCT_BUNDLE_IDENTIFIER = ada.mc3.music; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = MusicCommunity; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; + A16B44CF24B2FBF700053D6C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 30DFE041381608564EB18E8D /* Pods-CommunityMC3Tests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 7D734D7EN3; + INFOPLIST_FILE = CommunityMC3Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.herokuapp.CommunityMC3Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CommunityMC3.app/CommunityMC3"; + }; + name = Debug; + }; + A16B44D024B2FBF700053D6C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 64E3FBC18FCDD9176F27A578 /* Pods-CommunityMC3Tests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 7D734D7EN3; + INFOPLIST_FILE = CommunityMC3Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.herokuapp.CommunityMC3Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CommunityMC3.app/CommunityMC3"; + }; + name = Release; + }; + A16B44D224B2FBF700053D6C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8A8733AF0E9CC638EA6B0781 /* Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = CommunityMC3UITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.herokuapp.CommunityMC3UITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CommunityMC3; + }; + name = Debug; + }; + A16B44D324B2FBF700053D6C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B99D5A48E4347EB77E44214C /* Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = CommunityMC3UITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.herokuapp.CommunityMC3UITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CommunityMC3; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A16B449A24B2FBF200053D6C /* Build configuration list for PBXProject "CommunityMC3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A16B44C924B2FBF700053D6C /* Debug */, + A16B44CA24B2FBF700053D6C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A16B44CB24B2FBF700053D6C /* Build configuration list for PBXNativeTarget "Allegro" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A16B44CC24B2FBF700053D6C /* Debug */, + A16B44CD24B2FBF700053D6C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A16B44CE24B2FBF700053D6C /* Build configuration list for PBXNativeTarget "CommunityMC3Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A16B44CF24B2FBF700053D6C /* Debug */, + A16B44D024B2FBF700053D6C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A16B44D124B2FBF700053D6C /* Build configuration list for PBXNativeTarget "CommunityMC3UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A16B44D224B2FBF700053D6C /* Debug */, + A16B44D324B2FBF700053D6C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + A15C4D1724C5038C00ED0C0E /* DB_Model.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + A15C4D1824C5038C00ED0C0E /* DB_Model.xcdatamodel */, + ); + currentVersion = A15C4D1824C5038C00ED0C0E /* DB_Model.xcdatamodel */; + path = DB_Model.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ + }; + rootObject = A16B449724B2FBF200053D6C /* Project object */; +} diff --git a/frontend/mobile/CommunityMC3.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/frontend/mobile/CommunityMC3.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c8ec8d4 --- /dev/null +++ b/frontend/mobile/CommunityMC3.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/frontend/mobile/CommunityMC3.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/frontend/mobile/CommunityMC3.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/frontend/mobile/CommunityMC3.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/frontend/mobile/CommunityMC3.xcodeproj/xcshareddata/xcschemes/Allegro.xcscheme b/frontend/mobile/CommunityMC3.xcodeproj/xcshareddata/xcschemes/Allegro.xcscheme new file mode 100644 index 0000000..c3909c7 --- /dev/null +++ b/frontend/mobile/CommunityMC3.xcodeproj/xcshareddata/xcschemes/Allegro.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3.xcworkspace/contents.xcworkspacedata b/frontend/mobile/CommunityMC3.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..843b77f --- /dev/null +++ b/frontend/mobile/CommunityMC3.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/frontend/mobile/CommunityMC3.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/frontend/mobile/CommunityMC3.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/frontend/mobile/CommunityMC3.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/frontend/mobile/CommunityMC3/AppDelegate.swift b/frontend/mobile/CommunityMC3/AppDelegate.swift new file mode 100644 index 0000000..0d2e93a --- /dev/null +++ b/frontend/mobile/CommunityMC3/AppDelegate.swift @@ -0,0 +1,129 @@ +// +// AppDelegate.swift +// CommunityMC3 +// +// Created by Bryanza on 06/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import CoreData +import CloudKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + let launchStoryboard = UIStoryboard(name: "OnboardingScreen", bundle: nil) + let mainStoryboard = UIStoryboard(name: "Main", bundle: nil) + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + let launchedBefore = UserDefaults.standard.bool(forKey: "hasLaunched") + self.window = UIWindow(frame: UIScreen.main.bounds) + + + var vc: UIViewController + + if launchedBefore + { + vc = mainStoryboard.instantiateInitialViewController()! + } + else + { + vc = launchStoryboard.instantiateViewController(identifier: "OnboardingVC") + } + + UserDefaults.standard.set(true, forKey: "hasLaunched") + + self.window?.rootViewController = vc + self.window?.makeKeyAndVisible() + + DataManager.shared() + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + // lazy var persistentContainer: NSPersistentContainer = { + // let container = NSPersistentContainer(name: "AccountModel") + // container.loadPersistentStores(completionHandler: { (storeDescription, error) in + // if let error = error as NSError?{ + // //Error Condition + // } + // }) + // return container + // }() + + // MARK: - Core Data stack + + lazy var persistentContainer: NSPersistentCloudKitContainer = { + /* + The persistent container for the application. This implementation + creates and returns a container, having loaded the store for the + application to it. This property is optional since there are legitimate + error conditions that could cause the creation of the store to fail. + */ + let container = NSPersistentCloudKitContainer(name: "DB_Model") + container.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error as NSError? { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + /* + Typical reasons for an error here include: + * The parent directory does not exist, cannot be created, or disallows writing. + * The persistent store is not accessible, due to permissions or data protection when the device is locked. + * The device is out of space. + * The store could not be migrated to the current model version. + Check the error message to determine what the actual problem was. + */ + fatalError("Unresolved error \(error), \(error.userInfo)") + } + }) + return container + }() + + static var persistentContainer: NSPersistentContainer { + return (UIApplication.shared.delegate as! AppDelegate).persistentContainer + } + + static var viewContext: NSManagedObjectContext { + let viewContext = persistentContainer.viewContext + viewContext.automaticallyMergesChangesFromParent = true + return viewContext + } + + // MARK: - Core Data Saving support + + func saveContext () { + let context = persistentContainer.viewContext + if context.hasChanges { + do { + try context.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nserror = error as NSError + fatalError("Unresolved error \(nserror), \(nserror.userInfo)") + } + } + } + + +} + diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Contents 2.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Contents 2.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..eaecd91 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "filename" : "icon_20pt@2x-1.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "icon_20pt@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "filename" : "icon_29pt@2x-1.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "icon_29pt@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "filename" : "icon_40pt@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "icon_40pt@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "filename" : "icon_60pt@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "filename" : "icon_60pt@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "filename" : "icon_20pt.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "filename" : "icon_20pt@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "icon_29pt.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "filename" : "icon_29pt@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "icon_40pt.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "filename" : "icon_40pt@2x-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "icon_76pt.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "filename" : "icon_76pt@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "filename" : "icon_83.5@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "filename" : "Icon.png", + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Icon.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Icon.png new file mode 100644 index 0000000..1cce5bc Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/Icon.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt.png new file mode 100644 index 0000000..5dfb0ce Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png new file mode 100644 index 0000000..d6f0690 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png new file mode 100644 index 0000000..d6f0690 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png new file mode 100644 index 0000000..63e143a Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt.png new file mode 100644 index 0000000..19dbafe Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png new file mode 100644 index 0000000..ae48130 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png new file mode 100644 index 0000000..ae48130 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png new file mode 100644 index 0000000..eef2c37 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt.png new file mode 100644 index 0000000..d6f0690 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png new file mode 100644 index 0000000..942a53c Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png new file mode 100644 index 0000000..942a53c Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png new file mode 100644 index 0000000..0b01897 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png new file mode 100644 index 0000000..0b01897 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png new file mode 100644 index 0000000..52be78b Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_76pt.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_76pt.png new file mode 100644 index 0000000..d3d1009 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_76pt.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png new file mode 100644 index 0000000..13b013d Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png new file mode 100644 index 0000000..04072fa Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Contents 2.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Contents 2.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/Contents 2.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/Contents 2.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/Contents 2.json new file mode 100644 index 0000000..abb25df --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/Contents.json new file mode 100644 index 0000000..abb25df --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/artist-1 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/artist-1 2.png new file mode 100644 index 0000000..4a9e9eb Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/artist-1 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/artist-1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/artist-1.png new file mode 100644 index 0000000..4a9e9eb Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-1.imageset/artist-1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/Contents 2.json new file mode 100644 index 0000000..3fe6bb5 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/Contents.json new file mode 100644 index 0000000..3fe6bb5 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/artist-2 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/artist-2 2.png new file mode 100644 index 0000000..5d11ef2 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/artist-2 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/artist-2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/artist-2.png new file mode 100644 index 0000000..5d11ef2 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-2.imageset/artist-2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/Contents 2.json new file mode 100644 index 0000000..6b65bb9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-3.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/Contents.json new file mode 100644 index 0000000..6b65bb9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-3.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/artist-3 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/artist-3 2.png new file mode 100644 index 0000000..e182cea Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/artist-3 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/artist-3.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/artist-3.png new file mode 100644 index 0000000..e182cea Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-3.imageset/artist-3.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/Contents 2.json new file mode 100644 index 0000000..6b44ceb --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-4.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/Contents.json new file mode 100644 index 0000000..6b44ceb --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-4.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/artist-4 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/artist-4 2.png new file mode 100644 index 0000000..1996a15 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/artist-4 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/artist-4.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/artist-4.png new file mode 100644 index 0000000..1996a15 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-4.imageset/artist-4.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/Contents 2.json new file mode 100644 index 0000000..0760b28 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-5.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/Contents.json new file mode 100644 index 0000000..0760b28 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-5.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/artist-5 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/artist-5 2.png new file mode 100644 index 0000000..087e7d7 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/artist-5 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/artist-5.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/artist-5.png new file mode 100644 index 0000000..087e7d7 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Featured artists/artist-5.imageset/artist-5.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/HeartFill.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartFill.imageset/Contents.json new file mode 100644 index 0000000..f89706c --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartFill.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "HeartFill.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/HeartFill.imageset/HeartFill.png b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartFill.imageset/HeartFill.png new file mode 100644 index 0000000..5821262 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartFill.imageset/HeartFill.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/HeartUnfill.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartUnfill.imageset/Contents.json new file mode 100644 index 0000000..446d6be --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartUnfill.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/HeartUnfill.imageset/Vector.png b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartUnfill.imageset/Vector.png new file mode 100644 index 0000000..108fb15 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/HeartUnfill.imageset/Vector.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 1.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 1.imageset/Contents.json new file mode 100644 index 0000000..688719a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Onboarding BG 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 1.imageset/Onboarding BG 1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 1.imageset/Onboarding BG 1.png new file mode 100644 index 0000000..dc7c3cd Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 1.imageset/Onboarding BG 1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 2.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 2.imageset/Contents.json new file mode 100644 index 0000000..3ce3189 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Onboarding BG 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 2.imageset/Onboarding BG 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 2.imageset/Onboarding BG 2.png new file mode 100644 index 0000000..b4a2e5a Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 2.imageset/Onboarding BG 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 3.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 3.imageset/Contents.json new file mode 100644 index 0000000..fd69a88 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Onboarding BG 3.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 3.imageset/Onboarding BG 3.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 3.imageset/Onboarding BG 3.png new file mode 100644 index 0000000..ea1f679 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Onboarding BG 3.imageset/Onboarding BG 3.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/PlayButtonFullColor.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/PlayButtonFullColor.imageset/Contents.json new file mode 100644 index 0000000..d8ef38b --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/PlayButtonFullColor.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PlayButtonFullColor.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/PlayButtonFullColor.imageset/PlayButtonFullColor.png b/frontend/mobile/CommunityMC3/Assets.xcassets/PlayButtonFullColor.imageset/PlayButtonFullColor.png new file mode 100644 index 0000000..7bdd1a8 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/PlayButtonFullColor.imageset/PlayButtonFullColor.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Primary.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Primary.imageset/Contents.json new file mode 100644 index 0000000..16d82ff --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Primary.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Primary.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Primary.imageset/Primary.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Primary.imageset/Primary.png new file mode 100644 index 0000000..1de07b5 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Primary.imageset/Primary.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Effect Circle.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Effect Circle.imageset/Contents.json new file mode 100644 index 0000000..7ba69b1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Effect Circle.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Effect Circle.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Effect Circle.imageset/Effect Circle.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Effect Circle.imageset/Effect Circle.png new file mode 100644 index 0000000..d0ff5dd Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Effect Circle.imageset/Effect Circle.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Mask Group.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Mask Group.imageset/Contents.json new file mode 100644 index 0000000..5706470 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Mask Group.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Mask Group.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Mask Group.imageset/Mask Group.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Mask Group.imageset/Mask Group.png new file mode 100644 index 0000000..7e8e796 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Mask Group.imageset/Mask Group.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Outer Effect.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Outer Effect.imageset/Contents.json new file mode 100644 index 0000000..349e45b --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Outer Effect.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Outer Effect.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Outer Effect.imageset/Outer Effect.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Outer Effect.imageset/Outer Effect.png new file mode 100644 index 0000000..8a3c2a0 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Random Spotlight Assets/Outer Effect.imageset/Outer Effect.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Stop.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Stop.imageset/Contents.json new file mode 100644 index 0000000..ce2fc00 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Stop.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Stop.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Stop.imageset/Stop.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Stop.imageset/Stop.png new file mode 100644 index 0000000..cc95a56 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Stop.imageset/Stop.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/StopButtonFavorite.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/StopButtonFavorite.imageset/Contents.json new file mode 100644 index 0000000..f7c03c6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/StopButtonFavorite.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "StopButtonFavorite.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/StopButtonFavorite.imageset/StopButtonFavorite.png b/frontend/mobile/CommunityMC3/Assets.xcassets/StopButtonFavorite.imageset/StopButtonFavorite.png new file mode 100644 index 0000000..ca43689 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/StopButtonFavorite.imageset/StopButtonFavorite.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Contents 2.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Contents 2.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Contents 2.json new file mode 100644 index 0000000..48dce4e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Play.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Contents.json new file mode 100644 index 0000000..48dce4e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Play.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Play 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Play 2.png new file mode 100644 index 0000000..f6dbb30 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Play 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Play.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Play.png new file mode 100644 index 0000000..f6dbb30 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Play.imageset/Play.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Contents 2.json new file mode 100644 index 0000000..446d6be --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Contents.json new file mode 100644 index 0000000..446d6be --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Vector 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Vector 2.png new file mode 100644 index 0000000..11ea4d2 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Vector 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Vector.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Vector.png new file mode 100644 index 0000000..11ea4d2 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/Vector.imageset/Vector.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/Contents 2.json new file mode 100644 index 0000000..5f71ed8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "pause.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/Contents.json new file mode 100644 index 0000000..5f71ed8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "pause.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/pause 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/pause 2.png new file mode 100644 index 0000000..67a74b6 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/pause 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/pause.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/pause.png new file mode 100644 index 0000000..67a74b6 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/pause.imageset/pause.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/Contents 2.json new file mode 100644 index 0000000..aafa0cc --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "repeat.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/Contents.json new file mode 100644 index 0000000..aafa0cc --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "repeat.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/repeat 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/repeat 2.png new file mode 100644 index 0000000..413b516 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/repeat 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/repeat.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/repeat.png new file mode 100644 index 0000000..413b516 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeat.imageset/repeat.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/Contents 2.json new file mode 100644 index 0000000..533ca80 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "repeatOneTrackOnly.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/Contents.json new file mode 100644 index 0000000..533ca80 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "repeatOneTrackOnly.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/repeatOneTrackOnly 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/repeatOneTrackOnly 2.png new file mode 100644 index 0000000..72736b9 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/repeatOneTrackOnly 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/repeatOneTrackOnly.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/repeatOneTrackOnly.png new file mode 100644 index 0000000..72736b9 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatOneTrackOnly.imageset/repeatOneTrackOnly.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/Contents 2.json new file mode 100644 index 0000000..5633103 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "repeatPlaylist.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/Contents.json new file mode 100644 index 0000000..5633103 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "repeatPlaylist.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/repeatPlaylist 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/repeatPlaylist 2.png new file mode 100644 index 0000000..d111ead Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/repeatPlaylist 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/repeatPlaylist.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/repeatPlaylist.png new file mode 100644 index 0000000..d111ead Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/repeatPlaylist.imageset/repeatPlaylist.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/Contents 2.json new file mode 100644 index 0000000..1296bbc --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "shuffle.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/Contents.json new file mode 100644 index 0000000..1296bbc --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "shuffle.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/shuffle 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/shuffle 2.png new file mode 100644 index 0000000..402428c Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/shuffle 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/shuffle.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/shuffle.png new file mode 100644 index 0000000..402428c Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffle.imageset/shuffle.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/Contents 2.json new file mode 100644 index 0000000..8ca0b94 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "shuffleActive.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/Contents.json new file mode 100644 index 0000000..8ca0b94 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "shuffleActive.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/shuffleActive 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/shuffleActive 2.png new file mode 100644 index 0000000..a43cdaa Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/shuffleActive 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/shuffleActive.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/shuffleActive.png new file mode 100644 index 0000000..a43cdaa Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/shuffleActive.imageset/shuffleActive.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/Contents 2.json new file mode 100644 index 0000000..5adb009 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "skip-back.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/Contents.json new file mode 100644 index 0000000..5adb009 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "skip-back.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/skip-back 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/skip-back 2.png new file mode 100644 index 0000000..50d5457 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/skip-back 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/skip-back.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/skip-back.png new file mode 100644 index 0000000..50d5457 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-back.imageset/skip-back.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/Contents 2.json new file mode 100644 index 0000000..7f38546 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "skip-forward.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/Contents.json new file mode 100644 index 0000000..7f38546 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "skip-forward.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/skip-forward 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/skip-forward 2.png new file mode 100644 index 0000000..a0adc95 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/skip-forward 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/skip-forward.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/skip-forward.png new file mode 100644 index 0000000..a0adc95 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/skip-forward.imageset/skip-forward.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/Contents 2.json new file mode 100644 index 0000000..e988fee --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "trackThumbTint.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/Contents.json new file mode 100644 index 0000000..e988fee --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "trackThumbTint.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/trackThumbTint 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/trackThumbTint 2.png new file mode 100644 index 0000000..3e7b446 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/trackThumbTint 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/trackThumbTint.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/trackThumbTint.png new file mode 100644 index 0000000..3e7b446 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/trackThumbTint.imageset/trackThumbTint.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/Contents 2.json new file mode 100644 index 0000000..e2bdfa7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "volume-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/Contents.json new file mode 100644 index 0000000..e2bdfa7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "volume-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/volume-2 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/volume-2 2.png new file mode 100644 index 0000000..af10981 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/volume-2 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/volume-2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/volume-2.png new file mode 100644 index 0000000..af10981 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Track Button Assets/volume-2.imageset/volume-2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Upload Button.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/Upload Button.imageset/Contents.json new file mode 100644 index 0000000..39bb970 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/Upload Button.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Upload Button.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/Upload Button.imageset/Upload Button.png b/frontend/mobile/CommunityMC3/Assets.xcassets/Upload Button.imageset/Upload Button.png new file mode 100644 index 0000000..b51eba4 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/Upload Button.imageset/Upload Button.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Contents 2.json new file mode 100644 index 0000000..b065837 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Group 141.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Contents.json new file mode 100644 index 0000000..b065837 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Group 141.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Group 141.png b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Group 141.png new file mode 100644 index 0000000..ef816d3 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Group 141.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Group 142.png b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Group 142.png new file mode 100644 index 0000000..ef816d3 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/apple.imageset/Group 142.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/artist-group-image.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/artist-group-image.imageset/Contents.json new file mode 100644 index 0000000..881aa3b --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/artist-group-image.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "artist-group-image.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/artist-group-image.imageset/artist-group-image.png b/frontend/mobile/CommunityMC3/Assets.xcassets/artist-group-image.imageset/artist-group-image.png new file mode 100644 index 0000000..cc6e400 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/artist-group-image.imageset/artist-group-image.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/audioIcon.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/audioIcon.imageset/Contents.json new file mode 100644 index 0000000..e21c242 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/audioIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "audio note 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/audioIcon.imageset/audio note 1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/audioIcon.imageset/audio note 1.png new file mode 100644 index 0000000..20d28a2 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/audioIcon.imageset/audio note 1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/camera 1.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/camera 1.imageset/Contents.json new file mode 100644 index 0000000..18ad136 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/camera 1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "camera 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/camera 1.imageset/camera 1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/camera 1.imageset/camera 1.png new file mode 100644 index 0000000..153bbb4 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/camera 1.imageset/camera 1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/checkBox.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/checkBox.imageset/Contents.json new file mode 100644 index 0000000..0c687d4 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/checkBox.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "checkBox.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/checkBox.imageset/checkBox.png b/frontend/mobile/CommunityMC3/Assets.xcassets/checkBox.imageset/checkBox.png new file mode 100644 index 0000000..2f2daf9 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/checkBox.imageset/checkBox.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/darkGradient-overlay.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/darkGradient-overlay.imageset/Contents.json new file mode 100644 index 0000000..110ef01 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/darkGradient-overlay.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "darkGradient-overlay.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/darkGradient-overlay.imageset/darkGradient-overlay.png b/frontend/mobile/CommunityMC3/Assets.xcassets/darkGradient-overlay.imageset/darkGradient-overlay.png new file mode 100644 index 0000000..ec3086b Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/darkGradient-overlay.imageset/darkGradient-overlay.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Contents 2.json new file mode 100644 index 0000000..44a4015 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Group 140.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Contents.json new file mode 100644 index 0000000..44a4015 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Group 140.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Group 140.png b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Group 140.png new file mode 100644 index 0000000..5531bed Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Group 140.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Group 141.png b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Group 141.png new file mode 100644 index 0000000..5531bed Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/fb.imageset/Group 141.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/Contents 2.json new file mode 100644 index 0000000..33a7451 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/Contents 2.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000..33a7451 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/first 2.pdf b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/first 2.pdf new file mode 100644 index 0000000..47d911d Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/first 2.pdf differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/first.pdf b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/first.pdf new file mode 100644 index 0000000..47d911d Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/first.imageset/first.pdf differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/imageIcon.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/imageIcon.imageset/Contents.json new file mode 100644 index 0000000..b459893 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/imageIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "imageIcon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/imageIcon.imageset/imageIcon.png b/frontend/mobile/CommunityMC3/Assets.xcassets/imageIcon.imageset/imageIcon.png new file mode 100644 index 0000000..fa32bad Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/imageIcon.imageset/imageIcon.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/Contents 2.json new file mode 100644 index 0000000..76e679d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "SIGN IN.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/Contents.json new file mode 100644 index 0000000..76e679d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "SIGN IN.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/SIGN IN 2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/SIGN IN 2.png new file mode 100644 index 0000000..a7e7b06 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/SIGN IN 2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/SIGN IN.png b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/SIGN IN.png new file mode 100644 index 0000000..a7e7b06 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/login.imageset/SIGN IN.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy.imageset/Contents.json new file mode 100644 index 0000000..34ec4f7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "music-image-dummy.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy.imageset/music-image-dummy.png b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy.imageset/music-image-dummy.png new file mode 100644 index 0000000..e158154 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy.imageset/music-image-dummy.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy1.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy1.imageset/Contents.json new file mode 100644 index 0000000..2ce7491 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "music-image-dummy1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy1.imageset/music-image-dummy1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy1.imageset/music-image-dummy1.png new file mode 100644 index 0000000..3e173ce Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/music-image-dummy1.imageset/music-image-dummy1.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/no_album.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/no_album.imageset/Contents.json new file mode 100644 index 0000000..f7c7e00 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/no_album.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "no_album.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/no_album.imageset/no_album.png b/frontend/mobile/CommunityMC3/Assets.xcassets/no_album.imageset/no_album.png new file mode 100644 index 0000000..80154e0 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/no_album.imageset/no_album.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/pauseFullColor.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/pauseFullColor.imageset/Contents.json new file mode 100644 index 0000000..4662b8a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/pauseFullColor.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "pauseFullColor.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/pauseFullColor.imageset/pauseFullColor.png b/frontend/mobile/CommunityMC3/Assets.xcassets/pauseFullColor.imageset/pauseFullColor.png new file mode 100644 index 0000000..a4b231b Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/pauseFullColor.imageset/pauseFullColor.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/photos-dummy.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/photos-dummy.imageset/Contents.json new file mode 100644 index 0000000..9b8e4b2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/photos-dummy.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "photos-dummy.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/photos-dummy.imageset/photos-dummy.png b/frontend/mobile/CommunityMC3/Assets.xcassets/photos-dummy.imageset/photos-dummy.png new file mode 100644 index 0000000..2bfd13c Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/photos-dummy.imageset/photos-dummy.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/picture.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/picture.imageset/Contents.json new file mode 100644 index 0000000..f1bf83c --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/picture.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "picture.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/picture.imageset/picture.png b/frontend/mobile/CommunityMC3/Assets.xcassets/picture.imageset/picture.png new file mode 100644 index 0000000..dd85669 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/picture.imageset/picture.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/playButton.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton.imageset/Contents.json new file mode 100644 index 0000000..8ca648b --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "playButton.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/playButton.imageset/playButton.png b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton.imageset/playButton.png new file mode 100644 index 0000000..5082fe1 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton.imageset/playButton.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/playButton2.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton2.imageset/Contents.json new file mode 100644 index 0000000..fd3f1d1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "playButton2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/playButton2.imageset/playButton2.png b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton2.imageset/playButton2.png new file mode 100644 index 0000000..b01b7aa Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/playButton2.imageset/playButton2.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/playButtonFavorites.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/playButtonFavorites.imageset/Contents.json new file mode 100644 index 0000000..622cab5 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/playButtonFavorites.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "playButtonFavorites.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/playButtonFavorites.imageset/playButtonFavorites.png b/frontend/mobile/CommunityMC3/Assets.xcassets/playButtonFavorites.imageset/playButtonFavorites.png new file mode 100644 index 0000000..0bf3443 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/playButtonFavorites.imageset/playButtonFavorites.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/post button.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/post button.imageset/Contents.json new file mode 100644 index 0000000..72580ec --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/post button.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "post button.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/post button.imageset/post button.png b/frontend/mobile/CommunityMC3/Assets.xcassets/post button.imageset/post button.png new file mode 100644 index 0000000..d6b9b50 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/post button.imageset/post button.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/Contents 2.json new file mode 100644 index 0000000..03bd9c9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/Contents 2.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000..03bd9c9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/second 2.pdf b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/second 2.pdf new file mode 100644 index 0000000..401614e Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/second 2.pdf differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/second.pdf b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/second.pdf new file mode 100644 index 0000000..401614e Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/second.imageset/second.pdf differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-1.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-1.imageset/Contents.json new file mode 100644 index 0000000..d69a92f --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "segmented-bg.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-1.imageset/segmented-bg.png b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-1.imageset/segmented-bg.png new file mode 100644 index 0000000..e56c0fb Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-1.imageset/segmented-bg.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-notselected-1.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-notselected-1.imageset/Contents.json new file mode 100644 index 0000000..1216a0e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-notselected-1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "segmented-bg-notselected.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-notselected-1.imageset/segmented-bg-notselected.png b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-notselected-1.imageset/segmented-bg-notselected.png new file mode 100644 index 0000000..851c9c2 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/segmented-bg-notselected-1.imageset/segmented-bg-notselected.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/80 x 81.png b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/80 x 81.png new file mode 100644 index 0000000..ee228ea Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/80 x 81.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/80 x 82.png b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/80 x 82.png new file mode 100644 index 0000000..ee228ea Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/80 x 82.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/Contents 2.json b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/Contents 2.json new file mode 100644 index 0000000..2d38e6a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/Contents 2.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "80 x 81.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/Contents.json new file mode 100644 index 0000000..2d38e6a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/setting.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "80 x 81.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/splashScreen.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/splashScreen.imageset/Contents.json new file mode 100644 index 0000000..99cc8f1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/splashScreen.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "splashScreen.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/splashScreen.imageset/splashScreen.png b/frontend/mobile/CommunityMC3/Assets.xcassets/splashScreen.imageset/splashScreen.png new file mode 100644 index 0000000..6d3e2ff Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/splashScreen.imageset/splashScreen.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/surprise-red-button.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/surprise-red-button.imageset/Contents.json new file mode 100644 index 0000000..2f807ad --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/surprise-red-button.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "surprise-red-button.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/surprise-red-button.imageset/surprise-red-button.png b/frontend/mobile/CommunityMC3/Assets.xcassets/surprise-red-button.imageset/surprise-red-button.png new file mode 100644 index 0000000..3b4e71e Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/surprise-red-button.imageset/surprise-red-button.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/target.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/target.imageset/Contents.json new file mode 100644 index 0000000..8d0b424 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/target.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "target.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/target.imageset/target.png b/frontend/mobile/CommunityMC3/Assets.xcassets/target.imageset/target.png new file mode 100644 index 0000000..b83815c Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/target.imageset/target.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/trackIcon.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/trackIcon.imageset/Contents.json new file mode 100644 index 0000000..e30c0e2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/trackIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "trackIcon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/trackIcon.imageset/trackIcon.png b/frontend/mobile/CommunityMC3/Assets.xcassets/trackIcon.imageset/trackIcon.png new file mode 100644 index 0000000..e690ea5 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/trackIcon.imageset/trackIcon.png differ diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/videoIcon.imageset/Contents.json b/frontend/mobile/CommunityMC3/Assets.xcassets/videoIcon.imageset/Contents.json new file mode 100644 index 0000000..f2753d9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Assets.xcassets/videoIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "video 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/frontend/mobile/CommunityMC3/Assets.xcassets/videoIcon.imageset/video 1.png b/frontend/mobile/CommunityMC3/Assets.xcassets/videoIcon.imageset/video 1.png new file mode 100644 index 0000000..b7790fd Binary files /dev/null and b/frontend/mobile/CommunityMC3/Assets.xcassets/videoIcon.imageset/video 1.png differ diff --git a/frontend/mobile/CommunityMC3/Base.lproj/LaunchScreen.storyboard b/frontend/mobile/CommunityMC3/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..26be0ef --- /dev/null +++ b/frontend/mobile/CommunityMC3/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/BonsaiTest/SmallViewController.storyboard b/frontend/mobile/CommunityMC3/BonsaiTest/SmallViewController.storyboard new file mode 100644 index 0000000..97174d2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/BonsaiTest/SmallViewController.storyboard @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/BonsaiTest/SmallViewController.swift b/frontend/mobile/CommunityMC3/BonsaiTest/SmallViewController.swift new file mode 100644 index 0000000..91f597c --- /dev/null +++ b/frontend/mobile/CommunityMC3/BonsaiTest/SmallViewController.swift @@ -0,0 +1,20 @@ +// +// SmallViewController.swift +// BonsaiController +// +// Created by Warif Akhand Rishi on 27/5/18. +// Copyright © 2018 Warif Akhand Rishi. All rights reserved. +// + +import UIKit + +class SmallViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + } + + @IBAction func dismissButtonAction(_ sender: Any) { + dismiss(animated: true, completion: nil) + } +} diff --git a/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiFullScreenPopUtility.swift b/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiFullScreenPopUtility.swift new file mode 100644 index 0000000..de603fe --- /dev/null +++ b/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiFullScreenPopUtility.swift @@ -0,0 +1,66 @@ +// +// BonsaiFullScreenPopUtility.swift +// PencilTest +// +// Created by Warif Akhand Rishi on 11/4/19. +// Copyright © 2019 Warif Akhand Rishi. All rights reserved. +// + +import Foundation +import BonsaiController + +class BonsaiFullScreenPopUtility: NSObject { + + static let shared = BonsaiFullScreenPopUtility() + var sourceView: UIView? + + func show(viewController: UIViewController, fromView: UIView) { + + viewController.transitioningDelegate = self + viewController.modalPresentationStyle = .custom + sourceView = fromView + + topViewController()?.present(viewController, animated: true, completion: nil) + } +} + +private extension BonsaiFullScreenPopUtility { + + func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { + + if let navigationController = controller as? UINavigationController { + return topViewController(controller: navigationController.visibleViewController) + } + + if let tabController = controller as? UITabBarController { + if let selected = tabController.selectedViewController { + return topViewController(controller: selected) + } + } + + if let presented = controller?.presentedViewController { + return topViewController(controller: presented) + } + + return controller + } +} + +extension BonsaiFullScreenPopUtility: BonsaiControllerDelegate { + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + + let bonsaiController = BonsaiController(fromView: sourceView!, blurEffectStyle: .light, presentedViewController: presented, delegate: self) + bonsaiController.presentedView?.layer.cornerRadius = 0 + bonsaiController.presentedView?.layer.masksToBounds = false + return bonsaiController + } + + func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { + return containerViewFrame + } + + func didDismiss() { + //NotificationCenter.default.post(name: .refreshScreen, object: nil) + } +} diff --git a/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiNotificationUtility.swift b/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiNotificationUtility.swift new file mode 100644 index 0000000..153163c --- /dev/null +++ b/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiNotificationUtility.swift @@ -0,0 +1,62 @@ +// +// BonsaiNotificationUtility.swift +// BonsaiController_Example +// +// Created by Warif Akhand Rishi on 18/10/18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit +import BonsaiController + +class BonsaiNotificationUtility: NSObject { + + static let shared = BonsaiNotificationUtility() + let notificationHeight: CGFloat = 120 + let notificationDelay: TimeInterval = 2 + + func show(viewController: UIViewController) { + + viewController.transitioningDelegate = self + viewController.modalPresentationStyle = .custom + + topViewController()?.present(viewController, animated: true, completion: nil) + } +} + +extension BonsaiNotificationUtility { + + func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { + + if let navigationController = controller as? UINavigationController { + return topViewController(controller: navigationController.visibleViewController) + } + + if let tabController = controller as? UITabBarController { + if let selected = tabController.selectedViewController { + return topViewController(controller: selected) + } + } + + if let presented = controller?.presentedViewController { + return topViewController(controller: presented) + } + + return controller + } +} + +extension BonsaiNotificationUtility: BonsaiControllerDelegate { + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + + let bonsaiController = BonsaiController(fromDirection: .right, blurEffectStyle: .light, presentedViewController: presented, delegate: self) + bonsaiController.perform(#selector(bonsaiController.dismiss), with: nil, afterDelay: notificationDelay) + return bonsaiController + } + + func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { + + return CGRect(origin: .zero, size: CGSize(width: containerViewFrame.width, height: notificationHeight)) + } +} diff --git a/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiPopupUtility.swift b/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiPopupUtility.swift new file mode 100644 index 0000000..cc16798 --- /dev/null +++ b/frontend/mobile/CommunityMC3/BonsaiUtilities/BonsaiPopupUtility.swift @@ -0,0 +1,74 @@ +// +// BonsaiPopupUtility.swift +// BonsaiController_Example +// +// Created by Warif Akhand Rishi on 1/6/18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit +import BonsaiController + +class BonsaiPopupUtility: NSObject { + + static let shared = BonsaiPopupUtility() + let popupSize = CGSize(width: 280, height: 150) + + func show(viewController: UIViewController) { + + viewController.transitioningDelegate = self + viewController.modalPresentationStyle = .custom + + topViewController()?.present(viewController, animated: true, completion: nil) + } +} + +extension BonsaiPopupUtility { + + func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { + + if let navigationController = controller as? UINavigationController { + return topViewController(controller: navigationController.visibleViewController) + } + + if let tabController = controller as? UITabBarController { + if let selected = tabController.selectedViewController { + return topViewController(controller: selected) + } + } + + if let presented = controller?.presentedViewController { + return topViewController(controller: presented) + } + + return controller + } +} + +extension BonsaiPopupUtility: BonsaiControllerDelegate { + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + + let frame = frameOfPresentedView(in: source.view.frame) + let originFrame = frame.insetBy(dx: -20, dy: -20) + + var blurEffectStyle = UIBlurEffect.Style.light + + if #available(iOS 13.0, *) { + blurEffectStyle = .systemChromeMaterial + } + + let bonsaiController = BonsaiController(fromView: UIView(frame: originFrame), blurEffectStyle: blurEffectStyle, presentedViewController: presented, delegate: self) + bonsaiController.springWithDamping = 0.5 + bonsaiController.duration = 0.5 + bonsaiController.isDisabledTapOutside = true + bonsaiController.isDisabledDismissAnimation = true + + return bonsaiController + } + + func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { + + return CGRect(origin: CGPoint(x: (containerViewFrame.width - popupSize.width) / 2, y: (containerViewFrame.height - popupSize.height) / 2), size: popupSize) + } +} diff --git a/frontend/mobile/CommunityMC3/Cloud/DocumentTableViewController.swift b/frontend/mobile/CommunityMC3/Cloud/DocumentTableViewController.swift new file mode 100644 index 0000000..4428ca9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Cloud/DocumentTableViewController.swift @@ -0,0 +1,527 @@ +// +// ContactTableViewController.swift +// StarterCloudkit +// +// Created by Jazilul Athoya on 09/07/20. +// Copyright © 2020 Jazilul Athoya. All rights reserved. +// + +import UIKit +import CloudKit +import AVFoundation + +class Upload: NSObject { + var recordID: CKRecord.ID! + var genre: String! + var name: String! + var file: URL! +} + +class DocumentTableViewController: UITableViewController { + + @IBOutlet weak var uploadButton: UIBarButtonItem! + // var documents: [String] = [] + var documents: [CKRecord] = [] + var uploads: [Upload] = [] + var selectRow = 0 + var audioPlayer: AVAudioPlayer! + + var selectedVideo: URL! + + static let shared = DocumentTableViewController() + + override func viewDidLoad() { + super.viewDidLoad() + } + + @IBAction func uploadVideo(_ sender: UIBarButtonItem) { + openCameraAndLibrary() + + } + + override func viewWillAppear(_ animated: Bool) { + getUploadsFromCloudKit(tableView: self.tableView) { (records) in + self.documents = records + } + // getFromCloudKit() + // getFilmsFromCloudKit { (videos) in + // if videos.count > 0 { + // let videoURL = videos[0].fileURL + // let player = AVPlayer(url: videoURL) + // let playerLayer = AVPlayerLayer(player: player) + // playerLayer.frame = self.view.bounds + // self.view.layer.addSublayer(playerLayer) + // player.play() + // } + // } + } + + func getFavoritesFromCloudKit(completionHandler: @escaping ([FavouritesDataStruct]) -> Void){ + var favourites = [FavouritesDataStruct]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Favourites", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + +// print(records) + + if let fetchedRecords = records { + for record in fetchedRecords { + let trackData = try? JSONDecoder().decode([PrimitiveTrackDataStruct].self, from: record.value(forKey: "tracks") as! Data) + let videoData = try? JSONDecoder().decode([PrimitiveVideosDataStruct].self, from: record.value(forKey: "video") as! Data) + let temp = FavouritesDataStruct( + id: (record.value(forKey: "id") as? String)!, + track: trackData!, + videos: videoData! + ) + favourites.append(temp) + } + completionHandler(favourites) + } + } + } + + func uploadFavorite(id: String, track: [PrimitiveTrackDataStruct]?) { + // guard let arrayTrack = track else { return } + // do{ + let trackData = try? JSONEncoder().encode(track) + var musicRecord = CKRecord(recordType: "Favourites") + // let musicRecord = CKRecord(recordType: "Favourites", recordID: recordID) + //Parent record (Aircraft) + // let recordAircraft = CKRecord(recordType: "Aircraft", recordID: ...) + // + // //Add child references (FieldValue). As far as I know, the child records must have already been created and sent to CloudKit + // var fieldValueReferences = [CKRecord.Reference]() + // + // for fieldValue in fieldValues{ + // let ref = CKReference(record: fieldValue, action: .deleteSelf) + // fieldValueReferences.append(ref) + // } + // + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Favourites", predicate: predicate) + + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + +// print(records) + + if let fetchedRecords = records { + var flag = false + for record in fetchedRecords { + let email = (record.value(forKey: "id") as? String)! + let favouriteData = try? JSONDecoder().decode([PrimitiveTrackDataStruct].self, from: record.value(forKey: "tracks") as! Data) + if email == id && favouriteData!.count != trackData!.count { + // print("bener") + flag = true + musicRecord = record + musicRecord["tracks"] = trackData + database.save(musicRecord) { [unowned self] record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + } + if !flag { + // print("salah") + musicRecord["id"] = id as CKRecordValue + musicRecord["tracks"] = trackData + database.save(musicRecord) { [unowned self] record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + } + } + + + // //Assign the array of references to the key that represents your Reference List field + // recordAircraft["fieldValues"] = fieldValueReferences as CKRecordValue + // musicRecord["track"] = fieldValueReferences as CKRecordValue + // musicRecord["videos"] = (video! as CKRecordValue) + + // }catch{print("error")} + + } + + func uploadTrack(email: String, genre: String, name: String, fileURL: URL) { + let musicRecord = CKRecord(recordType: "Track") + musicRecord["genre"] = genre as CKRecordValue + musicRecord["name"] = name as CKRecordValue + musicRecord["email"] = email as CKRecordValue + + // let audioURL = UploadController.getMusicURL(document: document) + let musicAsset = CKAsset(fileURL: fileURL) + musicRecord["fileData"] = musicAsset + + CKContainer(identifier: iCloudContainerID).publicCloudDatabase.save(musicRecord) { [unowned self] record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + + func uploadFilm(name: String, email: String, genre: String, myVideo: URL?) { + let profileRecord = CKRecord(recordType: "Videos") + profileRecord["genre"] = genre as CKRecordValue + profileRecord["name"] = name as CKRecordValue + profileRecord["email"] = email as CKRecordValue + + if let videoURL = myVideo { + do { + let videoData = try Data(contentsOf: videoURL) + let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(NSUUID().uuidString+".dat") + do { + try videoData.write(to: url!, options: []) + } catch let e as NSError { + print("Error! \(e)"); + return + } + profileRecord["fileData"] = CKAsset(fileURL: url!) + + CKContainer(identifier: iCloudContainerID).publicCloudDatabase.save(profileRecord) { record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + // Delete the temporary file + do { try FileManager.default.removeItem(at: url!) } + catch let e { print("Error deleting temp file: \(e)") } + print("Done!") + } + } + } + } catch let error { + print(error) + } + } + } + + func getFilmsFromCloudKit(completionHandler: @escaping ([CKRecord]) -> Void) { + var videos = [CKRecord]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Videos", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + for record in fetchedRecords { + // let asset = (record.value(forKey: "fileData") as? CKAsset)! + // let temp = VideosDataStruct( + // genre: (record.value(forKey: "genre") as? String)!, + // name: (record.value(forKey: "name") as? String)!, + // email: (record.value(forKey: "email") as? String)!, + // fileURL: asset.fileURL! + // ) + // videos.append(temp) + videos.append(record) + } + completionHandler(videos) + } + } + // print("panjang ", tracks.count) + } + + func uploadProfile(name: String, email: String, genre: String, myImage: UIImage) { + // let profileRecord = CKRecord(recordType: "Profiles") + let profileRecord = CKRecord(recordType: "UserData") + profileRecord["genre"] = genre as CKRecordValue + profileRecord["name"] = name as CKRecordValue + profileRecord["email"] = email as CKRecordValue + + + let data = myImage.pngData(); // UIImage -> NSData, see also UIImageJPEGRepresentation + let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(NSUUID().uuidString+".dat") + do { + try data!.write(to: url!, options: []) + } catch let e as NSError { + print("Error! \(e)"); + return + } + profileRecord["fileData"] = CKAsset(fileURL: url!) + + CKContainer(identifier: iCloudContainerID).publicCloudDatabase.save(profileRecord) { record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + // Delete the temporary file + do { try FileManager.default.removeItem(at: url!) } + catch let e { print("Error deleting temp file: \(e)") } + print("Done!") + } + } + } + } + + func getProfilesFromCloudKit(completionHandler: @escaping ([CKRecord]) -> Void) { + var photos = [CKRecord]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Profiles", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + +// print(records) + + if let fetchedRecords = records { + for record in fetchedRecords { + // let temp = Upload() + // let temp = TrackDataClass() + // let asset = (record.value(forKey: "fileData") as? CKAsset)! + // let temp = PhotoDataStruct( + // fileURL: asset.fileURL!, + // email: (record.value(forKey: "email") as? String)!, + // genre: (record.value(forKey: "genre") as? String)!, + // name: (record.value(forKey: "name") as? String)! + // ) + // temp.audioData = try AVAudioPlayer(contentsOf: asset.fileURL) + + // temp.name = record.value(forKey: "name") as? String + // temp.recordID = record.recordID + photos.append(record) + // self.uploads.append(temp) + } + completionHandler(photos) + } + } + // print("panjang ", tracks.count) + } + + func getFromDevice(){ + let file = AppFile() + // _ = file.writeFile(containing: "This file was written for my tutorial on the iOS 11 Files app.\n\nThe text file was written to this app\'s Documents folder.", to: .Documents, withName: "textFile1.txt") + let fetchedDocuments = file.list() +// print(fetchedDocuments) + + if fetchedDocuments.count > 0 { + // print(fetchedDocuments[0]) + for document in fetchedDocuments { + var temp = document + temp = String(temp.dropFirst()) + temp = String(temp.dropLast()) + // self.documents.append(temp) + } + // print(file.readFile(at: .Documents, withName: self.documents[0])) + DispatchQueue.main.async { + self.tableView.reloadData() + } + } + } + + func getUploadsFromCloudKit(tableView: UITableView, completionHandler: @escaping ([CKRecord]) -> Void){ + var tracks = [CKRecord]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Uploads", predicate: predicate) + // let query = CKQuery(recordType: "Tracks", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + +// print(records) + + if let fetchedRecords = records { + for record in fetchedRecords { + // let temp = Upload() + // let temp = TrackDataClass() + // let asset = (record.value(forKey: "fileData") as? CKAsset)! + // let temp = TrackDataStruct( + // genre: (record.value(forKey: "genre") as? String)!, + // name: (record.value(forKey: "name") as? String)!, + // recordID: record.recordID, + // email: (record.value(forKey: "email") as? String)!, + // fileURL: asset.fileURL! + // ) + // temp.audioData = try AVAudioPlayer(contentsOf: asset.fileURL) + + // temp.name = record.value(forKey: "name") as? String + // temp.recordID = record.recordID + // tracks.append(temp) + tracks.append(record) + // self.uploads.append(temp) + } + // self.documents = fetchedRecords + DispatchQueue.main.async { + // self.tableView.reloadData() + tableView.reloadData() + } + completionHandler(tracks) + } + } + // print("panjang ", tracks.count) + } + + func downloadDocument(upload: TrackDataStruct) { + // let spinner = UIActivityIndicatorView(style: .gray) + // spinner.tintColor = UIColor.black + // spinner.startAnimating() + // navigationItem.rightBarButtonItem = UIBarButtonItem(customView: spinner) + + // CKContainer(identifier: "iCloud.ada.mc3.music").publicCloudDatabase.fetch(withRecordID: upload.recordID) { [unowned self] record, error in + // if let error = error { + // DispatchQueue.main.async { + // meaningful error message here! + // print(error.localizedDescription) + // self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Download", style: .plain, target: self, action: #selector(self.downloadTapped)) + // } + // } else { + // if let record = record { + // if let asset = record["fileData"] as? CKAsset { + // upload.file = asset.fileURL + // upload.fileURL = asset.fileURL! + + DispatchQueue.main.async { + // self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Listen", style: .plain, target: self, action: #selector(self.listenTapped)) + do { + self.audioPlayer = try AVAudioPlayer(contentsOf: upload.fileData!.fileURL!) + self.audioPlayer.play() + } catch { + print("play failed") + // let ac = UIAlertController(title: "Playback failed", message: "There was a problem playing your whistle; please try re-recording.", preferredStyle: .alert) + // ac.addAction(UIAlertAction(title: "OK", style: .default)) + // present(ac, animated: true) + } + } + + // } + // } + // } + // } + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return documents.count + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) + + let record = documents[indexPath.row] + + // cell.textLabel?.text = record + cell.textLabel?.text = record.value(forKey: "name") as? String + // cell.detailTextLabel?.text = record.value(forKey: "email") as? String + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + // selectRow = indexPath.row + // self.performSegue(withIdentifier: "uploadTest", sender: self) + // downloadDocument(upload: self.uploads[indexPath.row]) + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // if segue.identifier == "uploadTest" { + // if let mainPage = segue.destination as? UploadController { + // mainPage.document = documents[selectRow] + // } + // } + } + +} + +// Extension to make more structured +extension DocumentTableViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { + // MARK: Func to open camera and library function + func openCameraAndLibrary() { + let imagePicker = UIImagePickerController() + imagePicker.delegate = self + let actionAlert = UIAlertController(title: "Browse attachment", message: "Choose source", preferredStyle: .alert) + actionAlert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { + (action:UIAlertAction) in + if UIImagePickerController.isSourceTypeAvailable(.camera) { + imagePicker.sourceType = .camera + self.present(imagePicker, animated:true, completion: nil) + }else{ + print("Camera is not available at this device") + } + })) // give an option in alert controller to open camera + + actionAlert.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action: UIAlertAction) in + imagePicker.sourceType = .photoLibrary + imagePicker.mediaTypes = ["public.movie"] + self.present(imagePicker, animated:true, completion: nil) + })) // give the second option in alert controller to open Photo library + + actionAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) // give the third option in alert controller to cancel the form + + self.present(actionAlert, animated: true, completion: nil) + } + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + // print("masuk") + if let videoURL = info[.mediaURL] as? URL { + // print("lebih") + picker.videoExportPreset = AVAssetExportPresetPassthrough + picker.dismiss(animated: true) { + self.selectedVideo = videoURL + print(videoURL) + self.uploadFilm(name: "test", email: "mnb@mnb", genre: "Pop", myVideo: videoURL) + } + } + } +} + diff --git a/frontend/mobile/CommunityMC3/Cloud/Test.storyboard b/frontend/mobile/CommunityMC3/Cloud/Test.storyboard new file mode 100644 index 0000000..8d4c3f7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Cloud/Test.storyboard @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Cloud/UploadController.swift b/frontend/mobile/CommunityMC3/Cloud/UploadController.swift new file mode 100644 index 0000000..177a663 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Cloud/UploadController.swift @@ -0,0 +1,553 @@ +// +// UploadController.swift +// CommunityMC3 +// +// Created by Bryanza on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVFoundation +import CloudKit +//import MediaPlayer + +class UploadController: UIViewController { + var document: String! + var audioPlayer: AVAudioPlayer! + + static let shared = UploadController() + + @IBOutlet weak var testButton: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + if document != nil { + print(document) + // testButton.titleLabel?.text = document + } + doSubmission(document: document) + } + + @IBAction func uploadNow(_ sender: UIButton) { +// openMediaPlayer() + } + + func uploadFavorite(id: String, video: [PrimitiveVideosDataStruct]?) { + let videoData = try? JSONEncoder().encode(video) + var videoRecord = CKRecord(recordType: "Favourites") + + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Favourites", predicate: predicate) + + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + var flag = false + for record in fetchedRecords { + let email = (record.value(forKey: "id") as? String)! + if email == id { + flag = true + videoRecord = record + videoRecord["video"] = videoData + + database.save(videoRecord) { [unowned self] record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + } + if !flag { + videoRecord["id"] = id as CKRecordValue + videoRecord["video"] = videoData + database.save(videoRecord) { [unowned self] record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + } + } + } + + func uploadUserData(email: String, name: String, genre: String, myImage: UIImage) { + // 1. buat dulu recordnya + var newRecord = CKRecord(recordType: "UserData") + + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "UserData", predicate: predicate) + + let data = myImage.pngData(); // UIImage -> NSData, see also UIImageJPEGRepresentation + let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(NSUUID().uuidString+".dat") + do { + try data!.write(to: url!, options: []) + } catch let e as NSError { + print("Error! \(e)"); + return + } + newRecord.setValue(CKAsset(fileURL: url!) , forKey: "fileURL") + + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + var flag = false + for record in fetchedRecords { + let id = (record.value(forKey: "email") as? String)! + if email == id { + flag = true + newRecord = record + newRecord.setValue(name , forKey: "name") + newRecord.setValue(genre , forKey: "genre") + database.save(newRecord) { [unowned self] record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + } + if !flag { + // 3. set propertynya + newRecord.setValue(email , forKey: "email") + newRecord.setValue(name , forKey: "name") + newRecord.setValue(genre , forKey: "genre") + + // 4. execute save or insert + database.save(newRecord) { record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + } + } + } + + func getUsersDataFromCloudKit(completionHandler: @escaping ([UserDataStruct]) -> Void) { + var users = [UserDataStruct]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "UserData", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + let registers = fetchedRecords + for register in registers { + let asset = (register.value(forKey: "fileURL") as? CKAsset)! + let temp = UserDataStruct( + genre: (register.value(forKey: "genre") as? String)!, + name: (register.value(forKey: "name") as? String)!, + fileURL: asset.fileURL!, + email: (register.value(forKey: "email") as? String)! + ) + users.append(temp) + } + completionHandler(users) + } + } + } + + func uploadAccount(email: String, password: String) { + // 1. buat dulu recordnya + let newRecord = CKRecord(recordType: "Account") + + // 2. set propertynya + newRecord.setValue(email , forKey: "email") + newRecord.setValue(password , forKey: "password") + + // 3. execute save or insert + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + database.save(newRecord) { record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + print("Done!") + } + } + } + } + + func getAccountsFromCloudKit(completionHandler: @escaping ([AccountDataStruct]) -> Void) { + var accounts = [AccountDataStruct]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Account", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + let registers = fetchedRecords + for register in registers { + let temp = AccountDataStruct( + email: (register.value(forKey: "email") as? String)!, + password: (register.value(forKey: "password") as? String)! + ) + accounts.append(temp) + } + completionHandler(accounts) + } + } + } + + func getTracksFromCloudKit(tableView: UITableView, completionHandler: @escaping ([TrackDataStruct]) -> Void){ + var tracks = [TrackDataStruct]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Tracks", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + for record in fetchedRecords { + let asset = (record.value(forKey: "fileData") as? CKAsset)! + let temp = TrackDataStruct( + genre: (record.value(forKey: "genre") as? String)!, + name: (record.value(forKey: "name") as? String)!, +// recordID: record.recordID, + email: (record.value(forKey: "email") as? String)!, + fileURL: asset.fileURL! + ) + tracks.append(temp) + } + DispatchQueue.main.async { + tableView.reloadData() + } + completionHandler(tracks) + } + } + } + + func getTrackFromCloudKit(recordID: CKRecord.ID, completionHandler: @escaping (TrackDataStruct) -> Void) { + CKContainer(identifier: iCloudContainerID).publicCloudDatabase.fetch(withRecordID: recordID) { [unowned self] record, error in + if let error = error { + DispatchQueue.main.async { + print(error.localizedDescription) + } + } else { + if let record = record { + if let asset = record["fileURL"] as? CKAsset { + let upload = TrackDataStruct( + genre: (record.value(forKey: "genre") as? String)!, + name: (record.value(forKey: "name") as? String)!, +// recordID: record.recordID, + email: (record.value(forKey: "email") as? String)!, + fileURL: asset.fileURL! + ) + DispatchQueue.main.async { + do { + self.audioPlayer = try AVAudioPlayer(contentsOf: upload.fileData!.fileURL!) + self.audioPlayer.play() + } catch { + print("play failed") + } + } + } + } + } + } + } + + func downloadVideo(id: CKRecord.ID) { + + CKContainer(identifier: iCloudContainerID).publicCloudDatabase.fetch(withRecordID: id) { (results, error) -> Void in + + // dispatch_async(dispatch_get_main_queue()) { () -> Void in + DispatchQueue.main.async { + if error != nil { + + print(" Error Fetching Record " + error!.localizedDescription) + } else { + if results != nil { + print("pulled record") + + let record = results as CKRecord? + let videoFile = record!.value(forKey: "video") as! CKAsset + + var videoURL = videoFile.fileURL as NSURL? + let videoData = NSData(contentsOf: videoURL! as URL) + + let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + let destinationPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent("filename.mov", isDirectory: false) //This is where I messed up. + + FileManager.default.createFile(atPath: (destinationPath?.path)!, contents:videoData as Data?, attributes:nil) + + videoURL = destinationPath as NSURL? + + // let videoAsset = AVURLAsset(url: videoURL! as URL) + // self.playVideo() + + } else { + print("results Empty") + } + } + } + } + } + + func uploadPhoto(email: String, myImage: UIImage) { + let photoRecord = CKRecord(recordType: "Photos") + photoRecord["email"] = email as CKRecordValue + + + let data = myImage.pngData(); // UIImage -> NSData, see also UIImageJPEGRepresentation + let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(NSUUID().uuidString+".dat") + do { + try data!.write(to: url!, options: []) + } catch let e as NSError { + print("Error! \(e)"); + return + } + photoRecord["fileData"] = CKAsset(fileURL: url!) + + CKContainer(identifier: iCloudContainerID).publicCloudDatabase.save(photoRecord) { record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + } else { + // Delete the temporary file + do { try FileManager.default.removeItem(at: url!) } + catch let e { print("Error deleting temp file: \(e)") } + print("Done!") + } + } + } + } + + func getPhotosFromCloudKit(completionHandler: @escaping ([ProfilePictureDataStruct]) -> Void) { + var photos = [ProfilePictureDataStruct]() + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: iCloudContainerID).publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + let query = CKQuery(recordType: "Photos", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + for record in fetchedRecords { + // let temp = Upload() + // let temp = TrackDataClass() + let asset = (record.value(forKey: "fileData") as? CKAsset)! + let temp = ProfilePictureDataStruct( + fileURL: asset.fileURL!, + email: (record.value(forKey: "email") as? String)! + ) + // temp.audioData = try AVAudioPlayer(contentsOf: asset.fileURL) + + // temp.name = record.value(forKey: "name") as? String + // temp.recordID = record.recordID + photos.append(temp) + // self.uploads.append(temp) + } + completionHandler(photos) + } + } + // print("panjang ", tracks.count) + } + + + class func getDocumentsDirectory() -> URL { + let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) + let documentsDirectory = paths[0] + return documentsDirectory + } + + class func getMusicURL(document: String) -> URL { + return getDocumentsDirectory().appendingPathComponent(document) + } + + func startUploading() { + // 3 + // let audioURL = UploadController.getMusicURL() + // print(audioURL.absoluteString) + + // 4 + let settings = [ + AVFormatIDKey: Int(kAudioFormatMPEG4AAC), + AVSampleRateKey: 12000, + AVNumberOfChannelsKey: 1, + AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue + ] + } + + func doSubmission(document: String) { + let musicRecord = CKRecord(recordType: "Uploads") + musicRecord["genre"] = "Blues" as CKRecordValue + musicRecord["name"] = document as CKRecordValue + musicRecord["email"] = "mnb@mnb" as CKRecordValue + + let audioURL = UploadController.getMusicURL(document: document) + let musicAsset = CKAsset(fileURL: audioURL) + musicRecord["fileData"] = musicAsset + + CKContainer(identifier: iCloudContainerID).publicCloudDatabase.save(musicRecord) { [unowned self] record, error in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error.localizedDescription)") + // self.testButton.titleLabel!.text = + // self.spinner.stopAnimating() + } else { + // self.view.backgroundColor = UIColor(red: 0, green: 0.6, blue: 0, alpha: 1) + // self.testButton.titleLabel!.text = "Done!" + // self.spinner.stopAnimating() + print("Done!") + // ViewController.isDirty = true + } + + // self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.doneTapped)) + } + } + } +} +/* +extension UploadController: MPMediaPickerControllerDelegate, UINavigationControllerDelegate { + // MARK: Func to open media library function + func openMediaPlayer() { + // let imagePicker = UIImagePickerController() + let mediaPicker = MPMediaPickerController(mediaTypes: .anyAudio) + mediaPicker.delegate = self + // imagePicker.delegate = self + let actionAlert = UIAlertController(title: "Browse attachment", message: "Choose source", preferredStyle: .alert) + // actionAlert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { + // actionAlert.addAction(UIAlertAction(title: "Media", style: .default, handler: { + // (action:UIAlertAction) in + // if UIImagePickerController.isSourceTypeAvailable(.camera) { + // imagePicker.sourceType = .camera + // self.present(imagePicker, animated:true, completion: nil) + // }else{ + // print("Camera is not available at this device") + // } + // })) // give an option in alert controller to open camera + + // actionAlert.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action: UIAlertAction) in + actionAlert.addAction(UIAlertAction(title: "Media Library", style: .default, handler: { (action: UIAlertAction) in + // imagePicker.sourceType = .photoLibrary + // mediaPicker.mediaTypes = .anyAudio + // imagePicker.mediaTypes = ["public.image", "public.movie"] + // picker.delegate = self + mediaPicker.allowsPickingMultipleItems = false + mediaPicker.prompt = "Choose a song" + // present(picker, animated: true, completion: nil) + self.present(mediaPicker, animated:true, completion: nil) + })) // give the second option in alert controller to open Photo library + + actionAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) // give the third option in alert controller to cancel the form + + self.present(actionAlert, animated: true, completion: nil) + } + + + func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) { + // if let imageTaken = info[.originalImage] as? UIImage { + // if let mediaItems = mediaItemCollection.items { + if let mediaItems = MPMediaQuery.songs().items { + let mediaCollection = MPMediaItemCollection(items: mediaItems) + mediaPicker.dismiss(animated: true) { + // self.settingImage?.image = imageTaken + let player = MPMusicPlayerController.systemMusicPlayer + player.setQueue(with: mediaCollection) + player.play() + } + } + } +} +*/ + +//MARK: - Ext. Delegate DocumentPicker +extension UploadController: UIDocumentPickerDelegate { + func openDocumentPicker() { + let documentsPicker = UIDocumentPickerViewController(documentTypes: ["public.image", "public.jpeg", "public.png"], in: .open) + documentsPicker.delegate = self + documentsPicker.modalPresentationStyle = .fullScreen + // self.presentationController?.present(documentsPicker, animated: true, completion: nil) + } + public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { + guard controller.documentPickerMode == .open, let url = urls.first, url.startAccessingSecurityScopedResource() else { return } + // defer { url.stopAccessingSecurityScopedResource() } + + guard let image = UIImage(contentsOfFile: url.path) else { return } + // self.delegate?.didSelect(image: image) + controller.dismiss(animated: true) + } + + public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { + controller.dismiss(animated: true) + } +} diff --git a/frontend/mobile/CommunityMC3/CommunityMC3.entitlements b/frontend/mobile/CommunityMC3/CommunityMC3.entitlements new file mode 100644 index 0000000..109ab1f --- /dev/null +++ b/frontend/mobile/CommunityMC3/CommunityMC3.entitlements @@ -0,0 +1,18 @@ + + + + + aps-environment + development + com.apple.developer.icloud-container-identifiers + + iCloud.ada.mc3.music + + com.apple.developer.icloud-services + + CloudKit + + com.apple.developer.ubiquity-kvstore-identifier + $(TeamIdentifierPrefix)$(CFBundleIdentifier) + + diff --git a/frontend/mobile/CommunityMC3/DB_Model.xcdatamodeld/DB_Model.xcdatamodel/contents b/frontend/mobile/CommunityMC3/DB_Model.xcdatamodeld/DB_Model.xcdatamodel/contents new file mode 100644 index 0000000..690ce0e --- /dev/null +++ b/frontend/mobile/CommunityMC3/DB_Model.xcdatamodeld/DB_Model.xcdatamodel/contents @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/mobile/CommunityMC3/Data/Account+Extension.swift b/frontend/mobile/CommunityMC3/Data/Account+Extension.swift new file mode 100644 index 0000000..501e1d1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Account+Extension.swift @@ -0,0 +1,105 @@ +// +// Account+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import CoreData + +class AccountDataStruct +{ + var email:String + var password:String + + var user:UserDataStruct? + init(email:String, password:String) { + self.email = email + self.password = password + } +} + +extension Account { + + static func registerAccount(context: NSManagedObjectContext, accountEmail: String, accountPassword: String) -> Account? { + let account = Account(context: context) + account.email = accountEmail + account.password = accountPassword + // task.subtask = [] + // guard ((try? context.save()) != nil) else { + // return nil + // } + // return task + do { + try context.save() + return account + } catch { + return nil + } + } + + static func loginAccount(context: NSManagedObjectContext, accountEmail: String, accountPassword: String) -> Account? { + let request: NSFetchRequest = Account.fetchRequest() + do { + let accounts = try context.fetch(request) + for account in accounts { + if account.email == accountEmail && account.password == accountPassword { + return account + } + } + return nil + } catch { + return nil + } + } + + static func editAccount(context: NSManagedObjectContext, accountEmail: String, accountPassword: String) -> Bool { + // let request: NSFetchRequest = Account.fetchRequest() + // let predicate = NSPredicate(format: "taskName BEGINSWITH 'v'") + // request.predicate = predicate + // if accountEmail == "" || accountPassword == "" { + // let deletedRequest = NSBatchDeleteRequest(fetchRequest: request) + // let result = try? context.execute(deletedRequest) + // if (result != nil) { + // let account = Account(context: context) + // if accountEmail != "" { + // account.email = accountEmail + // } + // if accountPassword != "" { + // account.password = accountPassword + // } + // do { + // try context.save() + // return true + // } catch { + // return false + // } + // } + // return false + // }else { + let request: NSFetchRequest = Account.fetchRequest() + var response = false + do { + let accounts = try context.fetch(request) + for account in accounts { + if account.email != "" && account.password == accountPassword { + account.setValue(accountEmail, forKey: "email") + response = true + } + if account.email == accountEmail && account.password != "" { + account.setValue(accountPassword, forKey: "password") + response = true + } + } + return response + } catch { + return false + } + // } + } + + + +} diff --git a/frontend/mobile/CommunityMC3/Data/Album+Extension.swift b/frontend/mobile/CommunityMC3/Data/Album+Extension.swift new file mode 100644 index 0000000..e05b1d0 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Album+Extension.swift @@ -0,0 +1,21 @@ +// +// Album.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit + +class AlbumDataStruct +{ + var cover:UIImage? + var name:String + init() + { + cover = UIImage(color: .red) + name = "" + } +} diff --git a/frontend/mobile/CommunityMC3/Data/Constant.swift b/frontend/mobile/CommunityMC3/Data/Constant.swift new file mode 100644 index 0000000..d2c6af3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Constant.swift @@ -0,0 +1,45 @@ +// +// Constant.swift +// CommunityMC3 +// +// Created by Bernardinus on 26/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation + +var showLogin:Bool = false + +let iCloudContainerID:String = "iCloud.ada.mc3.music" + +let availableAudioFilesExt:[String] = [ + "mp3", + "m4a", + "wav", + "mpeg", +] + +let availableVideoFilesExt:[String] = [ + "mp4", + "m4v", + "mov" +] + +let musicGenreArray:[String] = [ + "Rock", + "Jazz", + "Pop", + "RnB", + "Acoustic", + "Blues" +] + +var explorerViewTableCount:[String:Int] = [ + "trendingNow":3, + "discoverNew":1, + "latestMusic":3, + "featuredArtist":1, + "featuredVideo":3 +] + + diff --git a/frontend/mobile/CommunityMC3/Data/Favourites+Extension.swift b/frontend/mobile/CommunityMC3/Data/Favourites+Extension.swift new file mode 100644 index 0000000..981c4cb --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Favourites+Extension.swift @@ -0,0 +1,81 @@ +// +// Favourites+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import CloudKit + +class FavouritesDataStruct +{ + var id:String + var album:[AlbumDataStruct]? + // var track:[TrackDataStruct]? + var track:[PrimitiveTrackDataStruct]? + var trackRef: CKRecord? + var user:[UserDataStruct]? + // var videos:[VideosDataStruct]? + var videos:[PrimitiveVideosDataStruct]? + var videoRef: CKRecord? + + + + func getCKRecord() -> CKRecord + { + let record = CKRecord(recordType: "Favourites") + + record.setValue(id, forKey: "id") + + if trackRef != nil + { + let trackRef = CKRecord.Reference(record: self.trackRef!, action: .deleteSelf) + record.setValue(trackRef, forKey: "trackRef") + } + else + { + record.setNilValueForKey("trackRef") + } + + if videoRef != nil + { + let videoRef = CKRecord.Reference(record: self.videoRef!, action: .deleteSelf) + record.setValue(videoRef, forKey: "videoRef") + } + else + { + record.setNilValueForKey("videoRef") + } + + return record + } + +// func getDataStruct()->FavouritesDataStruct { +// let favourite = FavouriteData +// } + + + init(id:String, + album:[AlbumDataStruct] = [], + // track:[TrackDataStruct] = [], + track:[PrimitiveTrackDataStruct] = [], + // videos:[VideosDataStruct] = [], + videos:[PrimitiveVideosDataStruct] = [], + user:[UserDataStruct]? = [] + ) + { + self.id = id + self.album = album + self.track = track + self.videos = videos + } + + func asDict()->[String:Any] + { + return [ + "id":id + ] + } +} diff --git a/frontend/mobile/CommunityMC3/Data/Featured+Extension.swift b/frontend/mobile/CommunityMC3/Data/Featured+Extension.swift new file mode 100644 index 0000000..cb32aef --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Featured+Extension.swift @@ -0,0 +1,49 @@ +// +// Featured+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import CloudKit + + +// specific ID +public var FeaturedID_Artist = "featuredArtist" + +class FeaturedDataStruct +{ + // var id:String + var id: CKRecord.ID? + + var track: TrackDataStruct? + var user: UserDataStruct? + var video: VideosDataStruct? + + var tracks:[TrackDataStruct] = [] + var users:[UserDataStruct] = [] + var videos:[VideosDataStruct] = [] + + init() + { + } + init(id:CKRecord.ID, user:UserDataStruct) + { + self.id = id + self.user = user + } + + init(id:CKRecord.ID, track:TrackDataStruct) + { + self.id = id + self.track = track + } + + init(id:CKRecord.ID, video:VideosDataStruct) + { + self.id = id + self.video = video + } +} diff --git a/frontend/mobile/CommunityMC3/Data/Photos+Extension.swift b/frontend/mobile/CommunityMC3/Data/Photos+Extension.swift new file mode 100644 index 0000000..4b65ea9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Photos+Extension.swift @@ -0,0 +1,58 @@ +// +// Photos+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit +import CloudKit + +class PhotoDataStruct +{ + // var fileData:UIImage? + + var record:CKRecord? = nil + var photosData: UIImage? + var email: String? = nil +// var genre:String +// var name: String + + init(record:CKRecord) + { + self.record = record + + let data = record.value(forKey: "photosData") + if( data != nil) + { + photosData = UIImage(data: data as! Data) + } + +// genre = "" +// name = "" + + } + + init() + { + photosData = UIImage(color: .red) + email = "" +// genre = "" +// name = "" + } + + func getCKRecord()->CKRecord + { + var newRecord = CKRecord(recordType: "Photos") + newRecord.setValue(email, forKey: "email") + newRecord.setValue(photosData?.pngData(), forKey: "photosData") + return newRecord + } +} + +struct ProfilePictureDataStruct { + var fileURL: URL + var email: String +} diff --git a/frontend/mobile/CommunityMC3/Data/Track+Extension.swift b/frontend/mobile/CommunityMC3/Data/Track+Extension.swift new file mode 100644 index 0000000..f4ad4ff --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Track+Extension.swift @@ -0,0 +1,122 @@ +// +// Track+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import AVFoundation +import CloudKit +import UIKit + + +struct PrimitiveTrackDataStruct: Codable +{ + var genre:String + var name:String + + var email: String +} + +class TrackDataStruct +{ + var record: CKRecord? + + var album:AlbumDataStruct? + var artistName:String = "artistName" + var coverImage:UIImage? + var email: String = "email" + var fileData: CKAsset? + var genre:String = "musicGenre" + var isCoverSong:Bool = false + var name:String = "musicName" + var duration:String = "00:00" + +// var audioData:AVAudioPlayer? + + + + init(record:CKRecord) + { + self.record = record + + let artistData = record.value(forKey: "artistName") + if artistData != nil + { + self.artistName = artistData as! String + } + + let coverImageData = record.value(forKey: "coverImage") + if(coverImageData != nil) + { + coverImage = UIImage(data: coverImageData as! Data) + } + self.email = record.value(forKey: "email") as! String + + self.fileData = record.value(forKey: "fileData") as? CKAsset + do { + let player = try AVAudioPlayer(contentsOf: fileData!.fileURL!) + let minute = Int(player.duration / 60) + let second = Int(player.duration) - minute * 60 + duration = "\(minute):\(String(format: "%2d", second))" + } catch let error as NSError { + print("Load \(artistName) Track \(name) Error:\(error)") + } + + let genreData = record.value(forKey: "genre") + if genreData != nil + { + self.genre = genreData as! String + } + + let isCoverSongData = record.value(forKey: "isCoverSong") + var isCoverSongDataIntValue:Int = 0 + if(isCoverSongData != nil ) + { + isCoverSongDataIntValue = isCoverSongData as! Int + + if(isCoverSongDataIntValue == 1) + { + self.isCoverSong = true + } + } + + let nameData = record.value(forKey: "name") + if(nameData != nil) + { + self.name = nameData as! String + } + + } + +// init() +// { +// self.genre = "" +// self.name = "" +// self.email = "" +// self.fileData = CKAsset(fileURL: URL(string: "")!) +// } +// + init(genre:String, name:String, email:String, fileURL:URL) + { + self.genre = genre + self.name = name + self.email = email + self.fileData = CKAsset(fileURL:fileURL) + } + + func getCKRecord()->CKRecord + { + var record = CKRecord(recordType: "Track") + record.setValue(nil, forKey: "album") + record.setValue(genre, forKey: "genre") + record.setValue(email, forKey: "email") + record.setValue(name, forKey: "name") + record.setValue(fileData, forKey: "fileData") + record.setValue(DataManager.shared().currentUser?.name, forKey: "artistName") + record.setValue(coverImage?.pngData(), forKey: "coverImage") + return record + } +} diff --git a/frontend/mobile/CommunityMC3/Data/UploadedData+Extension.swift b/frontend/mobile/CommunityMC3/Data/UploadedData+Extension.swift new file mode 100644 index 0000000..fa6d7d2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/UploadedData+Extension.swift @@ -0,0 +1,114 @@ +// +// UploadedData+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import CloudKit + +class UploadedDataStruct +{ + // param + var uploadedDate:Date? + + // ref +// var track:TrackDataStruct? +// var video:VideosDataStruct? + var trackRecord:CKRecord? + var videoRecord:CKRecord? + + var isVideo:Bool = false + + var trackData:TrackDataStruct? + var videoData:VideosDataStruct? + + init(){ + isVideo = false + } + /* + init(record:CKRecord) + { + uploadedDate = record.value(forKey: "uploadedDate") as? Date + + let trackRef = record.value(forKey: "track") as? CKRecord.Reference + if(trackRef != nil) + { + CloudKitUtil.shared().loadRecordFromPublicDB(recordID: trackRef!.recordID, completionHandler: { + (isSuccess, errorString, record) in + if(isSuccess) + { + self.trackRecord = record + } + + }) + } + + let videoRef = record.value(forKey: "video") as? CKRecord.Reference + if(videoRef != nil) + { + CloudKitUtil.shared().loadRecordFromPublicDB(recordID: videoRef!.recordID, completionHandler: { + (isSuccess, errorString, record) in + if(isSuccess) + { + self.videoRecord = record + } + + }) + } + + isVideo = self.videoRecord != nil + } + */ + + init(uploadedDate:Date, track:CKRecord?, video:CKRecord?) + { + self.uploadedDate = uploadedDate + self.trackRecord = track + self.videoRecord = video + } + + func updateData(recordMediaData:CKRecord) + { +// print("recordData \(recordMediaData)") + if(isVideo) + { + videoData = VideosDataStruct(record: recordMediaData) + } + else + { + trackData = TrackDataStruct(record: recordMediaData) + } + } + + func getCKRecord() -> CKRecord + { + let record = CKRecord(recordType: "UploadedData") + + record.setValue(uploadedDate, forKey: "uploadedDate") + + if trackRecord != nil + { + let trackRef = CKRecord.Reference(record: trackRecord!, action: .deleteSelf) + record.setValue(trackRef, forKey: "track") + } + else + { + record.setNilValueForKey("track") + } + + if videoRecord != nil + { + let trackRef = CKRecord.Reference(record: videoRecord!, action: .deleteSelf) + record.setValue(trackRef, forKey: "video") + } + else + { + record.setNilValueForKey("video") + } + + return record + } +} diff --git a/frontend/mobile/CommunityMC3/Data/UserData+Extension.swift b/frontend/mobile/CommunityMC3/Data/UserData+Extension.swift new file mode 100644 index 0000000..784809e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/UserData+Extension.swift @@ -0,0 +1,195 @@ +// +// UserData+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit +import CloudKit + +struct PrimitiveUserDataStruct: Codable { + var email: String + var password: String + var name: String + var role: String + var profilePicture: String +} + +class UserDataStruct +{ + var record:CKRecord? = nil + + // normal data + var followerCount:Int? = 0 + var genre:String? = "" + var instagram:String? = "" + var isVerified:Bool = false // saved as Int(64) + var name:String? = "" + var phoneNumber:String? = "" + var role:String? = "" + var whatsApp:String? = "" + + var fileURL:URL? = nil + var email: String? = "" + + var isArtist = false + + // asset + var profilePicture:UIImage? = nil + + // ref + var albums:AlbumDataStruct? = nil + var favourites:FavouritesDataStruct? = nil + var musics:[TrackDataStruct]? = [] + var photos:[PhotoDataStruct]? = [] + var videos:[VideosDataStruct]? = [] + var recordID:CKRecord.ID? = nil + + var favMusics:[String]? = [] + var favArtist:[String]? = [] + var favVideo:[String]? = [] + + init(){} + init(genre:String, name:String, fileURL:URL, email:String){ + self.genre = genre + self.name = name + self.fileURL = fileURL + self.email = email + } + + init(_ record:CKRecord) + { + self.record = record + self.name = record.value(forKey: "name") as? String + self.genre = record.value(forKey: "genre") as? String + self.followerCount = record.value(forKey: "followerCount") as? Int + + let isVerifiedData = record.value(forKey: "isVerified") + var isVerifiedIntValue:Int = 0 + if(isVerifiedData != nil ) + { + isVerifiedIntValue = isVerifiedData as! Int + } + + if(isVerifiedIntValue == 1) + { + self.isVerified = true + } + + + let isArtistData = record.value(forKey: "isArtist") + var isArtistIntValue:Int = 0 + if(isArtistData != nil ) + { + isArtistIntValue = isArtistData as! Int + } + if(isArtistIntValue == 1) + { + self.isArtist = true + } + + self.phoneNumber = record.value(forKey: "phoneNumber") as? String + self.role = record.value(forKey: "role") as? String + self.instagram = record.value(forKey: "instagram") as? String + self.whatsApp = record.value(forKey: "whatsapp") as? String +// self.profilePicture = UIImage(data: record.value(forKey: "profilePicture") as! Data) + + let profPicData = record.value(forKey: "profilePicture") + if(profPicData != nil ) + { + self.profilePicture = UIImage(data: record.value(forKey: "profilePicture") as! Data) + } + + self.email = record.value(forKey: "email") as? String + + let favMusicsData = record.value(forKey: "favTracks") + if(favMusicsData != nil ) + { + self.favMusics = favMusicsData as? [String] + } + + let favArtistData = record.value(forKey: "favArtist") + if(favArtistData != nil ) + { + self.favArtist = favArtistData as? [String] + } + + let favVideoData = record.value(forKey: "favVideo") + if(favVideoData != nil ) + { + self.favVideo = favVideoData as? [String] + } + + } + + func isFavMusic(recName:String)-> Bool + { + if(favMusics != nil) + { + return favMusics!.contains(recName) + } + return false + } + + func isFavArtist(recName:String) -> Bool + { + if(favArtist != nil) + { + return favArtist!.contains(recName) + } + return false + } + + func isFavVideo(recName:String) -> Bool + { + if(favVideo != nil) + { + return favVideo!.contains(recName) + } + return false + } + + + /* + func UserDataStruct(record:CKRecord) + { + followerCount = record.value(forKey: "followerCount") as? Int + genre = record.value(forKey: "followerCount") as? String + instagram = record.value(forKey: "instagram") as? String + let boolValue = record.value(forKey: "isVerified") as? Int + isVerified = (boolValue == 1) ? true : false + name = record.value(forKey: "name") as? String + phoneNumber = record.value(forKey: "phoneNumber") as? String + role = record.value(forKey: "role") as? String + whatsApp = record.value(forKey: "whatsApp") as? String + profilePicture = UIImage(data: (record.value(forKey: "profilePicture") as? Data)!) + } + */ + + func asDict()->[String:Any] + { + return [ + "name": name!, + "genre":genre!, + "followerCount":followerCount!, + "isVerified":Int(truncating: NSNumber(value: isVerified)), + "phoneNumber":phoneNumber!, + "role":role!, + "instagram":instagram!, + "whatsApp":"", + "profilePicture":profilePicture!.pngData()!, + "email":email + ] + } + + func getCKRecord() -> CKRecord + { + let newRecord = CKRecord(recordType: "UserData") + newRecord.setValuesForKeys(asDict()) + return newRecord + } + +} diff --git a/frontend/mobile/CommunityMC3/Data/Videos+Extension.swift b/frontend/mobile/CommunityMC3/Data/Videos+Extension.swift new file mode 100644 index 0000000..cdb92fc --- /dev/null +++ b/frontend/mobile/CommunityMC3/Data/Videos+Extension.swift @@ -0,0 +1,116 @@ +// +// Videos+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import AVKit +import CloudKit + +class VideosDataStruct +{ + var record:CKRecord? = nil + + // ref + var album:AlbumDataStruct? = nil + + + // normal param + var artistName:String = "artistName" + var coverImage:UIImage? = nil + var email:String = "videoEmail" + var fileData:CKAsset? = nil + var genre:String = "videoGenre" + var isCoverSong:Bool = false + var name:String = "videoName" + + // asset + var videoData:AVPlayer? = nil + + init(record:CKRecord) + { + self.record = record + + let artistData = record.value(forKey: "artistName") + if artistData != nil + { + self.artistName = artistData as! String + } + + + let coverImageData = record.value(forKey: "coverImage") + if(coverImageData != nil) + { + coverImage = UIImage(data: coverImageData as! Data) + } + self.email = record.value(forKey: "email") as! String + + self.fileData = record.value(forKey: "fileData") as? CKAsset + + let genreData = record.value(forKey: "genre") + if genreData != nil + { + self.genre = genreData as! String + } + + let isCoverSongData = record.value(forKey: "isCoverSong") + var isCoverSongDataIntValue:Int = 0 + if(isCoverSongData != nil ) + { + isCoverSongDataIntValue = isCoverSongData as! Int + + if(isCoverSongDataIntValue == 1) + { + self.isCoverSong = true + } + } + + let nameData = record.value(forKey: "name") + if(nameData != nil) + { + self.name = nameData as! String + } + } + + init() + { + self.genre = "" + self.name = "" + self.email = "" + self.fileData = CKAsset(fileURL: URL(string: "")!) + + } + + init(genre: String, name:String, email:String, fileURL:URL) + { + self.genre = genre + self.name = name + self.email = email + self.fileData = CKAsset(fileURL:fileURL) + + } + + func getCKRecord()->CKRecord + { + var record = CKRecord(recordType: "Videos") + record.setValue(nil, forKey: "album") + record.setValue(genre, forKey: "genre") + record.setValue(email, forKey: "email") + record.setValue(name, forKey: "name") + record.setValue(fileData, forKey: "fileData") + record.setValue(DataManager.shared().currentUser?.name, forKey: "artistName") + record.setValue(coverImage?.pngData(), forKey: "coverImage") + return record + } +} + +struct PrimitiveVideosDataStruct: Codable +{ + // normal param + var genre:String + var name:String + var email:String +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Discover New/DiscoverNewCell.swift b/frontend/mobile/CommunityMC3/Explorer View/Discover New/DiscoverNewCell.swift new file mode 100644 index 0000000..2ebcbde --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Discover New/DiscoverNewCell.swift @@ -0,0 +1,37 @@ +// +// DiscoverNewCell.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class DiscoverNewCell: UITableViewCell { + + + @IBOutlet weak var tapSurpriseButton: UIButton! + @IBOutlet weak var tapSupriseLabel: UILabel! + + var callBack: (() -> Void)? = nil + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + tapSupriseLabel.text = NSLocalizedString("Suprise".uppercased(), comment: "") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + @IBAction func randomSpotlightButton(_ sender: Any) { + self.callBack!() + } + + func setCallBack(callback: (() -> Void)?){ + self.callBack = callback + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Discover New/DiscoverNewCell.xib b/frontend/mobile/CommunityMC3/Explorer View/Discover New/DiscoverNewCell.xib new file mode 100644 index 0000000..d7330fd --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Discover New/DiscoverNewCell.xib @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/DiscoverNewCell 2.swift b/frontend/mobile/CommunityMC3/Explorer View/DiscoverNewCell 2.swift new file mode 100644 index 0000000..3c90e2c --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/DiscoverNewCell 2.swift @@ -0,0 +1,25 @@ +// +// DiscoverNewCell.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class DiscoverNewCell: UITableViewCell { + + @IBOutlet weak var CellName: UILabel! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/DiscoverNewCell 2.xib b/frontend/mobile/CommunityMC3/Explorer View/DiscoverNewCell 2.xib new file mode 100644 index 0000000..b2e5f2f --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/DiscoverNewCell 2.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Explorer.storyboard b/frontend/mobile/CommunityMC3/Explorer View/Explorer.storyboard new file mode 100644 index 0000000..20f5bb2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Explorer.storyboard @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/ExplorerView.swift b/frontend/mobile/CommunityMC3/Explorer View/ExplorerView.swift new file mode 100644 index 0000000..40fb885 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/ExplorerView.swift @@ -0,0 +1,631 @@ +// +// FirstViewController.swift +// CommunityMC3 +// +// Created by Bryanza on 06/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +//import BonsaiController +import CloudKit + +enum ExplorerSection:Int { + case TrendingNow = 0 + case DiscoverNew = 1 + case LatestMusic = 2 + case FeaturedArtist = 3 + case FeaturedVideos = 4 + case Count = 5 +} + +/* + private enum TransitionType { + case none + case bubble + case slide(fromDirection: Direction) + case menu(fromDirection: Direction) + } + */ + +class ExplorerView: UIViewController { + + @IBOutlet weak var ExploreTitleLabel: UILabel! + @IBOutlet weak var mainTableView: UITableView! + @IBOutlet weak var notificationsIconImage: UIImageView! + + let documentController = DocumentTableViewController.shared + let videoController = VideoPlayerViewController.shared + let uploadController = UploadController.shared + let userDefault = UserDefaults.standard + // var tracks = [TrackDataStruct]() + // var videos = [VideosDataStruct]() + var uploads = [UploadedDataStruct]() + var features = [FeaturedDataStruct]() + var trendings = [FeaturedDataStruct]() + var artistCount = 0 + var uploadCount = 0 + var selectedRow = 0 + var selectUpload = false + var selectFeatured = false + var selectTrending = false + var dm:DataManager = DataManager.shared() + + override func viewDidLoad() { + super.viewDidLoad() + // dm.initData() + mainTableView.separatorStyle = UITableViewCell.SeparatorStyle.none + ExploreTitleLabel.text = NSLocalizedString("Explore", comment: "") + + + // Do any additional setup after loading the view. + + mainTableView.register(UINib(nibName: "TrendingNowCell", bundle:nil), forCellReuseIdentifier: "trendingNowCell") + mainTableView.register(UINib(nibName: "HeaderCell", bundle:nil), forCellReuseIdentifier: "headerCell") + mainTableView.register(UINib(nibName: "DiscoverNewCell", bundle:nil), forCellReuseIdentifier: "discoverNewCell") + mainTableView.register(UINib(nibName: "LatestMusicCell", bundle:nil), forCellReuseIdentifier: "latestMusicCell") + mainTableView.register(UINib(nibName: "FeaturedArtistCell", bundle:nil), forCellReuseIdentifier: "featuredArtistCell") + mainTableView.register(UINib(nibName: "FeaturedVideosCell", bundle:nil), forCellReuseIdentifier: "featuredVideosCell") + mainTableView.canCancelContentTouches = true + // mainTableView.delaysContentTouches = true; + + // hightlightUpload() + featuredCombine() + // latestUpload() + + } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + } + + func passTabData() { + let favoriteTab = self.tabBarController?.viewControllers![2] as! FavouritesView + favoriteTab.uploads = DataManager.shared().latestUploadRecord + } + + /* + func hightlightUpload() { + uploadController.getTracksFromCloudKit(tableView: mainTableView) { (tracks) in + for track in tracks { + // let temp = FeaturedDataStruct ( + // id: track.recordID, + // track: track + // ) + // self.trendings.append(temp) + // self.features.append(temp) + // self.uploadCount += 1 + } + } + + documentController.getFilmsFromCloudKit { (videos) in + for video in videos { + let temp = FeaturedDataStruct ( + id: video.recordID, + video: VideosDataStruct ( + genre: (video.value(forKey: "genre") as? String)!, + name: (video.value(forKey: "name") as? String)!, + email: (video.value(forKey: "email") as? String)!, + fileURL: (video.value(forKey: "fileData") as? CKAsset)!.fileURL! + ) + ) + self.trendings.append(temp) + self.features.append(temp) + self.uploadCount += 1 + } + } + } + */ + + func featuredCombine() { + documentController.getProfilesFromCloudKit { (photos) in + for photo in photos { + let asset = (photo.value(forKey: "fileData") as? CKAsset)! + let temp = FeaturedDataStruct ( + id: photo.recordID, + user: UserDataStruct( + genre: (photo.value(forKey: "genre") as? String)!, + name: (photo.value(forKey: "name") as? String)!, + fileURL: asset.fileURL!, + email: (photo.value(forKey: "email") as? String)! + ) + ) + self.features.append(temp) + self.artistCount += 1 + } + } + } + + /* + func latestUpload() { + documentController.getUploadsFromCloudKit(tableView: mainTableView) { (tracks) in + // self.tracks = tracks + for track in tracks { + let temp = UploadedDataStruct ( + uploadedDate: track.creationDate!, + track: TrackDataStruct ( + genre: (track.value(forKey: "genre") as? String)!, + name: (track.value(forKey: "name") as? String)!, + recordID: track.recordID, + email: (track.value(forKey: "email") as? String)!, + fileURL: (track.value(forKey: "fileData") as? CKAsset)!.fileURL! + ) + ) + self.uploads.append(temp) + } + // print("count ", tracks.count) + } + + documentController.getFilmsFromCloudKit { (videos) in + // self.videos = videos + for video in videos { + let temp = UploadedDataStruct ( + uploadedDate: video.creationDate!, + video: VideosDataStruct ( + genre: (video.value(forKey: "genre") as? String)!, + name: (video.value(forKey: "name") as? String)!, + email: (video.value(forKey: "email") as? String)!, + fileURL: (video.value(forKey: "fileData") as? CKAsset)!.fileURL! + ) + ) + // let tmp = self.videoController.retrieveVideo(video: temp.video)! + // temp.video?.fileURL = tmp + self.uploads.append(temp) + } + } + + // self.uploads = self.uploads.sorted(by: { $0.uploadedDate.compare($1.uploadedDate) == .orderedDescending }) + + } + */ + + + + @IBAction func accountButtonTouched(_ sender: Any) + { + if DataManager.shared().IsUserLogin() + { + self.performSegue(withIdentifier: "userProfileSegue", sender: nil) + } + else + { + self.performSegue(withIdentifier: "loginScreenSegue", sender: nil) + } + } + + @IBAction func notificationButtonTouched(_ sender: Any) + { + // self.performSegue(withIdentifier: "notificationScreenSegue", sender: nil) + print("openInstagram") + openInstagram(username: "ubmuniversity") + + + } + + @IBAction func unwindToExplorerView(_ segue:UIStoryboardSegue) + { + + } + + /* + private var transitionType: TransitionType = .none + private func showSmallVC(transition: TransitionType) + { + + transitionType = transition + let sb = UIStoryboard(name: "SmallViewController", bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: "SmallVC") as! SmallViewController + vc.transitioningDelegate = self + vc.modalPresentationStyle = .custom + present(vc, animated: true, completion: nil) + } + */ + + // MARK: Storyboard + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + print("Prepare Segue \(segue.identifier)") + if segue.identifier == "trendingSegue" { + if let trendingPage = segue.destination as? TrendingNowVC { + trendingPage.trendings = dm.trendingNow + // var temp = [FeaturedDataStruct]() + // for trending in trendings { + // temp.append(trending) + // } + // trendingPage.trendings = temp + trendingPage.mainTableView = mainTableView + } + } + else if segue.identifier == "featuredArtistSegue" { + if let artistPage = segue.destination as? FeaturedArtistVC { + artistPage.features = dm.featuredArtist + /* + var temp = [FeaturedDataStruct]() + for feature in features { + if feature.user != nil { + temp.append(feature) + } + } + artistPage.features = temp + */ + } + } + else if segue.identifier == "featuredVideoSegue" { + if let featuredPage = segue.destination as? FeaturedVideosVC { + featuredPage.features = dm.featuredVideos + /* + var temp = [FeaturedDataStruct]() + for feature in features { + if feature.user == nil { + temp.append(feature) + } + } + featuredPage.features = temp + featuredPage.mainTableView = mainTableView + */ + } + } + else if segue.identifier == "latestMusicSegue" { + // print("masuk ", tracks.count) + // let navPage = segue.destination as! UINavigationController + // let latestMusicPage = navPage.topViewController as! LatestMusicVC + if let latestMusicPage = segue.destination as? LatestMusicVC { + latestMusicPage.uploads = dm.latestUpload + latestMusicPage.mainTableView = mainTableView + } + } + else if segue.identifier == "trackPlayerSegue" { + if let trackPlayerPage = segue.destination as? TrackPlayerViewController { + if selectUpload { + selectUpload = false + trackPlayerPage.track = dm.latestUpload![selectedRow].trackData + }else if selectTrending { + selectTrending = false + trackPlayerPage.track = sender as! TrackDataStruct + }else { + selectFeatured = false + trackPlayerPage.track = features[selectedRow].track + } + } + } + else if segue.identifier == "videoPlayerSegue" { + if let videoPlayerPage = segue.destination as? VideoPlayerViewController { + if selectUpload { + selectUpload = false + // videoPlayerPage.video = uploads[selectedRow].video + }else if selectTrending { + selectTrending = false + videoPlayerPage.video = trendings[selectedRow].video + }else { + selectFeatured = false + // videoPlayerPage.video = dm.featuredVideos?.videos[selectedRow]// features[selectedRow].video + + } + } + } + else if segue.identifier == "loginScreenSegue" + { + let loginView = segue.destination as! LoginController + loginView.callBack = { + loginView.dismiss(animated: true) { + self.performSegue(withIdentifier: "userProfileSegue", sender: nil) + } + } + } + else if segue.identifier == "artistPageSegue" + { + let artistVC = segue.destination as! UserProfileVC + artistVC.isPersonalProfile = false + artistVC.userData = sender as? UserDataStruct + } + else if segue.identifier == "userProfileSegue" + { + let profileVC = segue.destination as! UserProfileVC +// profileVC.signOutCallback = { +// profileVC.dismiss(animated: true) { +// self.performSegue(withIdentifier: "userProfileSegue", sender: nil) +// } +// } +// artistVC.isPersonalProfile = false +// artistVC.userData = sender as? UserDataStruct + } + } + + override func viewWillAppear(_ animated: Bool) { + if(showLogin) + { + showLogin = false + performSegue(withIdentifier: "loginScreenSegue", sender: nil) + } + + navigationController?.setNavigationBarHidden(true, animated: false) + navigationController?.navigationBar.shadowImage = nil + super.viewWillAppear(true) + } + + +} + + + +extension ExplorerView:UITableViewDelegate, UITableViewDataSource +{ + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let cell = mainTableView.dequeueReusableCell(withIdentifier: "headerCell") as! HeaderCell + if(section == ExplorerSection.TrendingNow.rawValue) + { + cell.HeaderName.text = NSLocalizedString("Trending Now", comment: "") + cell.HeaderName.textColor = #colorLiteral(red: 1, green: 0.8352941176, blue: 0.2509803922, alpha: 1) + cell.sectionBlock.backgroundColor = #colorLiteral(red: 1, green: 0.8352941176, blue: 0.2509803922, alpha: 1) + cell.seeMoreButton.setTitle(NSLocalizedString("See more >", comment: ""), for: .normal) + cell.seeMoreButton.setTitleColor(UIColor.white, for: .normal) + cell.callBack = { + self.performSegue(withIdentifier: "trendingSegue", sender: nil) + } + cell.headerBackgroundView.layer.backgroundColor = #colorLiteral(red: 0.2784313725, green: 0, blue: 0.7843137255, alpha: 1) + } + else if(section == ExplorerSection.DiscoverNew.rawValue) + { + cell.HeaderName.text = NSLocalizedString("Discover New", comment: "") + cell.seeMoreButton.isHidden = true + } + else if(section == ExplorerSection.LatestMusic.rawValue) + { + cell.HeaderName.text = NSLocalizedString("Latest Upload", comment: "") + cell.seeMoreButton.setTitle(NSLocalizedString("See more >", comment: ""), for: .normal) + cell.callBack = { + self.performSegue(withIdentifier: "latestMusicSegue", sender: nil) + } + } + else if(section == ExplorerSection.FeaturedArtist.rawValue) + { + cell.HeaderName.text = NSLocalizedString("Featured Artist", comment: "") + cell.seeMoreButton.setTitle(NSLocalizedString("More artist >", comment: ""), for: .normal) + cell.callBack = { + self.performSegue(withIdentifier: "featuredArtistSegue", sender: nil) + } + } + else if(section == ExplorerSection.FeaturedVideos.rawValue) + { + cell.HeaderName.text = NSLocalizedString("Featured Upload", comment: "") + cell.seeMoreButton.setTitle(NSLocalizedString("More videos >", comment: ""), for: .normal) + cell.callBack = { + self.performSegue(withIdentifier: "featuredVideoSegue", sender: nil) + } + } + + return cell + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + 48 + } + + func numberOfSections(in tableView: UITableView) -> Int { + return ExplorerSection.Count.rawValue + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + var rowCount:Int = 0 + if(section == ExplorerSection.TrendingNow.rawValue) + { + if dm.trendingNow != nil + { + rowCount = explorerViewTableCount["trendingNow"]! + let availableData = dm.trendingNow!.tracks.count + if availableData < rowCount + { + rowCount = availableData + } + return rowCount + } + else + { + return 0 + } + } + if(section == ExplorerSection.DiscoverNew.rawValue) + { + return 1 // Discover New + } + if(section == ExplorerSection.LatestMusic.rawValue) + { + rowCount = explorerViewTableCount["latestMusic"]! + let availableData = DataManager.shared().latestUpload!.count + if availableData < rowCount + { + rowCount = availableData + } + return rowCount + } + if(section == ExplorerSection.FeaturedArtist.rawValue) + { + return explorerViewTableCount["featuredArtist"]! + } + if(section == ExplorerSection.FeaturedVideos.rawValue) + { + if(dm.featuredVideos != nil) + { + rowCount = explorerViewTableCount["featuredVideo"]! + let availableData = dm.featuredVideos!.videos.count + if availableData < rowCount + { + rowCount = availableData + } + return rowCount + } + return 0 + } + return rowCount + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if(indexPath.section == ExplorerSection.TrendingNow.rawValue) + { + let cell = mainTableView.dequeueReusableCell(withIdentifier: "trendingNowCell") as! TrendingNowCell + cell.mainTableView = mainTableView + cell.updateData(trackData:dm.trendingNow!.tracks[indexPath.row]) + /* + cell.trending = trendings[indexPath.row] + if trendings[indexPath.row].track != nil { + cell.trackTitleLabel.text = trendings[indexPath.row].track?.name + cell.artistNameLabel.text = trendings[indexPath.row].track?.email + if cell.player { + cell.playMusicButton.setImage(UIImage(systemName: "pause.fill"), for: .normal) + }else{ + cell.playMusicButton.setImage(UIImage(systemName: "play.fill"), for: .normal) + } + } + if trendings[indexPath.row].video != nil { + cell.trackTitleLabel.text = trendings[indexPath.row].video?.name + cell.artistNameLabel.text = trendings[indexPath.row].video?.email + // cell.musicImageView.imageView?.image = videoController.generateThumbnail(path: uploads[indexPath.row].video!.fileURL) + } + */ + return cell + } + if(indexPath.section == ExplorerSection.DiscoverNew.rawValue) + { + let cell = mainTableView.dequeueReusableCell(withIdentifier: "discoverNewCell") as! DiscoverNewCell + cell.callBack = { + self.performSegue(withIdentifier: "randomSpotlightSegue", sender: nil) + } + return cell + } + if(indexPath.section == ExplorerSection.LatestMusic.rawValue) + { + let cell = mainTableView.dequeueReusableCell(withIdentifier: "latestMusicCell") as! LatestMusicCell + let dt = dm.latestUpload![indexPath.row] + + cell.updateCellData(data:dt) + cell.mainTableView = mainTableView + return cell + } + if(indexPath.section == ExplorerSection.FeaturedArtist.rawValue) + { + let cell = mainTableView.dequeueReusableCell(withIdentifier: "featuredArtistCell") as! FeaturedArtistCell + cell.callBack = {userData in self.performSegue(withIdentifier: "artistPageSegue", sender: userData)} + // print("FeaturedArtist explorer:\(dm.featuredArtist!.users)") + cell.featuredArtistList = dm.featuredArtist?.users + cell.featuredArtistsCollectionCell.reloadData() + /* + var temp = [FeaturedDataStruct]() + for feature in features { + if feature.user != nil { + temp.append(feature) + } + } + cell.features = temp + */ + return cell + } + if(indexPath.section == ExplorerSection.FeaturedVideos.rawValue) + { + let cell = mainTableView.dequeueReusableCell(withIdentifier: "featuredVideosCell") as! FeaturedVideosCell + cell.mainTableView = mainTableView + cell.updateData(videoData:dm.featuredVideos!.videos[indexPath.row]) + /* + if features[indexPath.row].track != nil { + cell.feature = features[indexPath.row] + if cell.player { + cell.videoPlayButton.setImage(UIImage(systemName: "pause.fill"), for: .normal) + }else{ + cell.videoPlayButton.setImage(UIImage(systemName: "play.fill"), for: .normal) + } + } + */ + return cell + } + + return mainTableView.dequeueReusableCell(withIdentifier: "trendingNowCell")! + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if(indexPath.section == ExplorerSection.TrendingNow.rawValue) + { + return 88 + } + if(indexPath.section == ExplorerSection.DiscoverNew.rawValue) + { + return 80 + } + if(indexPath.section == ExplorerSection.FeaturedArtist.rawValue) + { + return 160 + } + if(indexPath.section == ExplorerSection.FeaturedVideos.rawValue) + { + return 160 + } + return 110 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + // selectRow = indexPath.row + // self.performSegue(withIdentifier: "uploadTest", sender: self) + if(indexPath.section == ExplorerSection.TrendingNow.rawValue) + { + selectedRow = indexPath.row + selectTrending = true + let cell = tableView.cellForRow(at: indexPath) as! TrendingNowCell + if(cell.trackData != nil) + { + // self.performSegue(withIdentifier: "trackPlayerSegue", sender: cell.trackData) + TrackManager.shared.play(trackData: cell.trackData!) + } + /* + if trendings[selectedRow].video != nil { + self.performSegue(withIdentifier: "videoPlayerSegue", sender: nil) + } + if trendings[selectedRow].track != nil { + + } + */ + } + if(indexPath.section == ExplorerSection.DiscoverNew.rawValue) + { + } + if(indexPath.section == ExplorerSection.LatestMusic.rawValue) + { + selectedRow = indexPath.row + selectUpload = true + if(dm.latestUpload![selectedRow].isVideo) + { + TrackManager.shared.playVideo(view: self, videoData: dm.featuredVideos!.videos[selectedRow]) + } + else + { + self.performSegue(withIdentifier: "trackPlayerSegue", sender: nil) + } + } + if(indexPath.section == ExplorerSection.FeaturedArtist.rawValue) + { + } + if(indexPath.section == ExplorerSection.FeaturedVideos.rawValue) + { + selectedRow = indexPath.row + selectFeatured = true + // if features[selectedRow].video != nil { + // self.performSegue(withIdentifier: "videoPlayerSegue", sender: nil) + // } + TrackManager.shared.playVideo(view: self, videoData: dm.featuredVideos!.videos[selectedRow]) + if features[selectedRow].track != nil + { + self.performSegue(withIdentifier: "trackPlayerSegue", sender: nil) + } + } + } + + func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return 25 + } + + + func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + let footerView = UIView() + let footerChildView = UIView(frame: CGRect(x: 60, y: 0, width: tableView.frame.width - 60, height: 0.5)) + // footerChildView.backgroundColor = UIColor.darkGray + footerView.addSubview(footerChildView) + return footerView + } + +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCell.swift b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCell.swift new file mode 100644 index 0000000..0013be3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCell.swift @@ -0,0 +1,66 @@ +// +// FeaturedArtistCell.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FeaturedArtistCell: UITableViewCell +{ + + @IBOutlet weak var featuredArtistsCollectionCell: UICollectionView! + var callBack: ((UserDataStruct) -> Void)? = nil + + var featuredArtistList: [UserDataStruct]? = [] + + override func awakeFromNib() { + super.awakeFromNib() + + self.featuredArtistsCollectionCell.dataSource = self + self.featuredArtistsCollectionCell.delegate = self + self.featuredArtistsCollectionCell.register(UINib.init(nibName: "FeaturedArtistCollectionCell", bundle: nil), forCellWithReuseIdentifier: "artistCollectionViewCell") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } +} + +extension FeaturedArtistCell : UICollectionViewDelegate, UICollectionViewDataSource +{ + + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + print("FeaturedArtist Total: \(featuredArtistList?.count)") + if featuredArtistList != nil { + return featuredArtistList!.count + } + return 0 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = featuredArtistsCollectionCell.dequeueReusableCell(withReuseIdentifier: "artistCollectionViewCell", + for: indexPath as IndexPath) as! FeaturedArtistCollectionCell + cell.updateData(userData: featuredArtistList![indexPath.row]) + + /* + if let data = NSData(contentsOf: featuredArtistList![indexPath.row].fileURL!) + { + DispatchQueue.main.async { + cell.artistImageView.image = UIImage(data: data as Data) + } + } + */ + + return cell + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + callBack!(featuredArtistList![indexPath.row]) + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCell.xib b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCell.xib new file mode 100644 index 0000000..9d412d8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCell.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCollectionCell.swift b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCollectionCell.swift new file mode 100644 index 0000000..759f751 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCollectionCell.swift @@ -0,0 +1,28 @@ +// +// FeaturedArtistCollectionCell.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FeaturedArtistCollectionCell: UICollectionViewCell { + + @IBOutlet weak var artistImageView: UIImageView! + var callBack: (() -> Void)? = nil + @IBOutlet weak var name: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + func updateData(userData:UserDataStruct) + { + artistImageView.image = userData.profilePicture + name.text = userData.name + } + +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCollectionCell.xib b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCollectionCell.xib new file mode 100644 index 0000000..caf2086 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistCollectionCell.xib @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistVC.swift b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistVC.swift new file mode 100644 index 0000000..6cd766d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistVC.swift @@ -0,0 +1,55 @@ +// +// FeaturedArtistVC.swift +// CommunityMC3 +// +// Created by Theofani on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FeaturedArtistVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { + + + + @IBOutlet weak var featuredArtistCollectionView: UICollectionView! + var features: FeaturedDataStruct? + + override func viewDidLoad() { + super.viewDidLoad() + self.featuredArtistCollectionView.register(UINib.init(nibName: "FeaturedArtistCollectionCell", bundle: nil), forCellWithReuseIdentifier: "artistCollectionViewCell") + + let layout = UICollectionViewFlowLayout() + layout.itemSize = CGSize(width: 180, height: 180) + featuredArtistCollectionView.collectionViewLayout = layout + + } + + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + navigationController?.navigationBar.backItem?.title = "" + + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + if features != nil { + return features!.users.count + } + return 0 + } + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + + let cell = featuredArtistCollectionView.dequeueReusableCell(withReuseIdentifier: "artistCollectionViewCell", for: indexPath as IndexPath) as! FeaturedArtistCollectionCell + cell.updateData(userData: features!.users[indexPath.row]) + return cell + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: 180, height: 180) + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + performSegue(withIdentifier: "artistPageSegue", sender: nil) + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistView.storyboard b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistView.storyboard new file mode 100644 index 0000000..b5b06f8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Artists/FeaturedArtistView.storyboard @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosCell.swift b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosCell.swift new file mode 100644 index 0000000..17963c3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosCell.swift @@ -0,0 +1,70 @@ +// +// FeaturedVideosCell.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVFoundation + +class FeaturedVideosCell: UITableViewCell { + + @IBOutlet weak var videoThumbnailImage: UIImageView! + @IBOutlet weak var videoPlayButton: UIButton! + +// var feature: FeaturedDataStruct! + var player: Bool = false + var audioPlayer: AVAudioPlayer! + var mainTableView: UITableView! + var videoData:VideosDataStruct? + + override func awakeFromNib() { + super.awakeFromNib() + videoThumbnailImage.layer.cornerRadius = 10 + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + func updateData(videoData:VideosDataStruct) + { + self.videoData = videoData + videoThumbnailImage.image = videoData.coverImage + if player { + videoPlayButton.setImage(UIImage(systemName: "pause.fill"), for: .normal) + }else{ + videoPlayButton.setImage(UIImage(systemName: "play.fill"), for: .normal) + } + } + + @IBAction func playUpload(_ sender: UIButton) { + /* + if feature != nil { + player = true + mainTableView.reloadData() + DispatchQueue.main.async { + do { + self.audioPlayer = try AVAudioPlayer(contentsOf: (self.feature.track!.fileData?.fileURL!)!) + self.audioPlayer.delegate = self + self.audioPlayer.play() + } catch { + print("play failed") + } + } + } + */ + } + +} + +extension FeaturedVideosCell: AVAudioPlayerDelegate { + func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { + self.player = false + mainTableView.reloadData() + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosCell.xib b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosCell.xib new file mode 100644 index 0000000..19078e9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosCell.xib @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosVC.swift b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosVC.swift new file mode 100644 index 0000000..453a86d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosVC.swift @@ -0,0 +1,80 @@ +// +// FeaturedVideosVC.swift +// CommunityMC3 +// +// Created by Theofani on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FeaturedVideosVC: UIViewController { + + + var features: FeaturedDataStruct? = nil + var selectedRow = 0 + var mainTableView: UITableView! + + @IBOutlet weak var featuredVideoTableView: UITableView! + override func viewDidLoad() { + super.viewDidLoad() + featuredVideoTableView.register(UINib(nibName: "FeaturedVideosCell", bundle: nil), forCellReuseIdentifier: "featuredVideosCell") + } + + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + navigationController?.navigationBar.backItem?.title = "" + + } + + // MARK: Storyboard + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "trackPlayerSegue" { + if let trackPlayerPage = segue.destination as? TrackPlayerViewController { +// trackPlayerPage.track = features[selectedRow].track + } + } + if segue.identifier == "videoPlayerSegue" { + if let videoPlayerPage = segue.destination as? VideoPlayerViewController { +// videoPlayerPage.video = features[selectedRow].video + } + } + } +} + +extension FeaturedVideosVC: UITableViewDelegate, UITableViewDataSource +{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if features != nil { + return features!.videos.count + } + // return 10 + return 0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = featuredVideoTableView.dequeueReusableCell(withIdentifier: "featuredVideosCell") as! FeaturedVideosCell + cell.updateData(videoData: features!.videos[indexPath.row]) + + return cell + } + + override func viewWillDisappear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(true, animated: false) + super .viewWillDisappear(animated) + } + + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 200 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + selectedRow = indexPath.row +// if features[selectedRow].video != nil { +// self.performSegue(withIdentifier: "videoPlayerSegue", sender: nil) +// } + TrackManager.shared.playVideo(view: self, videoData: features!.videos[indexPath.row]) + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosView.storyboard b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosView.storyboard new file mode 100644 index 0000000..a02dc15 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Featured Videos/FeaturedVideosView.storyboard @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 2.swift b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 2.swift new file mode 100644 index 0000000..cb68993 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 2.swift @@ -0,0 +1,26 @@ +// +// HeaderCell.swift +// CommunityMC3 +// +// Created by Bernardinus on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class HeaderCell: UITableViewCell { + + @IBOutlet weak var HeaderName: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 2.xib b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 2.xib new file mode 100644 index 0000000..7458dd8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 2.xib @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 3.swift b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 3.swift new file mode 100644 index 0000000..cb68993 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 3.swift @@ -0,0 +1,26 @@ +// +// HeaderCell.swift +// CommunityMC3 +// +// Created by Bernardinus on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class HeaderCell: UITableViewCell { + + @IBOutlet weak var HeaderName: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 3.xib b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 3.xib new file mode 100644 index 0000000..7458dd8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell 3.xib @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/HeaderCell.swift b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell.swift new file mode 100644 index 0000000..252cf6c --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell.swift @@ -0,0 +1,38 @@ +// +// HeaderCell.swift +// CommunityMC3 +// +// Created by Bernardinus on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class HeaderCell: UITableViewCell { + + @IBOutlet weak var headerBackgroundView: UIView! + @IBOutlet weak var HeaderName: UILabel! + @IBOutlet weak var seeMoreButton: UIButton! + @IBOutlet weak var sectionBlock: UIView! + + var callBack: (() -> Void)? = nil + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + @IBAction func tapSeeMore(_ sender: Any) { + self.callBack!() + } + + func setCallBack(callback: (() -> Void)?){ + self.callBack = callback + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/HeaderCell.xib b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell.xib new file mode 100644 index 0000000..d8319d5 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/HeaderCell.xib @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicCell.swift b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicCell.swift new file mode 100644 index 0000000..6aa171c --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicCell.swift @@ -0,0 +1,117 @@ +// +// LatestMusicCell.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVFoundation + +class LatestMusicCell: UITableViewCell { + + @IBOutlet weak var playMusicButton: UIButton! + @IBOutlet weak var trackTitleLabel: UILabel! + @IBOutlet weak var artistNameLabel: UILabel! + @IBOutlet weak var musicImageView: UIImageView! +// @IBOutlet weak var genreLabel: UILabel! +// @IBOutlet weak var indicatorImage: UIImageView! + + let musicImg:UIImage = UIImage(systemName: "music.note")! + let videoImg:UIImage = UIImage(systemName: "play.rectangle.fill")! + + var upload: UploadedDataStruct! + var player: Bool = false + var audioPlayer: AVAudioPlayer! + var mainTableView: UITableView! + var dt:UploadedDataStruct? + // let documentController = DocumentTableViewController.shared + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + func updateCellData(data:UploadedDataStruct) + { + upload = dt + self.dt = data + if(dt!.isVideo) + { + print("uploadedVideo \(dt?.videoRecord)") + trackTitleLabel.text = dt?.videoData?.name + artistNameLabel.text = dt?.videoData?.artistName + musicImageView.image = dt?.videoData?.coverImage + + } + else + { +// print("uploadedTrack \(dt?.trackRecord)") + trackTitleLabel.text = dt?.trackData?.name + artistNameLabel.text = dt?.trackData?.artistName + musicImageView.image = dt?.trackData?.coverImage +// print("masuk ", player) + if player + { + playMusicButton.imageView?.image = UIImage(systemName: "pause.fill") + playMusicButton.setImage(UIImage(systemName: "pause.fill"), for: .normal) + } + else + { + playMusicButton.imageView?.image = UIImage(systemName: "play.fill") + playMusicButton.setImage(UIImage(systemName: "play.fill"), for: .normal) + } + + } + + } + + @IBAction func directPlay(_ sender: UIButton) { + if upload.trackRecord != nil { + +// setupUIViewForGenre(view: genreLabel, genre: "RnB") +// indicatorImage.image = musicImg + + player = true + mainTableView.reloadData() + // playMusicButton.imageView?.image = UIImage(systemName: "pause.fill") + // let playerGroup = DispatchGroup() + // playerGroup.enter() + DispatchQueue.main.async { + do { +// self.audioPlayer = try AVAudioPlayer(contentsOf: self.upload.track!.fileURL) + self.audioPlayer.delegate = self + self.audioPlayer.play() + // playerGroup.leave() + } + catch + { + print("play failed") + } + } + // playerGroup.notify(queue: .main) { + // } + // if player { + // player = false + // }else{ + // player = true + // } + } + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} + +extension LatestMusicCell: AVAudioPlayerDelegate { + func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { + // playMusicButton.imageView?.image = UIImage(systemName: "play.fill") + self.player = false + mainTableView.reloadData() + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicCell.xib b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicCell.xib new file mode 100644 index 0000000..6b2e0ad --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicCell.xib @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicVC.swift b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicVC.swift new file mode 100644 index 0000000..fd261a9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicVC.swift @@ -0,0 +1,78 @@ +// +// LatestMusicVC.swift +// CommunityMC3 +// +// Created by Theofani on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class LatestMusicVC: UIViewController { + + @IBOutlet weak var latestMusicTableView: UITableView! + + var uploads: [UploadedDataStruct]! + var selectedRow = 0 + var mainTableView: UITableView! + + override func viewDidLoad() { + super.viewDidLoad() + latestMusicTableView.register(UINib(nibName: "LatestMusicCell", bundle: nil), forCellReuseIdentifier: "latestMusicCell") + + } + + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + navigationController?.navigationBar.backItem?.title = "" + } + + // MARK: Storyboard + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "trackPlayerSegue" { + if let trackPlayerPage = segue.destination as? TrackPlayerViewController { + trackPlayerPage.track = uploads[selectedRow].trackData + } + } + if segue.identifier == "videoPlayerSegue" { + if let videoPlayerPage = segue.destination as? VideoPlayerViewController { + videoPlayerPage.video = uploads[selectedRow].videoData + } + } + } + +} + +extension LatestMusicVC: UITableViewDelegate, UITableViewDataSource +{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if uploads != nil { + return uploads.count + } + return 0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = latestMusicTableView.dequeueReusableCell(withIdentifier: "latestMusicCell") as! LatestMusicCell + cell.mainTableView = mainTableView + cell.updateCellData(data: uploads[indexPath.row]) + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 110 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + selectedRow = indexPath.row + if(uploads[selectedRow].isVideo) + { + self.performSegue(withIdentifier: "videoPlayerSegue", sender: nil) + } + else + { + self.performSegue(withIdentifier: "trackPlayerSegue", sender: nil) + } + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicView.storyboard b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicView.storyboard new file mode 100644 index 0000000..85720e6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Latest Music/LatestMusicView.storyboard @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowCell.swift b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowCell.swift new file mode 100644 index 0000000..1476bff --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowCell.swift @@ -0,0 +1,188 @@ +// +// TrendingNowCell.swift +// CommunityMC3 +// +// Created by Bernardinus on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVFoundation + +class TrendingNowCell: UITableViewCell { + + @IBOutlet weak var trackTitleLabel: UILabel! + @IBOutlet weak var artistNameLabel: UILabel! + @IBOutlet weak var musicImageView: UIImageView! + @IBOutlet weak var favoriteIconButton: UIButton! + @IBOutlet weak var trackTimerLabel: UILabel! + @IBOutlet weak var playMusicButton: UIButton! + + var trackData:TrackDataStruct? + + var player: Bool = false + var audioPlayer: AVAudioPlayer! + var mainTableView: UITableView! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + favoriteButtonStateChange() + retreiveFavorites() + } + + func updateData(trackData:TrackDataStruct) + { + self.trackData = trackData + trackTitleLabel.text = trackData.name + artistNameLabel.text = trackData.artistName + musicImageView.image = trackData.coverImage + if player { + playMusicButton.setImage(UIImage(systemName: "pause.fill"), for: .normal) + }else{ + playMusicButton.setImage(UIImage(systemName: "play.fill"), for: .normal) + } + trackTimerLabel.text = trackData.duration + + var isFavouriteMusic = DataManager.shared().currentUser?.isFavMusic(recName:(trackData.record?.recordID.recordName)!) + favoriteIconButton.isSelected = isFavouriteMusic! + + } + + func favoriteButtonStateChange() + { + + favoriteIconButton.setImage(#imageLiteral(resourceName: "HeartUnfill"), for: .normal) + favoriteIconButton.setImage(#imageLiteral(resourceName: "HeartFill"), for: .selected) + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + @IBAction func playTrending(_ sender: UIButton) { + /* + if trackData != nil { + player = true + /* + mainTableView.reloadData() + DispatchQueue.main.async { + do { + self.audioPlayer = try AVAudioPlayer(contentsOf: (self.trackData!.fileData?.fileURL!)!) + self.audioPlayer.delegate = self + self.audioPlayer.play() + } catch { + print("play failed") + } + }*/ + TrackManager.shared.play(trackData: trackData!) + mainTableView.reloadData() + } + */ + } + + @IBAction func favoriteUpload(_ sender: UIButton) { + favoriteIconButton.isSelected = !favoriteIconButton.isSelected + if favoriteIconButton.isSelected + { + DataManager.shared().AddFavourites(favType: .Track, recordName: trackData!.record!.recordID.recordName) + } + else + { + DataManager.shared().RemoveFavourites(favType: .Track, recordName: trackData!.record!.recordID.recordName) + } + changeFavourites() + // print(favoriteBool) + } + + func changeFavourites() { + /* + if trending.track != nil { + let temp = PrimitiveTrackDataStruct( + genre: trending.track!.genre, + name: trending.track!.name, + email: trending.track!.email + ) + var counter = 0 + var flag = false + for trending in trendings { + if trending.name == self.trending.track!.name { + flag = true + trendings.remove(at: counter) + } + counter += 1 + } + if !flag { + trendings.append(temp) + } + + documentController.uploadFavorite(id: email, track: trendings) + } + if trending.video != nil { + let temp = PrimitiveVideosDataStruct( + genre: trending.video!.genre, + name: trending.video!.name, + email: trending.video!.email + ) + var counter = 0 + var flag = false + for video in videos { + if video.name == self.trending.video!.name { + flag = true + videos.remove(at: counter) + } + counter += 1 + } + if !flag { + videos.append(temp) + } + + uploadController.uploadFavorite(id: email, video: videos) + } + */ + } + + func retreiveFavorites() { + /* + documentController.getFavoritesFromCloudKit { (favourites) in + for favourite in favourites { + if self.email != "" && favourite.id == self.email { + self.trendings = favourite.track! + self.videos = favourite.videos! + } + } + // print("current", self.trendings.count) + if self.trending.track != nil { + for trending in self.trendings { + if trending.name == self.trending.track!.name { + DispatchQueue.main.async { + self.favoriteIconButton.isSelected = !self.favoriteIconButton.isSelected + } + } + } + } + if self.trending.video != nil { + /* + for video in self.videos { + if video.name == self.trending.video!.name { + DispatchQueue.main.async { + self.favoriteIconButton.isSelected = !self.favoriteIconButton.isSelected + } + } + } + */ + } + } + */ + } + + +} + +extension TrendingNowCell: AVAudioPlayerDelegate { + func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { + self.player = false + mainTableView.reloadData() + } +} diff --git a/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowCell.xib b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowCell.xib new file mode 100644 index 0000000..faf40b3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowCell.xib @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowList.storyboard b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowList.storyboard new file mode 100644 index 0000000..4ad63c2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowList.storyboard @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowVC.swift b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowVC.swift new file mode 100644 index 0000000..ec25b2a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Explorer View/Trending Now/TrendingNowVC.swift @@ -0,0 +1,89 @@ +// +// TrendingNowVC.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class TrendingNowVC: UIViewController { + + @IBOutlet weak var trendingTableView: UITableView! + + var trendings: FeaturedDataStruct! + var selectedRow = 0 + var mainTableView: UITableView! + + override func viewDidLoad() { + super.viewDidLoad() + trendingTableView.register(UINib(nibName: "TrendingNowCell", bundle:nil), forCellReuseIdentifier: "trendingNowCell") + + trendings = DataManager.shared().trendingNow! + } + + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + navigationController?.navigationBar.backItem?.title = "" + } + + // MARK: Storyboard + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "trackPlayerSegue" { + if let trackPlayerPage = segue.destination as? TrackPlayerViewController { + trackPlayerPage.track = sender as? TrackDataStruct + } + } + if segue.identifier == "videoPlayerSegue" { + if let videoPlayerPage = segue.destination as? VideoPlayerViewController { + videoPlayerPage.video = sender as? VideosDataStruct + } + } + } + +} + +extension TrendingNowVC: UITableViewDelegate, UITableViewDataSource +{ + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if trendings != nil { + return trendings.tracks.count + } + return 0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = trendingTableView.dequeueReusableCell(withIdentifier: "trendingNowCell") as! TrendingNowCell + cell.mainTableView = mainTableView + cell.updateData(trackData: trendings.tracks[indexPath.row]) + /* + cell.trending = trendings[indexPath.row] + if trendings[indexPath.row].track != nil { + cell.trackTitleLabel.text = trendings[indexPath.row].track?.name + cell.artistNameLabel.text = trendings[indexPath.row].track?.email + if cell.player { + cell.playMusicButton.setImage(UIImage(systemName: "pause.fill"), for: .normal) + }else{ + cell.playMusicButton.setImage(UIImage(systemName: "play.fill"), for: .normal) + } + } + if trendings[indexPath.row].video != nil { + cell.trackTitleLabel.text = trendings[indexPath.row].video?.name + cell.artistNameLabel.text = trendings[indexPath.row].video?.email + // cell.musicImageView.imageView?.image = videoController.generateThumbnail(path: uploads[indexPath.row].video!.fileURL) + } + */ + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + performSegue(withIdentifier: "trackPlayerSegue", sender: trendings.tracks[indexPath.row]) + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 88 + } +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoriteMenuCell/FavoritesMenuCell.swift b/frontend/mobile/CommunityMC3/Favourites View/FavoriteMenuCell/FavoritesMenuCell.swift new file mode 100644 index 0000000..c242e7d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoriteMenuCell/FavoritesMenuCell.swift @@ -0,0 +1,27 @@ +// +// FavoritesMenuCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FavoritesMenuCell: UITableViewCell { + + @IBOutlet weak var cellTitleLabel: UILabel! + @IBOutlet weak var countLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoriteMenuCell/FavoritesMenuCell.xib b/frontend/mobile/CommunityMC3/Favourites View/FavoriteMenuCell/FavoritesMenuCell.xib new file mode 100644 index 0000000..1a8f79e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoriteMenuCell/FavoritesMenuCell.xib @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteAlbumsCell.swift b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteAlbumsCell.swift new file mode 100644 index 0000000..d9e8a20 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteAlbumsCell.swift @@ -0,0 +1,24 @@ +// +// FavoriteAlbumsCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FavoriteAlbumsCell: UICollectionViewCell { + + @IBOutlet weak var albumCoverImage: UIImageView! + @IBOutlet weak var albumTitleButton: UIButton! + @IBOutlet weak var artistButton: UIButton! + @IBOutlet weak var albumButton: UIButton! + + + override func awakeFromNib() { + super.awakeFromNib() + + } + +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteAlbumsCell.xib b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteAlbumsCell.xib new file mode 100644 index 0000000..020e76b --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteAlbumsCell.xib @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteArtistsCell.swift b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteArtistsCell.swift new file mode 100644 index 0000000..509dd86 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteArtistsCell.swift @@ -0,0 +1,32 @@ +// +// FavoriteArtistsCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FavoriteArtistsCell: UICollectionViewCell { + + @IBOutlet weak var artistImage: UIImageView! + @IBOutlet weak var artistName: UIButton! + @IBOutlet weak var artistImageButton: UIButton! + + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + artistName.isUserInteractionEnabled = false + artistImageButton.isUserInteractionEnabled = false + + } + + func updateData(data:UserDataStruct) + { + artistImage.image = data.profilePicture + artistName.titleLabel?.text = data.name + + } +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteArtistsCell.xib b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteArtistsCell.xib new file mode 100644 index 0000000..5f20294 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteArtistsCell.xib @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteTracksCell.swift b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteTracksCell.swift new file mode 100644 index 0000000..f599528 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteTracksCell.swift @@ -0,0 +1,56 @@ +// +// FavoriteTracksCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FavoriteTracksCell: UITableViewCell { + + @IBOutlet weak var trackCoverImage: UIImageView! + @IBOutlet weak var playButton: UIButton! + @IBOutlet weak var trackTitleLabel: UILabel! + @IBOutlet weak var artistLabel: UILabel! + @IBOutlet weak var favoriteButton: UIButton! + @IBOutlet weak var trackDurationLabel: UILabel! + + var trackData:TrackDataStruct? = nil + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + favoriteButton.isSelected = true + setupButtonImage() + } + + func setupButtonImage() + { + playButton.setImage(#imageLiteral(resourceName: "playButtonFavorites"), for: .normal) + playButton.setImage(#imageLiteral(resourceName: "StopButtonFavorite"), for: .selected) + + favoriteButton.setImage(#imageLiteral(resourceName: "HeartUnfill"), for: .normal) + favoriteButton.setImage(#imageLiteral(resourceName: "HeartFill"), for: .selected) + } + + func updateData(td:TrackDataStruct) + { + trackData = td + trackCoverImage.image = trackData?.coverImage + trackTitleLabel.text = trackData?.name + artistLabel.text = trackData?.artistName + trackDurationLabel.text = trackData?.duration + + + } + + + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + } + +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteTracksCell.xib b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteTracksCell.xib new file mode 100644 index 0000000..0c83d66 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteTracksCell.xib @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteVideosCell.swift b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteVideosCell.swift new file mode 100644 index 0000000..916f64f --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteVideosCell.swift @@ -0,0 +1,51 @@ +// +// FavoriteVideosCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FavoriteVideosCell: UITableViewCell { + + @IBOutlet weak var playButton: UIButton! + @IBOutlet weak var videoThumbnailImage: UIImageView! + @IBOutlet weak var favoriteButton: UIButton! + + var videoData:VideosDataStruct? = nil + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + favoriteButton.isSelected = true + setupButtonImage() + } + + func setupButtonImage() + { + playButton.setImage(#imageLiteral(resourceName: "playButtonFavorites"), for: .normal) + playButton.setImage(#imageLiteral(resourceName: "StopButtonFavorite"), for: .selected) + + favoriteButton.setImage(#imageLiteral(resourceName: "HeartUnfill"), for: .normal) + favoriteButton.setImage(#imageLiteral(resourceName: "HeartFill"), for: .selected) + + videoThumbnailImage.layer.borderWidth = 0 + } + + func updateData(vd:VideosDataStruct) + { + videoData = vd + videoThumbnailImage.image = videoData?.coverImage + videoThumbnailImage.layer.borderWidth = 2 + } + + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteVideosCell.xib b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteVideosCell.xib new file mode 100644 index 0000000..4b4c4f8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/FavoritesDetailCell/FavoriteVideosCell.xib @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteAlbums.storyboard b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteAlbums.storyboard new file mode 100644 index 0000000..1eee4fa --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteAlbums.storyboard @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteArtist.storyboard b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteArtist.storyboard new file mode 100644 index 0000000..8637d8d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteArtist.storyboard @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteTracksView.storyboard b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteTracksView.storyboard new file mode 100644 index 0000000..716cca2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoriteTracksView.storyboard @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoritesVideo.storyboard b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoritesVideo.storyboard new file mode 100644 index 0000000..406e6a6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/FavoritesVideo.storyboard @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/Storyboards/Favourites.storyboard b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/Favourites.storyboard new file mode 100644 index 0000000..56133d7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/Storyboards/Favourites.storyboard @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteAlbumsView.swift b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteAlbumsView.swift new file mode 100644 index 0000000..0398a03 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteAlbumsView.swift @@ -0,0 +1,41 @@ +// +// FavoriteAlbumsView.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FavoriteAlbumsView: UIViewController { + + @IBOutlet weak var collectionView: UICollectionView! + + override func viewDidLoad() { + super.viewDidLoad() + + collectionView.register(UINib(nibName: "FavoriteAlbumsCell", bundle: nil), forCellWithReuseIdentifier: "favoriteAlbumsCell") + } + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + navigationController?.navigationBar.backItem?.title = "" + } + +} + +extension FavoriteAlbumsView: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 6 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "favoriteAlbumsCell", for: indexPath) as! FavoriteAlbumsCell + cell.albumCoverImage.layer.cornerRadius = 4 + cell.albumCoverImage.image = #imageLiteral(resourceName: "photos-dummy") + + return cell + } + +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteArtistsView.swift b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteArtistsView.swift new file mode 100644 index 0000000..f9dda13 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteArtistsView.swift @@ -0,0 +1,53 @@ +// +// FavoriteArtistsView.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class FavoriteArtistsView: UIViewController { + + @IBOutlet weak var collectionView: UICollectionView! + + var artistData:[UserDataStruct]? = nil + + override func viewDidLoad() { + super.viewDidLoad() + + collectionView.register(UINib(nibName: "FavoriteArtistsCell", bundle: nil), forCellWithReuseIdentifier: "favoriteArtistsCell") + artistData = DataManager.shared().favArtistData + } + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + navigationController?.navigationBar.backItem?.title = "" + } + + +} + +extension FavoriteArtistsView: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + if artistData != nil + { + return artistData!.count + } + return 0 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "favoriteArtistsCell", for: indexPath) as! FavoriteArtistsCell + cell.updateData(data: artistData![indexPath.row]) + cell.artistImage.image = #imageLiteral(resourceName: "artist-4") + + return cell + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + performSegue(withIdentifier: "artistProfileSegue", sender: nil) + } + +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteTracksView.swift b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteTracksView.swift new file mode 100644 index 0000000..ae2222a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteTracksView.swift @@ -0,0 +1,185 @@ +// +// FavoritesDetailView.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVFoundation +import AVKit + +class FavoriteTracksView: UIViewController, AVAudioPlayerDelegate { + + @IBOutlet weak var tableView: UITableView! + + var countTracks: [TrackDataStruct]! + var countFavorites = [PrimitiveTrackDataStruct]() + let documentController = DocumentTableViewController.shared + + var trackPlayer: AVAudioPlayer? + var playerTemp: AVAudioPlayer? + var timer: Timer? = nil + var seconds = 0 + var tempIndex = 0 + + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: true) + super.viewWillAppear(animated) + } + + override func viewDidLoad() { + super.viewDidLoad() + + tableView.register(UINib(nibName: "FavoriteTracksCell", bundle: nil), forCellReuseIdentifier: "favoriteTracksCell") + countTracks = DataManager.shared().favTrackData + // convertFavourites() + } + /* + func convertFavourites() { + for track in countTracks { + countFavorites.append( + PrimitiveTrackDataStruct( + genre: track.genre, + name: track.name, + email: track.email + ) + ) + } + } + */ + + func changeFavourites(track: TrackDataStruct) { + let temp = PrimitiveTrackDataStruct( + genre: track.genre, + name: track.name, + email: track.email + ) + var counter = 0 + var flag = false + for track in countFavorites { + if track.name == temp.name { + flag = true + countFavorites.remove(at: counter) + } + counter += 1 + } + if !flag { + countFavorites.append(temp) + } + let email = UserDefaults.standard.string(forKey: "email") + + documentController.uploadFavorite(id: email!, track: countFavorites) + } + + @objc func directPlay(_ sender: UIButton){ + /* + sender.isSelected = !sender.isSelected + let selectedIndex = IndexPath(row: sender.tag, section: 0) + + tempIndex = sender.tag + + var error : NSError? = nil + if countTracks != nil { + let audioPath = countTracks![tempIndex].fileData!.fileURL! + do { + trackPlayer = try AVAudioPlayer(contentsOf: audioPath) + + } catch let error1 as NSError { + error = error1 + } + }else { + let audioPath = Bundle.main.path(forResource: "", ofType: "mp3")! + do { + trackPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath)) + + } catch let error1 as NSError { + error = error1 + } + } + + trackPlayer!.delegate = self + timer?.invalidate() + + if sender.isSelected == true { + if error == nil { + trackPlayer?.delegate = self + trackPlayer?.prepareToPlay() + trackPlayer?.play() + } + let cell = tableView.cellForRow(at: selectedIndex) as! FavoriteTracksCell + seconds = Int(trackPlayer!.duration) + timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {_ in + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute, .second] + formatter.unitsStyle = .positional + + let formattedString = formatter.string(from: TimeInterval(self.seconds))! + self.seconds -= 1 + cell.trackDurationLabel.text = "\(formattedString)" + } + }else if sender.isSelected == false{ + trackPlayer?.stop() + timer!.invalidate() + } + tableView.reloadData() + */ + } + + @objc func favoriteButtonState(_ sender: UIButton){ + /* + sender.isSelected = !sender.isSelected + let selectedIndex = IndexPath(row: sender.tag, section: 0) + + changeFavourites(track: countTracks[sender.tag]) + + if sender.isSelected == false{ + let cell = tableView.cellForRow(at: selectedIndex) as! FavoriteTracksCell + + cell.favoriteButton.setImage(#imageLiteral(resourceName: "HeartUnfill"), for: .normal) + + self.tableView.reloadData() + } + */ + } + +} + +extension FavoriteTracksView: UITableViewDelegate, UITableViewDataSource{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if countTracks != nil { + return countTracks.count + } + return 0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "favoriteTracksCell", for: indexPath) as! FavoriteTracksCell + cell.updateData(td: countTracks[indexPath.row]) + + cell.playButton.tag = indexPath.row + cell.favoriteButton.tag = indexPath.row + + cell.playButton.addTarget(self, action: #selector(directPlay(_:)), for: .touchUpInside) + + cell.favoriteButton.addTarget(self, action: #selector(favoriteButtonState(_:)), for: .touchUpInside) + + + if indexPath.row == tempIndex{ + + }else{ + cell.playButton.isSelected = false + } + + return cell + } + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 90 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { +// performSegue(withIdentifier: "toTrackPlayer", sender: self) + TrackManager.shared.play(trackData: countTracks[indexPath.row]) + } +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteVideosView.swift b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteVideosView.swift new file mode 100644 index 0000000..79e1ead --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavoriteVideosView.swift @@ -0,0 +1,146 @@ +// +// FavoriteVideosView.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVKit + +class FavoriteVideosView: UIViewController { + + @IBOutlet weak var tableView: UITableView! + + var countVideos: [VideosDataStruct]! + var countFavorites = [PrimitiveVideosDataStruct]() + let uploadController = UploadController.shared + + var videoPlayer: AVPlayer? + + override func viewDidLoad() { + super.viewDidLoad() + + tableView.register(UINib(nibName: "FavoriteVideosCell", bundle: nil), forCellReuseIdentifier: "favoriteVideosCell") + // convertFavourites() + countVideos = DataManager.shared().favVideoData + } + + func convertFavourites() { + for video in countVideos { + countFavorites.append( + PrimitiveVideosDataStruct( + genre: video.genre, + name: video.name, + email: video.email + ) + ) + } + } + + func changeFavourites(video: VideosDataStruct) { + let temp = PrimitiveVideosDataStruct( + genre: video.genre, + name: video.name, + email: video.email + ) + var counter = 0 + var flag = false + for video in countFavorites { + if video.name == temp.name { + flag = true + countFavorites.remove(at: counter) + } + counter += 1 + } + if !flag { + countFavorites.append(temp) + } + let email = UserDefaults.standard.string(forKey: "email") + + uploadController.uploadFavorite(id: email!, video: countFavorites) + } + + @objc func clickPlayVideo(_ sender: UIButton){ + /* + let video: AVPlayer + if countVideos != nil { + let videoURL = countVideos[sender.tag].fileData!.fileURL! + let videoData = NSData(contentsOf: videoURL as URL) + + let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + let destinationPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent(countVideos[sender.tag].name + ".mov", isDirectory: false) //This is where I messed up. + + FileManager.default.createFile(atPath: (destinationPath?.path)!, contents:videoData as Data?, attributes:nil) + + video = AVPlayer(url: destinationPath!) + + }else { + if let urlString = Bundle.main.path(forResource: "", ofType: "mp4"){ + video = AVPlayer(url: URL(fileURLWithPath: urlString)) + }else{ + video = AVPlayer() + } + } + let videoPlayer = AVPlayerViewController() + videoPlayer.player = video + + //enter video player mode + self.present(videoPlayer, animated: true, completion: { + video.play() + }) + */ + } + + @objc func favoriteButtonState(_ sender: UIButton){ + /* + sender.isSelected = !sender.isSelected + let selectedIndex = IndexPath(row: sender.tag, section: 0) + + changeFavourites(video: countVideos[sender.tag]) + + if sender.isSelected == false{ + let cell = tableView.cellForRow(at: selectedIndex) as! FavoriteVideosCell + + cell.favoriteButton.setImage(#imageLiteral(resourceName: "HeartUnfill"), for: .normal) + + self.tableView.reloadData() + } + */ + } + + +} + + +extension FavoriteVideosView: UITableViewDelegate, UITableViewDataSource{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if countVideos != nil { + return countVideos.count + } + return 5//0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "favoriteVideosCell", for: indexPath) as! FavoriteVideosCell + + cell.favoriteButton.tag = indexPath.row + cell.favoriteButton.addTarget(self, action: #selector(favoriteButtonState(_:)), for: .touchUpInside) + +// let videoUrl = Bundle.main.path(forResource: " ", ofType: "mp4") +// let urls = URL(fileURLWithPath: videoUrl!) + + cell.playButton.tag = indexPath.row + cell.playButton.addTarget(self, action: #selector(clickPlayVideo(_:)), for: .touchUpInside) + + return cell + } + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 150 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + TrackManager.shared.playVideo(view: self, videoData: countVideos[indexPath.row]) + } +} diff --git a/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavouritesView.swift b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavouritesView.swift new file mode 100644 index 0000000..478f2b1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Favourites View/ViewControllers/FavouritesView.swift @@ -0,0 +1,203 @@ +// +// ThirdViewController.swift +// CommunityMC3 +// +// Created by Bryanza on 06/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import CloudKit + +enum Favorite: Int{ + case FavoriteTrack = 0 + case FavoriteVideo = 1 + case Albums = 2 + case Artist = 3 + + case Count = 4 +} + +class FavouritesView: UIViewController { + + @IBOutlet weak var tableView: UITableView! + + let documentController = DocumentTableViewController.shared + var countTracks = [TrackDataStruct]() + var countVideos = [VideosDataStruct]() + var uploads: [CKRecord]! + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + tableView.register(UINib(nibName: "FavoritesMenuCell", bundle: nil), forCellReuseIdentifier: "favoriteMenuCell") + // retrieveFavorite() + // retrieveUpload() + } + + func retrieveUpload() + { + /* + if uploads != nil { + for upload in uploads { + let track = upload.value(forKey: "track") as! CKRecord + var counter = 0 + for countTrack in countTracks { + if track.value(forKey: "name") as! String == countTrack.name { + let asset = (track.value(forKey: "fileURL") as? CKAsset)! + countTracks[counter].fileData = asset + } + counter += 1 + } + counter = 0 + let video = upload.value(forKey: "video") as! CKRecord + for countVideo in countVideos { + if video.value(forKey: "name") as! String == countVideo.name { + let asset = (video.value(forKey: "fileURL") as? CKAsset)! + countVideos[counter].fileData = CKAsset(fileURL:asset.fileURL!) + } + counter += 1 + } + } + } + */ + } + + func retrieveFavorite() { + /* + documentController.getFavoritesFromCloudKit { (favourites) in + var tracks = [PrimitiveTrackDataStruct]() + var videos = [PrimitiveVideosDataStruct]() + for favourite in favourites { + if favourite.id == UserDefaults.standard.string(forKey: "email") { + if favourite.track != nil { + tracks = favourite.track! + } + if favourite.videos != nil { + videos = favourite.videos! + } + } + } + for track in tracks { + self.countTracks.append( + TrackDataStruct( + genre: track.genre, + name: track.name, + email: track.email, + fileURL: URL(fileURLWithPath: "") + ) + ) + } + for video in videos { + self.countVideos.append( + VideosDataStruct( + genre: video.genre, + name: video.name, + email: video.email, + fileURL: URL(fileURLWithPath: "") + ) + ) + } + DispatchQueue.main.async { + self.tableView.reloadData() + } + } + */ + } + + override func viewWillAppear(_ animated: Bool) { + DataManager.shared().getFavouritesData() + navigationController?.setNavigationBarHidden(true, animated: false) + navigationController?.navigationBar.shadowImage = nil + super.viewWillAppear(true) + } + + @IBAction func unwindToFavorite(_ segue: UIStoryboardSegue){ + + } + + @IBAction func accountButtonTouched(_ sender: Any) + { + if DataManager.shared().IsUserLogin() + { + self.performSegue(withIdentifier: "userProfileSegue", sender: nil) + } + else + { + self.performSegue(withIdentifier: "loginScreenSegue", sender: nil) + } + } + + // MARK: Storyboard + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "favoriteTracks" { + if let trackPlayerPage = segue.destination as? FavoriteTracksView { + trackPlayerPage.countTracks = countTracks + } + } + if segue.identifier == "favoriteVideos" { + if let videoPlayerPage = segue.destination as? FavoriteVideosView { + videoPlayerPage.countVideos = countVideos + } + } + } + + +} +extension FavouritesView: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1//countTracks.count + countVideos.count + } + + func numberOfSections(in tableView: UITableView) -> Int { + return Favorite.Count.rawValue + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "favoriteMenuCell", for: indexPath) as! FavoritesMenuCell + if indexPath.section == Favorite.FavoriteTrack.rawValue + { + cell.cellTitleLabel.text = "Favorite Tracks" + cell.countLabel.text = String(DataManager.shared().currentUser!.favMusics!.count) + } + else if indexPath.section == Favorite.FavoriteVideo.rawValue + { + cell.cellTitleLabel.text = "Favorite Videos" + cell.countLabel.text = String(DataManager.shared().currentUser!.favVideo!.count) + } + else if indexPath.section == Favorite.Albums.rawValue + { + cell.cellTitleLabel.text = "Albums" + cell.countLabel.text = String(0) + } + else if indexPath.section == Favorite.Artist.rawValue + { + cell.cellTitleLabel.text = "Artists" + cell.countLabel.text = String(DataManager.shared().currentUser!.favArtist!.count) + } + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat + { + return 60 + } + + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) + { + if indexPath.section == Favorite.FavoriteTrack.rawValue + { + performSegue(withIdentifier: "favoriteTracks", sender: self) + + } + else if indexPath.section == Favorite.FavoriteVideo.rawValue { + performSegue(withIdentifier: "favoriteVideos", sender: self) + }else if indexPath.section == Favorite.Artist.rawValue{ + performSegue(withIdentifier: "favoriteArtists", sender: self) + }else if indexPath.section == Favorite.Albums.rawValue{ + performSegue(withIdentifier: "favoriteAlbums", sender: self) + } + } +} diff --git a/frontend/mobile/CommunityMC3/Info.plist b/frontend/mobile/CommunityMC3/Info.plist new file mode 100644 index 0000000..96e5885 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Info.plist @@ -0,0 +1,91 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + LSApplicationQueriesSchemes + + instagram + whatsapp + + LSRequiresIPhoneOS + + LSSupportsOpeningDocumentsInPlace + + NSCameraUsageDescription + Hey folks, please allow the application to open the camera, due to capture your picture from camera. + NSPhotoLibraryUsageDescription + Hey folks, please allow the application to open the library, to select image from it and upload your picture. + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIBackgroundModes + + remote-notification + + UIFileSharingEnabled + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportsDocumentBrowser + + + diff --git a/frontend/mobile/CommunityMC3/Login View/ForgotPasswordController.swift b/frontend/mobile/CommunityMC3/Login View/ForgotPasswordController.swift new file mode 100644 index 0000000..06f62c0 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Login View/ForgotPasswordController.swift @@ -0,0 +1,22 @@ +// +// ForgotPasswordController.swift +// Allegro +// +// Created by Bernardinus on 10/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit + +class ForgotPasswordController:UIViewController +{ + override func viewDidLoad() { + super.viewDidLoad() + } + + @IBAction func submitForgotPassword(_ sender: Any) { + AlertViewHelper.creteAlert(self, title: "Recovery Password", msg: "An email for reseting the password has been sent") + } + +} diff --git a/frontend/mobile/CommunityMC3/Login View/LoginController.swift b/frontend/mobile/CommunityMC3/Login View/LoginController.swift new file mode 100644 index 0000000..51aa6a0 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Login View/LoginController.swift @@ -0,0 +1,154 @@ +// +// LoginController.swift +// CommunityMC3 +// +// Created by Bryanza on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import CloudKit + +class LoginController: UIViewController { + + @IBOutlet weak var signInTitleLabel: UILabel! + @IBOutlet weak var signInDescriptionLabel: UILabel! + @IBOutlet weak var emailTitleLabel: UILabel! + @IBOutlet weak var passwordTitleLabel: UILabel! + @IBOutlet weak var forgotPasswordButton: UIButton! + @IBOutlet weak var createAccountButton: UIButton! + @IBOutlet weak var emailField: UITextField! + @IBOutlet weak var passwordField: UITextField! + @IBOutlet weak var loginButton: UIButton! + @IBOutlet weak var wrongLabel: UILabel! + var callBack: (() -> Void)? = nil + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + setLocalisation() + passwordField.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: .editingChanged) + } + + func setLocalisation() { + signInTitleLabel.text = NSLocalizedString("Sign In", comment: "") + signInDescriptionLabel.text = NSLocalizedString("Sign In Description".uppercased(), comment: "") + emailTitleLabel.text = NSLocalizedString("Email Address", comment: "") + passwordTitleLabel.text = NSLocalizedString("Password", comment: "") + forgotPasswordButton.titleLabel?.text = NSLocalizedString("Forgot Password".uppercased(), comment: "") + createAccountButton.titleLabel?.text = NSLocalizedString("Create Account".uppercased(), comment: "") + loginButton.titleLabel?.text = NSLocalizedString("Get Started", comment: "") + } + + @IBAction func unwindToLoginController(_ segue:UIStoryboardSegue) + { + + } + + @objc func textFieldDidChange(_ textField: UITextField) { + // passwordField.placeholder = "" + passwordField.isSecureTextEntry = true + } + + override func viewWillAppear(_ animated: Bool) { + self.navigationController?.setNavigationBarHidden(true, animated: animated) + // super.viewWillAppear(animated) + // // if(flag==0){ + // // tutor1View.alpha = 1 + // // } + // } + // + // override func viewWillDisappear(_ animated: Bool) { + // self.navigationController?.setNavigationBarHidden(false, animated: animated) + // super.viewWillDisappear(animated) + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "registerNewUser" + { + let regVC = segue.destination as! RegisterController + regVC.callBack = callBack + } + } + + @IBAction func loginUser(_ sender: UIButton) { + switch sender { + case loginButton: + loginToCloudKit() + default: + return + } + } + + func loginToCoreData() { + if let oldAccount = Account.loginAccount(context: getViewContext(), accountEmail: emailField.text ?? "", accountPassword: passwordField.text ?? "") { + emailField.text = "" + passwordField.text = "" + print(oldAccount) + callBack!() + // self.performSegue(withIdentifier: "loginMain", sender: self) + } + } + + func loginToCloudKit() + { + print("login2cloudkit") + DataManager.shared().loginToCloudKit(email: emailField.text!, password: passwordField.text!) { (isSuccess, errorString) in + if(isSuccess) + { + print("loginSuccess") + DispatchQueue.main.async { + self.callBack!() + } + + } + else + { + print("loginFail :\(errorString)") + } + } + + /* + // 1. tunjuk databasenya apa + let database = CKContainer(identifier: "iCloud.ada.mc3.music").publicCloudDatabase + // let database = CKContainer(identifier: "iCloud.com.herokuapp.communitymc3").publicCloudDatabase + + // 2. kita tentuin recordnya + let predicate = NSPredicate(value: true) + // let query = CKQuery(recordType: "Register", predicate: predicate) + let query = CKQuery(recordType: "Account", predicate: predicate) + + // 3. execute querynya + database.perform(query, inZoneWith: nil) { records, error in + + if let err = error { + print(err.localizedDescription) + } + + print(records) + + if let fetchedRecords = records { + let registers = fetchedRecords + for register in registers { + DispatchQueue.main.async { + if register.value(forKey: "email") as? String == self.emailField.text ?? "" && register.value(forKey: "password") as? String == self.passwordField.text ?? "" { + print(register) + // self.tableView.reloadData() + UserDefaults.standard.set(self.emailField.text, forKey: "email") + self.emailField.text = "" + self.passwordField.text = "" + self.callBack!() + // self.performSegue(withIdentifier: "loginMain", sender: self) + }else{ + self.wrongLabel.isHidden = false + } + } + } + } + } + */ + } + + + +} diff --git a/frontend/mobile/CommunityMC3/Login View/LoginScreen.storyboard b/frontend/mobile/CommunityMC3/Login View/LoginScreen.storyboard new file mode 100644 index 0000000..d99cb0b --- /dev/null +++ b/frontend/mobile/CommunityMC3/Login View/LoginScreen.storyboard @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Login View/RegisterController.swift b/frontend/mobile/CommunityMC3/Login View/RegisterController.swift new file mode 100644 index 0000000..4e6e138 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Login View/RegisterController.swift @@ -0,0 +1,144 @@ +// +// RegisterController.swift +// CommunityMC3 +// +// Created by Bryanza on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import CoreData +import CloudKit +import Foundation + +class RegisterController: UIViewController { + + @IBOutlet weak var signUpTitleLabel: UILabel! + @IBOutlet weak var signUpDescriptionLabel: UILabel! + @IBOutlet weak var emailTitleLabel: UILabel! + @IBOutlet weak var passwordTitleLabel: UILabel! + @IBOutlet weak var registerButton: UIButton! + @IBOutlet weak var haveAccountButton: UIButton! + @IBOutlet weak var emailField: UITextField! + @IBOutlet weak var passwordField: UITextField! + var callBack: (() -> Void)? = nil + + override func viewDidLoad() { + super.viewDidLoad() + setLocalisation() + passwordField.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: .editingChanged) + // self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) //UIImage.init(named: "transparent.png") + // self.navigationController?.navigationBar.shadowImage = UIImage() + // self.navigationController?.navigationBar.isTranslucent = true + // self.navigationController?.view.backgroundColor = .clear + // Do any additional setup after loading the view. + } + + func setLocalisation() { + signUpTitleLabel.text = NSLocalizedString("Sign Up", comment: "") + signUpDescriptionLabel.text = NSLocalizedString("Sign Up Description".uppercased(), comment: "") + emailTitleLabel.text = NSLocalizedString("Email Address", comment: "") + passwordTitleLabel.text = NSLocalizedString("Password", comment: "") + registerButton.titleLabel?.text = NSLocalizedString("Register Now".uppercased(), comment: "") + haveAccountButton.titleLabel?.text = NSLocalizedString("Have Account".uppercased(), comment: "") + } + + @objc func textFieldDidChange(_ textField: UITextField) { + // passwordField.placeholder = "" + passwordField.isSecureTextEntry = true + } + + // override func viewWillAppear(_ animated: Bool) { + // self.navigationController?.setNavigationBarHidden(true, animated: animated) + // super.viewWillAppear(animated) + // } + // + // override func viewWillDisappear(_ animated: Bool) { + // self.navigationController?.setNavigationBarHidden(false, animated: animated) + // super.viewWillDisappear(animated) + // } + + // func SetBackBarButtonCustom() + // { + // //Back buttion + // let btnLeftMenu: UIButton = UIButton() + // btnLeftMenu.setImage(UIImage(named: "back_arrow"), for: UIControlState()) + // btnLeftMenu.addTarget(self, action: #selector(UIViewController.onClcikBack), for: UIControlEvents.touchUpInside) + // btnLeftMenu.frame = CGRect(x: 0, y: 0, width: 33/2, height: 27/2) + // let barButton = UIBarButtonItem(customView: btnLeftMenu) + // self.navigationItem.leftBarButtonItem = barButton + // } + // + // func onClcikBack() + // { + // _ = self.navigationController?.popViewController(animated: true) + // } + + @IBAction func registerUser(_ sender: UIButton) { + registerToCloudKit() + } + + func registerToCoreData() { + // let newTask = Task(context: getViewContext()) + if let newAccount = Account.registerAccount(context: getViewContext(), accountEmail: emailField.text ?? "", accountPassword: passwordField.text ?? "") { + emailField.text = "" + passwordField.text = "" +// print(newAccount) + callBack!() + // self.performSegue(withIdentifier: "registerMain", sender: self) + } + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "registerAccountSegue" + { + let vc = segue.destination as! SettingController + vc.isEditProfile = false + vc.emailAddr = emailField.text! + vc.password = passwordField.text! + } + } + + @IBAction func unwindToRegisterController(_ segue:UIStoryboardSegue) + { + + } + + func registerToCloudKit() { + + performSegue(withIdentifier: "registerAccountSegue", sender: nil) + /* + // 1. buat dulu recordnya + // let newRecord = CKRecord(recordType: "Register") + let newRecord = CKRecord(recordType: "Account") + + // 2. set propertynya + newRecord.setValue(emailField.text ?? "", forKey: "email") + newRecord.setValue(passwordField.text ?? "", forKey: "password") + + // 3. execute save or insert + let database = CKContainer(identifier: "iCloud.ada.mc3.music").publicCloudDatabase + // let database = CKContainer(identifier: "iCloud.com.herokuapp.communitymc3").publicCloudDatabase + // print(CKContainer.default()) + database.save(newRecord) { record, error in + if let err = error { + print(err.localizedDescription) + } + + print(record) + + DispatchQueue.main.async { + UserDefaults.standard.set(self.emailField.text, forKey: "email") + // self.dismiss(animated: true, completion: nil) + self.navigationController?.popViewController(animated: true) + self.callBack!() + // self.performSegue(withIdentifier: "registerMain", sender: self) + } + } + */ + } +} + + + + diff --git a/frontend/mobile/CommunityMC3/Main Storyboard/Base.lproj/Main.storyboard b/frontend/mobile/CommunityMC3/Main Storyboard/Base.lproj/Main.storyboard new file mode 100644 index 0000000..03ea444 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Main Storyboard/Base.lproj/Main.storyboard @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Main Storyboard/MainTabController.swift b/frontend/mobile/CommunityMC3/Main Storyboard/MainTabController.swift new file mode 100644 index 0000000..7dbac00 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Main Storyboard/MainTabController.swift @@ -0,0 +1,53 @@ +// +// MainTabController.swift +// CommunityMC3 +// +// Created by Bernardinus on 26/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class MainTabController: UITabBarController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + + + } + + override func viewDidAppear(_ animated: Bool) { + + let maxTabCount:Int = tabBar.items!.count + print(maxTabCount) + for index in 0.. DataManager + { + if instance == nil + { + instance = DataManager() + } + return instance + } + +// var selectedTrackData:TrackDataStruct? = nil +// var selectedVideoData:VideosDataStruct? = nil + + + var ckUtil:CloudKitUtil = CloudKitUtil.shared() + + // FEATURED DATA + + + + var currentUser:UserDataStruct? = nil +// var currentUsers:[UserDataStruct]? = nil + var currentUsersPrimitive:[PrimitiveUserDataStruct]? = nil + + + // CloudKit Data + var currentUserRec:CKRecord? = nil + + var userTrackRecord:[CKRecord] = [] + + var latestUploadRecord:[CKRecord] = [] + var latestUpload:[UploadedDataStruct]? = [] + var newLatestUpload:[UploadedDataStruct]? = [] + + var trendingNowRecord:CKRecord? + var trendingNow:FeaturedDataStruct? + var newTrendingNow:FeaturedDataStruct? + + var featuredArtistRecord:CKRecord? + var featuredArtist:FeaturedDataStruct? + var newFeaturedArtist:FeaturedDataStruct? + + var featuredVideosRecord:CKRecord? + var featuredVideos:FeaturedDataStruct? + var newFeaturedVideos:FeaturedDataStruct? + + + var latestFavouriteRec:[CKRecord] = [] + var latestFavourite:[FavouritesDataStruct] = [] + + + var allTracksRec:[CKRecord] = [] + var allTracks:[TrackDataStruct] = [] + var filteredTracks:[TrackDataStruct] = [] + + var allVideosRec:[CKRecord] = [] + var allVideos:[VideosDataStruct] = [] + var filteredVideos:[VideosDataStruct] = [] + + var allArtistRec:[CKRecord] = [] + var allArtist:[UserDataStruct] = [] + var filteredArtist:[UserDataStruct] = [] + + var randomSpotlightData:[UserDataStruct] = [] + + + + var registerData:AccountDataStruct? + + var userDefault:UserDefaults = UserDefaults.standard + + var willUpdateFeaturedData:Bool = false + var maxFeaturedData:Int = 50 + + func IsUserLogin()->Bool + { + return currentUserRec != nil + } + + var favTrackData:[TrackDataStruct] = [] + var favVideoData:[VideosDataStruct] = [] + var favArtistData:[UserDataStruct] = [] + + var favTrack:[String] = [ + "67479FC3-8B0B-47DE-9FFF-6A3ACD42B13F", +// "1308C17A-C61E-418A-9F0D-8DE866FCDAB2", + "FC600672-8645-4690-8C26-085BF5D95EDD", +// "3ADCEE6C-85E2-4409-85FD-B5BB8269AB54", + "D6BAD740-2E0F-4A49-BE1B-D5352B1295E6", +// "D3E83A7C-ECAA-4036-A3A8-EE472EA744AF", + "D37C13D8-9A28-42EC-AE39-CF4BB15BD2B7", +// "6D3F3F6E-A670-412B-8DD0-4E73025B99FF", + "2920EE82-FA14-4427-A3FD-3D9AF22F4152", +// "D474D375-35C2-4C64-AA86-CC14201D1D63", + "1CD9F0E2-16DE-43AE-8C06-20BDEDBFD828", +// "692E80FB-24A6-45D6-AC2D-56676C7295BC", + "46A5CD72-3BCD-49E1-B313-DA23A9C05060", +// "30461B86-0CF7-44C7-A050-051E86D1A84F", + "6395EB35-1F58-4B29-AEAF-CAC9863B17EA", +// "5E036B3D-F6F7-4815-BD8E-A8AA59E8B9D0", + "FD692C39-64B2-49E5-9769-2666703D56BE", +// "940233EB-C94F-4261-8201-3FA66221AB4A", + "0B283ABF-F409-4042-A547-A7C5F0D638DF", +// "D61C7F38-5B50-498E-8D20-4FCCEF5A0F0D", + "D5805C61-1605-4973-89AA-D0FF16F75DDA", +// "2A73E6BE-8FCD-4E79-97AF-DF43ADEBB45A", + "B5DB44AF-997C-43CB-8873-5A87FC4670BF", +// "2284B1A1-4113-4D8D-AB86-4200043ABEA8", + "1A4C51F4-73D5-4CFD-A536-7A8A4265EBDC", + ] + var favTrackNow:[TrackDataStruct] = [] + + func isFavouriteMusic(recordName:String) -> Bool + { + return favTrack.contains(recordName) + } + + private init() + { + print("dataManager.init") + + ckUtil.setup(cloudKitContainerID: iCloudContainerID) + +// willUpdateFeaturedData = true + + getFeaturedData() + autoLoginLastAccount() + + getAllMusic() + getAllVideos() + getAllArtist() + + } + + func updateExplorerView() + { + DispatchQueue.main.async { + + let rootVC = UIApplication.shared.keyWindow?.rootViewController! + if rootVC is StartViewController + { + let rootView = rootVC as! StartViewController + + let tabBarView = rootView.baseVC + let navVC = tabBarView!.viewControllers![0] as! UINavigationController + let explorerView = navVC.viewControllers[0] as! ExplorerView + explorerView.mainTableView.reloadData() + } + + } + + } + + + func autoLoginLastAccount() + { + let loginEmail:String? = userDefault.string(forKey: "email") + let loginPassword:String? = userDefault.string(forKey: "password") + var isSuccessLogin = false + if(loginEmail != nil && loginPassword != nil) + { + if(loginEmail != "" && loginPassword != "") + { + isSuccessLogin = true + print("auto login acc email:\(loginEmail) pass:\(loginPassword)") + loginToCloudKit(email: loginEmail!,password: loginPassword!, completionHandler: loginSuccess) + } + } + + if(!isSuccessLogin) + { + print("didn't login e:\(loginEmail) p:\(loginPassword)") + } + } + + func loginSuccess(isSuccess:Bool, errorString:String) + { +// print("Auto loginSuccess") +// getLatestFavourite() +// updateFeaturedArtist() // to test add user only + } + + + func logout() + { + let loadEmail = userDefault.string(forKey: "email") + if currentUsersPrimitive == nil { + if let loadUsers = userDefault.value(forKey: "users"){ + currentUsersPrimitive = try? JSONDecoder().decode([PrimitiveUserDataStruct].self, from: loadUsers as! Data) + } + } + var idx = 0 + for currentUserPrimitive in currentUsersPrimitive! { + if currentUserPrimitive.email == loadEmail { + currentUsersPrimitive?.remove(at: idx) + if currentUsersPrimitive!.count > 0 { + userDefault.set(currentUsersPrimitive![0].email, forKey: "email") + userDefault.set(currentUsersPrimitive![0].password, forKey: "password") + let data:[String: Bool] = ["data": true] + NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: data) + }else{ + currentUserRec = nil + userDefault.set("", forKey: "password") + userDefault.set("", forKey: "email") + } + let temp = try? JSONEncoder().encode(currentUsersPrimitive) + userDefault.set(temp, forKey: "users") + break + } + idx += 1 + } + userDefault.synchronize() + } + + // #MARK: REGISTER + func registerCurrentLoginInUserDefault(email:String, password:String, userData: UserDataStruct) + { + userDefault.set(email, forKey: "email") + userDefault.set(password, forKey: "password") + + if let loadUsers = userDefault.value(forKey: "users"){ + currentUsersPrimitive = try? JSONDecoder().decode([PrimitiveUserDataStruct].self, from: loadUsers as! Data) + if currentUsersPrimitive == nil { + registerPrimitiveUserData(email: email, password: password, userData: userData) + }else { + var flag = false + for currentUserPrimitive in currentUsersPrimitive! { + if currentUserPrimitive.name == userData.name { + flag = true + break + } + } + if !flag { + registerPrimitiveUserData(email: email, password: password, userData: userData) + } + } + }else{ + registerPrimitiveUserData(email: email, password: password, userData: userData) + } + userDefault.synchronize() + } + + func registerPrimitiveUserData(email: String, password: String, userData: UserDataStruct) { +// let imageData = userData.profilePicture!.jpegData(compressionQuality: 1) +// let relativePath = "image_\(userData.email).jpg" +// let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) +// let path = paths[0] as String; +// let fullPath = path + relativePath +// imageData!.write(to: URL(fullPath)) + let data = userData.profilePicture!.pngData(); // UIImage -> NSData, see also UIImageJPEGRepresentation + let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(userData.name! + ".dat") + do { + try data!.write(to: url!, options: []) + } catch let e as NSError { + print("Error! \(e)"); + return + } +// let path = try? String(contentsOf: url!) + let tmp = PrimitiveUserDataStruct ( + email: email, + password: password, + name: userData.name!, + role: userData.role!, + profilePicture: url!.absoluteString +// profilePicture: path! + ) + currentUsersPrimitive?.append(tmp) + let temp = try? JSONEncoder().encode(currentUsersPrimitive) + userDefault.set(temp, forKey: "users") +// currentUsers?.append(userData) + } + + func registerToCloudKit(email:String, + password:String, + userData:UserDataStruct, + completionHandler:@escaping(Bool, String, CKRecord?)->Void) + { + let accRecord:CKRecord = CKRecord(recordType: "Account") + accRecord.setValue(email, forKey: "email") + accRecord.setValue(password, forKey: "password") + + ckUtil.saveRecordToPublicDB(record: userData.getCKRecord()) { + (isSuccess, errorString, record) in + + if isSuccess + { + let userDataRef = CKRecord.Reference(record: record!, action: .deleteSelf) + accRecord.setValue(userDataRef, forKey: "userData") + self.ckUtil.saveRecordToPublicDB(record: accRecord) { + (isSuccess, errorString, record) in + + if isSuccess + { + print("Register User Data Success") + self.currentUserRec = userData.getCKRecord() + self.currentUser = UserDataStruct(self.currentUserRec!) + self.registerCurrentLoginInUserDefault(email: email, password: password, userData: self.currentUser!) + } + else + { + print("Register User Data - Account Failed error:\(errorString)") + } + completionHandler(isSuccess, errorString, record) + } + } + else + { + completionHandler(isSuccess, + "Register User Data Failed error:\(errorString)", + nil) + } + } + } + + + + // MARK: LOGIN + func loginToCloudKit(email:String, password:String, completionHandler:@escaping(Bool, String)->Void) + { + let predicate = NSPredicate(format: "email == '\(email)' AND password == '\(password)'") + let query = CKQuery(recordType: "Account", predicate: predicate) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, record) in + if(!isSuccess) + { + print("Login to CloudKit Error") + } + else + { +// print("Login to CloudKit Success \(record.count)") + self.currentUserRec = record[0] + self.currentUser = UserDataStruct(self.currentUserRec!) + let userDataRef = self.currentUserRec!.value(forKey: "userData")! as! CKRecord.Reference + + + self.ckUtil.loadRecordFromPublicDB(recordID: userDataRef.recordID) + { + (isSuccess, errorString, userRecord) in + if(isSuccess) + { +// print("UserData: \(userRecord!)") + self.currentUserRec = userRecord + self.currentUser = UserDataStruct(self.currentUserRec!) + + self.registerCurrentLoginInUserDefault(email: email, password: password, userData: self.currentUser!) + self.loginSuccess(isSuccess: isSuccess, errorString: errorString) +// print("Account: \(self.currentUserRec!)") +// + + let tracksData = userRecord?.value(forKey: "tracks") + if(tracksData != nil ) + { + self.loadTracks(tracksData: tracksData) + } + + let videosData = userRecord?.value(forKey: "videos") + if(videosData != nil ) + { + self.loadVideos(videosData: videosData) + } + + let photosData = userRecord?.value(forKey: "photos") + if(photosData != nil ) + { + self.loadPhotos(photosData: photosData) + } + + // TODO: ALBUM DATA + +// let albumData = userRecord?.value(forKey: "album") +// if(albumData != nil ) +// { +// self.loadAlbum(albumData: albumData) +// } +// + // TODO: FAVOURITES DATA + +// self.getLatestFavourite() + } + else + { + print("Record ID Not Found \(errorString)") + } + completionHandler(isSuccess, errorString) + + } + + + } + } + } + + func loadTracks(tracksData:Any?) + { + let tracks = tracksData as! [CKRecord.Reference] + if tracks.count == 0 {return} + self.ckUtil.loadRecordFromPublicDB(recordType: "Track", recordName: tracks) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + self.currentUser?.musics?.removeAll() + for tr in trackRecords + { + self.currentUser?.musics?.append(TrackDataStruct(record: tr)) + } + print("Load UserTrack:\(self.currentUser?.musics?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + func loadVideos(videosData:Any?) + { + let videos = videosData as! [CKRecord.Reference] + if videos.count == 0 {return} + self.ckUtil.loadRecordFromPublicDB(recordType: "Videos", recordName: videos) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + self.currentUser?.videos?.removeAll() + for tr in trackRecords + { + self.currentUser?.videos?.append(VideosDataStruct(record: tr)) + } + print("Load UserVideos:\(self.currentUser?.videos?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + func loadPhotos(photosData:Any?) + { + let photos = photosData as! [CKRecord.Reference] + if photos.count == 0 {return} + print("photosCount :\(photos.count)") + + self.ckUtil.loadRecordFromPublicDB(recordType: "Photos", recordName: photos) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + self.currentUser?.photos?.removeAll() + for tr in trackRecords + { + self.currentUser?.photos?.append(PhotoDataStruct(record: tr)) + } + print("Load UserPhotos:\(self.currentUser?.photos?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + + // MARK: Update Current User + func savecurrentUserRec() + { + ckUtil.saveRecordToPublicDB(record: currentUserRec!) { (isSuccess, errorString, record) in + if !isSuccess + { + print("Save current user record failed : \(errorString)") + } + else + { +// print("Save current user record success") + } + } + + } + + + // MARK: Upload + func UploadNewTrack(trackData:TrackDataStruct, completionHandler:@escaping(Bool, String)->Void) + { + ckUtil.saveRecordToPublicDB( + record: trackData.getCKRecord(), + completionHandler:{ (isSuccess, errorString, record) in + if !isSuccess + { + print("UploadNewMusic Error : \(errorString)") + completionHandler(isSuccess, errorString) + } + else + { + let uploadedData = UploadedDataStruct(uploadedDate: Date.init(timeIntervalSinceNow: 7*3600), + track: record!, + video: nil) + + self.UpdateNewUploadData(record: uploadedData.getCKRecord()) + + if(self.currentUserRec != nil) + { + var allTracks = self.currentUserRec?.value(forKey: "tracks") + let ref = CKRecord.Reference(record: record!, action: .deleteSelf) + var arr:NSMutableArray? = nil + + if(allTracks != nil) + { +// print("allTracks not nil") + arr = NSMutableArray(array:self.currentUserRec!["tracks"] as! [CKRecord.Reference]) + arr!.add(ref) +// print(arr) + } + else + { +// print("allTracks nil") + arr = NSMutableArray(array: [ref]) + } + self.currentUserRec?.setValue(arr, forKey: "tracks") + self.currentUserRec?.setValue(1, forKey: "isArtist") + } + + self.savecurrentUserRec() + completionHandler(isSuccess, errorString) + } + + }) + } + + func UploadNewVideo(videoData:VideosDataStruct, completionHandler:@escaping(Bool, String)->Void) + { + ckUtil.saveRecordToPublicDB( + record: videoData.getCKRecord(), + completionHandler:{ (isSuccess, errorString, record) in + if !isSuccess + { + print("UploadNewVideo Error : \(errorString)") + completionHandler(isSuccess, errorString) + } + else + { + let uploadedData = UploadedDataStruct(uploadedDate: Date.init(timeIntervalSinceNow: 7*3600), + track: nil, + video: record!) + + self.UpdateNewUploadData(record: uploadedData.getCKRecord()) + + if(self.currentUserRec != nil) + { + var allTracks = self.currentUserRec?.value(forKey: "videos") + let ref = CKRecord.Reference(record: record!, action: .deleteSelf) + var arr:NSMutableArray? = nil + + if(allTracks != nil) + { +// print("allTracks not nil") + arr = NSMutableArray(array:self.currentUserRec!["videos"] as! [CKRecord.Reference]) + arr!.add(ref) +// print(arr) + } + else + { +// print("allTracks nil") + arr = NSMutableArray(array: [ref]) + } + self.currentUserRec?.setValue(arr, forKey: "videos") + self.currentUserRec?.setValue(1, forKey: "isArtist") + } + + self.savecurrentUserRec() + completionHandler(isSuccess, errorString) + } + + }) + } + + func UploadNewPhoto(photoData:PhotoDataStruct, completionHandler:@escaping(Bool, String)->Void) + { + ckUtil.saveRecordToPublicDB( + record: photoData.getCKRecord(), + completionHandler:{ (isSuccess, errorString, record) in + if !isSuccess + { + print("UploadNewPhotos Error : \(errorString)") + completionHandler(isSuccess, errorString) + } + else + { + + if(self.currentUserRec != nil) + { + var allTracks = self.currentUserRec?.value(forKey: "photos") + let ref = CKRecord.Reference(record: record!, action: .deleteSelf) + var arr:NSMutableArray? = nil + + if(allTracks != nil) + { +// print("allTracks not nil") + arr = NSMutableArray(array:self.currentUserRec!["photos"] as! [CKRecord.Reference]) + arr!.add(ref) +// print(arr) + } + else + { +// print("allTracks nil") + arr = NSMutableArray(array: [ref]) + } + self.currentUserRec?.setValue(arr, forKey: "photos") + self.currentUserRec?.setValue(1, forKey: "isArtist") + } + + self.savecurrentUserRec() + completionHandler(isSuccess, errorString) + } + + }) + } + + + func UpdateNewUploadData(record:CKRecord) + { + ckUtil.saveRecordToPublicDB(record: record) { (isSuccess, errorString, record) in + if !isSuccess + { + print("Upload New Data Error :\(errorString)") + } + else + { +// print("Upload New Data Success :\(errorString)") + } + } + } + + // MARK: FEATURED + func getFeaturedData() + { + getTrendingNow() + getLatestUpload() + getFeaturedArtist() + getFeaturedVideo() + } + + //MARK: TRENDING NOW + func getTrendingNow() + { + let query = CKQuery(recordType: "Featured", predicate: NSPredicate(format: "id = %@", "trendingNow")) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("GetFeaturedID Error \(errorString)") + } + else + { + print("GetFeaturedID Success") + let count:Int = records.count + if count > 0 + { + + let trendingNowRecord = records[0] + self.newTrendingNow = FeaturedDataStruct() + self.newTrendingNow!.id = trendingNowRecord.recordID + + let trackRefArrData = trendingNowRecord.value(forKey: "tracks") + if( trackRefArrData != nil) + { + let trackRefArr = trackRefArrData as! [CKRecord.Reference] + self.ckUtil.loadRecordFromPublicDB(recordType: "Track", recordName: trackRefArr, completionHandler: self.trendingNowTracksResult) + + + self.trendingNowRecord = trendingNowRecord + } + + } + else + { + print("GetFeaturedArtist Error 0 Count") + } + } + } + } + + func trendingNowTracksResult(isSuccess:Bool, errorString:String, records:[CKRecord]) + { + if(isSuccess) + { + print("Trending now getTracks Success") + self.newTrendingNow?.tracks.removeAll() + + for record in records + { + let trackData = TrackDataStruct(record: record) + self.newTrendingNow?.tracks.append(trackData) + + } + self.trendingNow = newTrendingNow + updateExplorerView() + print("Trending Now :\(self.trendingNow!.tracks.count)") +// print("Trending Now ID:\(self.trendingNow!.tracks.map({$0.record!.recordID}))") +// favTrackNow = self.trendingNow!.tracks.filter{favTrack.contains(($0.record?.recordID.recordName)!)} +// print("Trending Now Favourited:\(favTrackNow) \(favTrackNow.count)") + } + else + { + print("Trending now getTracks Failed \(errorString)") + } + } + + + func updateTrendingNow() + { + let query = CKQuery(recordType: "Featured", predicate: NSPredicate(format: "id = %@", "trendingNow")) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("Update TrendingNow Error") + } + else + { + let count:Int = records.count + if count > 0 + { + print("Update TrendingNow Success \(records.count)") + + let featuredTracksRecord = records[0] + + let allTracksRecCount = self.allTracksRec.count + let totalFeaturedRecords:Int = min(allTracksRecCount, self.maxFeaturedData) + + let arr:NSMutableArray = NSMutableArray() + if allTracksRecCount < self.maxFeaturedData + { + let usedArr = self.allTracksRec.shuffled() + + for i in 0.. 0 + { + + for _ in 1...totalFeaturedRecords + { + let ref = CKRecord.Reference(record: self.allArtistRec.randomElement()!, action: .deleteSelf) + arr.add(ref) + } + + } + featuredTracksRecord.setValue(arr, forKey: "tracks") + self.ckUtil.saveRecordToPublicDB(record: featuredTracksRecord) { (isSuccess, errorString, record) in + print("update Record TrendingNow: \(isSuccess) \(errorString)") + if(isSuccess) + { + self.getTrendingNow() + } + } + } + else + { + print("Update TrendingNow Error 0 Count") + } + + } + } + } + + // MARK: LATEST UPLOAD + func getLatestUpload() + { + let query = CKQuery(recordType: "UploadedData", predicate: NSPredicate(value: true)) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("GetLatestUpload Error") + } + else + { + self.latestUploadRecord = records + let maxRecords = records.count + print("GetLatestUpload Success \(records.count)") + var idx = 0 + for record in records + { + let upData = UploadedDataStruct() + var usedRef = record.value(forKey: "video") as? CKRecord.Reference + if usedRef == nil + { + upData.isVideo = false + usedRef = record.value(forKey: "track") as? CKRecord.Reference + } + else + { + upData.isVideo = true + } + let cIDX = idx + self.ckUtil.loadRecordFromPublicDB(recordID: usedRef!.recordID) { (dataIsSuccess, dataErrorStr, dataRecord) in + self.updateUploadedDataStuct(uploadedData: upData, idx: cIDX, isSuccess: dataIsSuccess, errorString: dataErrorStr, record: dataRecord!, maxRecords: maxRecords) + } + idx += 1 + } + } + } + } + + func updateUploadedDataStuct(uploadedData:UploadedDataStruct, idx:Int, isSuccess:Bool, errorString:String, record:CKRecord, maxRecords:Int) + { + if(isSuccess) + { + uploadedData.updateData(recordMediaData: record) + self.newLatestUpload!.append(uploadedData) +// print("Get UploadedDataStruct success: \(idx) \(self.newLatestUpload!.count) \(maxRecords)") + + if(self.newLatestUpload!.count == maxRecords) + { + self.latestUpload = self.newLatestUpload + updateExplorerView() + } + } + else + { + print("Get UploadedDataStruct Failed: \(errorString)") + } + } + + // MARK: FEATURED ARTIST + func getFeaturedArtist() + { + let query = CKQuery(recordType: "Featured", predicate: NSPredicate(format: "id = %@", "featuredArtist")) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("GetFeaturedArtist Error") + } + else + { + let count:Int = records.count + if count > 0 + { +// print("GetFeaturedArtist Success \(records.count)") + let featuredArtistRecord = records[0] +// print(featuredArtistRecorxd) + self.newFeaturedArtist = FeaturedDataStruct() + self.newFeaturedArtist?.id = featuredArtistRecord.recordID + + let artistRefArrData = featuredArtistRecord.value(forKey: "users") + if(artistRefArrData != nil) + { + let artistRefArr = artistRefArrData as! [CKRecord.Reference] + self.ckUtil.loadRecordFromPublicDB(recordType: "UserData", recordName: artistRefArr, completionHandler: self.featuredArtistTrackResult) + + self.featuredArtistRecord = featuredArtistRecord + } + } + else + { + print("GetFeaturedArtist Error 0 Count") + } + + } + } + } + + func featuredArtistTrackResult(isSuccess:Bool, errorString:String, records:[CKRecord]) + { + if(isSuccess) + { + print("Featured Artist Get User Success \(records.count)") + self.newFeaturedArtist?.users.removeAll() + for record in records + { + let userData = UserDataStruct(record) + self.newFeaturedArtist?.users.append(userData) + } + self.featuredArtist = newFeaturedArtist + + var index = 0 + for data in featuredArtist!.users + { + loadFeaturedArtistData(artistIndex: index, featuredArtistRecord: data.record!) + index += 1 + } + + updateExplorerView() + print("FeaturedArtist :\(self.featuredArtist!.users.count)") + } + else + { + print("Featured Artist Get User Failed") + } + } + + func loadFeaturedArtistData(artistIndex:Int, featuredArtistRecord:CKRecord) + { + let tracksData = featuredArtistRecord.value(forKey: "tracks") + if(tracksData != nil ) + { + self.loadFeaturedArtistTracks(artistIndex,tracksData: tracksData) + } + + let videosData = featuredArtistRecord.value(forKey: "videos") + if(videosData != nil ) + { + self.loadFeaturedArtistVideos(artistIndex, videosData: videosData) + } + + let photosData = featuredArtistRecord.value(forKey: "photos") + if(photosData != nil ) + { + self.loadFeaturedArtistPhotos(artistIndex, photosData: photosData) + } + } + + func loadFeaturedArtistTracks(_ artistIndex:Int, tracksData:Any?) + { + let tracks = tracksData as! [CKRecord.Reference] + if tracks.count == 0 {return} + var artistData = featuredArtist?.users[artistIndex] + self.ckUtil.loadRecordFromPublicDB(recordType: "Track", recordName: tracks) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + if(artistData!.musics == nil) + { + artistData!.musics = [] + } + artistData!.musics?.removeAll() + for tr in trackRecords + { + artistData!.musics?.append(TrackDataStruct(record: tr)) + } + print("Load Featured Artist \(artistData?.name)Track:\(artistData!.musics?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + func loadFeaturedArtistVideos(_ artistIndex:Int,videosData:Any?) + { + let videos = videosData as! [CKRecord.Reference] + if videos.count == 0 {return} + var artistData = featuredArtist?.users[artistIndex] + + self.ckUtil.loadRecordFromPublicDB(recordType: "Videos", recordName: videos) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + if(artistData!.videos == nil) + { + artistData!.videos = [] + } + artistData!.videos?.removeAll() + for tr in trackRecords + { + artistData!.videos?.append(VideosDataStruct(record: tr)) + } + print("Load featured artist \(artistData?.name) videos:\(artistData!.videos?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + func loadFeaturedArtistPhotos(_ artistIndex:Int,photosData:Any?) + { + let photos = photosData as! [CKRecord.Reference] + if photos.count == 0 {return} + print("photosCount :\(photos.count)") + var artistData = featuredArtist?.users[artistIndex] + self.ckUtil.loadRecordFromPublicDB(recordType: "Photos", recordName: photos) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + if(artistData!.photos == nil) + { + artistData!.photos = [] + } + artistData!.photos?.removeAll() + for tr in trackRecords + { + artistData!.photos?.append(PhotoDataStruct(record: tr)) + } + print("Load featured artist \(artistData?.name) Photos:\(artistData!.photos?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + func getFavouritesData() + { + favTrackData = allTracks.filter{currentUser!.isFavMusic(recName:$0.record!.recordID.recordName)} + favVideoData = allVideos.filter{currentUser!.isFavVideo(recName:$0.record!.recordID.recordName)} + favArtistData = allArtist.filter{currentUser!.isFavArtist(recName:$0.record!.recordID.recordName)} + } + + + + func updateFeaturedArtist() + { + let query = CKQuery(recordType: "Featured", predicate: NSPredicate(format: "id = %@", "featuredArtist")) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("Update Featured Artist Error \(errorString)") + } + else + { + let count:Int = records.count + if count > 0 + { + print("Update Featured Artist Success \(records.count)") + + let featuredArtistRecord = records[0] + + let allArtistRecCount = self.allArtistRec.count + let totalFeaturedRecords:Int = min(allArtistRecCount, self.maxFeaturedData) + + let arr:NSMutableArray = NSMutableArray() + if allArtistRecCount < self.maxFeaturedData + { + let usedArr = self.allArtistRec.shuffled() + + for i in 0.. 0 + { + + for _ in 0.. 0) + { + print("GetFeaturedVideos Success") + let featuredVideosRecord = records[0] + self.newFeaturedVideos = FeaturedDataStruct() + self.newFeaturedVideos!.id = featuredVideosRecord.recordID + + let videoRefArrData = featuredVideosRecord.value(forKey: "videos") + if(videoRefArrData != nil) + { + let videoRefArr = featuredVideosRecord.value(forKey: "videos") as! [CKRecord.Reference] + self.ckUtil.loadRecordFromPublicDB(recordType: "Videos", recordName: videoRefArr, completionHandler: self.featuredVideoTracksResult) + + + self.featuredVideosRecord = featuredVideosRecord + + } + } + else + { + print("GetFeaturedVideos Error 0 Count") + } + } + } + } + + func featuredVideoTracksResult(isSuccess:Bool, errorString:String, records:[CKRecord]) + { + if(isSuccess) + { + print("FeaturedVideo getVideo Success") + self.newFeaturedVideos?.videos.removeAll() + + for record in records + { + let videoData = VideosDataStruct(record: record) + self.newFeaturedVideos?.videos.append(videoData) + + } + self.featuredVideos = newFeaturedVideos + updateExplorerView() + print("FeaturedVideos :\(self.featuredVideos?.videos.count)") + } + else + { + print("FeaturedVideo getVideo Failed \(errorString)") + } + } + + func updateFeaturedVideo() + { + let query = CKQuery(recordType: "Featured", predicate: NSPredicate(format: "id = %@", "featuredVideo")) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("Update Featured Video Error \(errorString)") + } + else + { + let count:Int = records.count + if count > 0 + { + print("Update Featured Video Success \(records.count)") + + let featuredVideoRecord = records[0] + + let allVideoRecCount = self.allVideosRec.count + let totalFeaturedRecords:Int = min(allVideoRecCount, self.maxFeaturedData) + + let arr:NSMutableArray = NSMutableArray() + if allVideoRecCount < self.maxFeaturedData + { + let usedArr = self.allVideosRec.shuffled() + + for i in 0.. 0 + { + + for _ in 1...totalFeaturedRecords + { + let ref = CKRecord.Reference(record: self.allArtistRec.randomElement()!, action: .deleteSelf) + arr.add(ref) + } + + } + featuredVideoRecord.setValue(arr, forKey: "videos") + self.ckUtil.saveRecordToPublicDB(record: featuredVideoRecord) { (isSuccess, errorString, record) in + print("update Record FeaturedVideos: \(isSuccess) \(errorString)") + if(isSuccess) + { + self.getFeaturedVideo() + } + } + } + else + { + print("Update Featured Video Error 0 Count") + } + + } + } + } + + // MARK: FAVOURITE + /* + func UploadNewFavourite(favouriteData:FavouritesDataStruct, completionHandler:(Bool, String)->Void) + { + + ckUtil.saveRecordToPublicDB( + record: favouriteData.getCKRecord(), + completionHandler:{ (isSuccess, errorString, record) in + if !isSuccess + { + print("UploadNewFavourite Error : \(errorString)") + } + else + { + print("UploadNewFavourite Success") + } + }) + + } + + func getLatestFavourite() + { + let query = CKQuery(recordType: "Favourites", predicate: NSPredicate(value: true)) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, record) in + if(!isSuccess) + { + print("GetLatestFavourite Error") + } + else + { + print("GetLatestFavourite Success") + self.latestFavouriteRec = record + print(self.latestFavouriteRec) + } + } + } + */ + func AddFavourites(favType:UserFavourites, recordName:String) + { + if(currentUser != nil) + { + switch favType { + case .Track: + if(!(currentUser?.favMusics?.contains(recordName))!) + { + currentUser?.favMusics?.append(recordName) + } + case .Video: + if(!(currentUser?.favVideo?.contains(recordName))!) + { + currentUser?.favArtist?.append(recordName) + } + case .Artist: + if(!(currentUser?.favArtist?.contains(recordName))!) + { + currentUser?.favArtist?.append(recordName) + } + } + savecurrentUserRec() + } + } + + func RemoveFavourites(favType:UserFavourites, recordName:String) + { + if(currentUser != nil) + { + switch favType { + case .Track: + if((currentUser?.favMusics?.contains(recordName))!) + { + currentUser!.favMusics!.remove(at:currentUser!.favMusics!.firstIndex(of:recordName)!) + } + case .Video: + if((currentUser?.favVideo?.contains(recordName))!) + { + currentUser?.favVideo?.remove(at:(currentUser?.favVideo?.firstIndex(of:recordName))!) + } + case .Artist: + if((currentUser?.favArtist?.contains(recordName))!) + { + currentUser?.favArtist?.remove(at:(currentUser?.favArtist?.firstIndex(of:recordName))!) + } + } + savecurrentUserRec() + } + } + + // MARK: GET ALL + func getAllMusic() + { + let query = CKQuery(recordType: "Track", predicate: NSPredicate(value: true)) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("getAllMusic Error") + } + else + { + print("getAllMusic Success") + self.allTracksRec = records + self.allTracks.removeAll() + for record in records + { + self.allTracks.append(TrackDataStruct(record:record)) + } + self.filteredTracks = self.allTracks + print("FilterTrack \(self.filteredTracks.count)") + + if self.willUpdateFeaturedData + { + self.updateTrendingNow() + } + } + } + } + + func getAllVideos() + { + let query = CKQuery(recordType: "Videos", predicate: NSPredicate(value: true)) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("getAllVideos Error") + } + else + { + print("getAllVideos Success") + self.allVideosRec = records + self.allVideos.removeAll() + for record in records + { + self.allVideos.append(VideosDataStruct(record: record)) + } + self.filteredVideos = self.allVideos + print("FilterVideos \(self.filteredTracks.count)") + + if(self.willUpdateFeaturedData) + { + self.updateFeaturedVideo() + } + } + } + } + + func getAllArtist() + { + let query = CKQuery(recordType: "UserData", predicate: NSPredicate(format: "isArtist = 1")) + ckUtil.loadRecordFromPublicDB(query: query) { (isSuccess, errorString, records) in + if(!isSuccess) + { + print("getAllArtist Error \(errorString)") + } + else + { + print("getAllArtist Success") + self.allArtistRec = records + self.allArtist.removeAll() + var index:Int = 0 + for record in records + { + self.allArtist.append(UserDataStruct(record)) + self.loadAllArtistData(artistIndex: index, artistRecord: record) + index += 1 + } + self.filteredArtist = self.allArtist + self.randomSpotlightData = self.allArtist.shuffled() + print("FilterArtist \(self.filteredTracks.count)") + + if(self.willUpdateFeaturedData) + { + self.updateFeaturedArtist() + } + } + } + } + + // MARK: LOAD USER DATA + func loadAllArtistData(artistIndex:Int, artistRecord:CKRecord) + { + let tracksData = artistRecord.value(forKey: "tracks") + if(tracksData != nil ) + { + self.loadAllArtistTracks(artistIndex,tracksData: tracksData) + } + + let videosData = artistRecord.value(forKey: "videos") + if(videosData != nil ) + { + self.loadAllArtistVideos(artistIndex, videosData: videosData) + } + + let photosData = artistRecord.value(forKey: "photos") + if(photosData != nil ) + { + self.loadAllArtistPhotos(artistIndex, photosData: photosData) + } + } + + func loadAllArtistTracks(_ artistIndex:Int, tracksData:Any?) + { + let tracks = tracksData as! [CKRecord.Reference] + if tracks.count == 0 {return} + var artistData = allArtist[artistIndex] + self.ckUtil.loadRecordFromPublicDB(recordType: "Track", recordName: tracks) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + artistData.musics?.removeAll() + for tr in trackRecords + { + artistData.musics?.append(TrackDataStruct(record: tr)) + } + print("Load all Artist \(artistData.name)Track:\(artistData.musics?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + func loadAllArtistVideos(_ artistIndex:Int,videosData:Any?) + { + let videos = videosData as! [CKRecord.Reference] + if videos.count == 0 {return} + var artistData = allArtist[artistIndex] + + self.ckUtil.loadRecordFromPublicDB(recordType: "Videos", recordName: videos) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + artistData.videos?.removeAll() + for tr in trackRecords + { + artistData.videos?.append(VideosDataStruct(record: tr)) + } + print("Load all artist \(artistData.name) videos:\(artistData.videos?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + func loadAllArtistPhotos(_ artistIndex:Int,photosData:Any?) + { + let photos = photosData as! [CKRecord.Reference] + if photos.count == 0 {return} + print("photosCount :\(photos.count)") + var artistData = allArtist[artistIndex] + self.ckUtil.loadRecordFromPublicDB(recordType: "Photos", recordName: photos) + { (isSuccess, errorString, trackRecords:[CKRecord]) in + + if(isSuccess) + { + artistData.photos?.removeAll() + for tr in trackRecords + { + artistData.photos?.append(PhotoDataStruct(record: tr)) + } + print("Load All artist \(artistData.name) Photos:\(artistData.photos?.count)") + } + else + { + print("failedGet Track: \(errorString)") + } + } + + } + + // MARK: SEARCH + + func filterArtist(_ filterText:String?) + { + filteredArtist = allArtist + if(filterText != nil) + { + if !(filterText!.isEmpty) + { + filteredArtist = allArtist.filter({ (data) -> Bool in + var result:Bool = false + if(data.name != nil) + { + if !result {result = data.name!.containsInsesitive(string: filterText!)} + } + if(data.genre != nil) + { + if !result {result = data.genre!.containsInsesitive(string: filterText!)} + } + if(data.role != nil) + { + if !result {result = data.role!.containsInsesitive(string: filterText!)} + } + return result + }) + } + } + } + + func filterTracks(_ filterText:String?) + { + filteredTracks = allTracks + if(filterText != nil) + { + if !(filterText!.isEmpty) + { + filteredTracks = allTracks.filter({ (data) -> Bool in + var result:Bool = false + if !result {result = data.name.containsInsesitive(string: filterText!)} + if !result {result = data.genre.containsInsesitive(string: filterText!)} + if(data.album != nil) + { + if !result {result = data.album!.name.containsInsesitive(string: filterText!)} + } + return result + }) + } + } + } + + func filterVideo(_ filterText:String?) + { + filteredVideos = allVideos + if(filterText != nil) + { + if !(filterText!.isEmpty) + { + filteredVideos = allVideos.filter({ (data) -> Bool in + var result:Bool = false + if !result {result = data.name.containsInsesitive(string: filterText!)} + if !result {result = data.genre.containsInsesitive(string: filterText!)} + if !result {result = data.artistName.containsInsesitive(string: filterText!)} + if(data.album != nil) + { + if !result {result = data.album!.name.containsInsesitive(string: filterText!)} + } + return result + + }) + } + } + } + + // MARK: RANDOM SPOTLIGHT + + func filterRandomSpotlight() + { + randomSpotlightData = [] + } +} diff --git a/frontend/mobile/CommunityMC3/Manager/FileManager.swift b/frontend/mobile/CommunityMC3/Manager/FileManager.swift new file mode 100644 index 0000000..06095a0 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Manager/FileManager.swift @@ -0,0 +1,50 @@ +// +// FileManager.swift +// CommunityMC3 +// +// Created by Bernardinus on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation + +class FileManagers +{ + private static let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + + + class func getAvailableAudioFiles() -> [URL] + { + return FileManagers.getFileList(availableAudioFilesExt) + } + + class func getAvailableVideoFiles() -> [URL] + { + return FileManagers.getFileList(availableVideoFilesExt) + } + + + class func getFileList(_ filter:[String] = []) -> [URL] + { + do { + + print(documentsUrl) + + let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil) + + var filteredFiles = directoryContents + if(filter.count > 0) + { + filteredFiles = directoryContents.filter({ (url) -> Bool in + filter.contains(url.pathExtension) + }) + } + + return filteredFiles + } catch { + print(error) + return [] + } + } + +} diff --git a/frontend/mobile/CommunityMC3/Manager/TrackManager.swift b/frontend/mobile/CommunityMC3/Manager/TrackManager.swift new file mode 100644 index 0000000..aa766fe --- /dev/null +++ b/frontend/mobile/CommunityMC3/Manager/TrackManager.swift @@ -0,0 +1,66 @@ +// +// TrackManager.swift +// Allegro +// +// Created by Rommy Julius Dwidharma on 07/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit +import AVKit + +class TrackManager { + + static let shared = TrackManager() + weak var delegate: MiniTrackPlayerDelegate? + + init() { + print("TrackManagerInit") + } + + func play(trackData: TrackDataStruct){ + delegate?.play(data: trackData) + } + + func stop() { + delegate?.stop() + } + func pause(){ + delegate?.pause() + } + + // to play videos in new view controller + func playVideo(view:UIViewController, videoData:VideosDataStruct) + { + let URL = saveVideoToLocalData(video: videoData) + let playerItem:AVPlayerItem = AVPlayerItem.init(url: URL!) + let video:AVPlayer? = AVPlayer(url: URL!) + video?.allowsExternalPlayback = true + if video != nil { + let videoPlayer = AVPlayerViewController() + videoPlayer.player = video! + + //enter video player mode + view.present(videoPlayer, animated: true, completion: { + video!.play() + }) + } + } + + func saveVideoToLocalData(video: VideosDataStruct?) -> URL? + { + if video != nil { + let videoURL = video!.fileData?.fileURL! + let videoData = NSData(contentsOf: videoURL! as URL) + + let documentsPath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0] + let destinationPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent("cache" + ".mp4", isDirectory: false) + + FileManager.default.createFile(atPath: (destinationPath?.path)!, contents:videoData as Data?, attributes:nil) + + return destinationPath! + } + return nil + } +} diff --git a/frontend/mobile/CommunityMC3/NotificationView/Notifications.storyboard b/frontend/mobile/CommunityMC3/NotificationView/Notifications.storyboard new file mode 100644 index 0000000..d3c0368 --- /dev/null +++ b/frontend/mobile/CommunityMC3/NotificationView/Notifications.storyboard @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/NotificationView/NotificationsVC.swift b/frontend/mobile/CommunityMC3/NotificationView/NotificationsVC.swift new file mode 100644 index 0000000..0e49d03 --- /dev/null +++ b/frontend/mobile/CommunityMC3/NotificationView/NotificationsVC.swift @@ -0,0 +1,41 @@ +// +// NotificationsVC.swift +// CommunityMC3 +// +// Created by Theofani on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class NotificationsVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + navigationController?.navigationBar.backItem?.title = "" + + // Do any additional setup after loading the view. + } + + override func viewWillAppear(_ animated: Bool) + { + navigationController?.setNavigationBarHidden(false, animated: false) + super .viewWillAppear(animated) + } + + @IBAction func clearAllButtonTouched(_ sender: Any) + { + + } + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/frontend/mobile/CommunityMC3/OnboardingScreen/CarouselPageViewController_.swift b/frontend/mobile/CommunityMC3/OnboardingScreen/CarouselPageViewController_.swift new file mode 100644 index 0000000..e38b3a9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/OnboardingScreen/CarouselPageViewController_.swift @@ -0,0 +1,102 @@ +import Foundation +import UIKit + +class CarouselPageViewController_: UIPageViewController { + fileprivate var items: [UIViewController] = { + let sb = UIStoryboard(name: "OnboardingScreen", bundle: nil) + + let vc1 = sb.instantiateViewController(withIdentifier: "onboardingView1") + let vc2 = sb.instantiateViewController(withIdentifier: "onboardingView2") + let vc3 = sb.instantiateViewController(withIdentifier: "onboardingView3") + + + return [vc1, vc2, vc3] + }() + + override func viewDidLoad() { + super.viewDidLoad() + dataSource = self + + decoratePageControl() + +// populateItems() + if let firstViewController = items.first { + setViewControllers([firstViewController], direction: .forward, animated: true, completion: nil) + } + } + + fileprivate func decoratePageControl() { + let pc = UIPageControl.appearance(whenContainedInInstancesOf: [CarouselPageViewController_.self]) + pc.currentPageIndicatorTintColor = .magenta + pc.pageIndicatorTintColor = .gray + } + + fileprivate func populateItems() { + let text = ["🎖", "👑", "🥇"] + let backgroundColor:[UIColor] = [.blue, .red, .green] + + for (index, t) in text.enumerated() { + let c = createCarouselItemControler(with: t, with: backgroundColor[index]) + items.append(c) + } + } + + fileprivate func createCarouselItemControler(with titleText: String?, with color: UIColor?) -> UIViewController { + let c = UIViewController() + c.view = CarouselItem(titleText: titleText, background: color) + + return c + } +} + +// MARK: - DataSource + +extension CarouselPageViewController_: UIPageViewControllerDataSource { + func pageViewController(_: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = items.firstIndex(of: viewController) else { + return nil + } + + let previousIndex = viewControllerIndex - 1 + + guard previousIndex >= 0 else { + return items.last + } + + guard items.count > previousIndex else { + return nil + } + + return items[previousIndex] + } + + func pageViewController(_: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = items.firstIndex(of: viewController) else { + return nil + } + + let nextIndex = viewControllerIndex + 1 + guard items.count != nextIndex else { + return items.first + } + + guard items.count > nextIndex else { + return nil + } + + return items[nextIndex] + } + + func presentationCount(for _: UIPageViewController) -> Int { + return items.count + } + + func presentationIndex(for _: UIPageViewController) -> Int { + guard let firstViewController = viewControllers?.first, + let firstViewControllerIndex = items.firstIndex(of: firstViewController) else { + return 0 + } + + return firstViewControllerIndex + } +} diff --git a/frontend/mobile/CommunityMC3/OnboardingScreen/CarouselViewController_.swift b/frontend/mobile/CommunityMC3/OnboardingScreen/CarouselViewController_.swift new file mode 100644 index 0000000..d9b1b18 --- /dev/null +++ b/frontend/mobile/CommunityMC3/OnboardingScreen/CarouselViewController_.swift @@ -0,0 +1,18 @@ +import UIKit + +class CarouselViewController_: UIViewController { + + @IBOutlet weak var vwContainer: UIView! + @IBOutlet weak var btnNext: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + } + + @IBAction func signInButtonTouched(_ sender: Any) { + + showLogin = true + performSegue(withIdentifier: "signInFromOnboarding", sender: nil) + } +} + diff --git a/frontend/mobile/CommunityMC3/OnboardingScreen/OnboardingScreen.storyboard b/frontend/mobile/CommunityMC3/OnboardingScreen/OnboardingScreen.storyboard new file mode 100644 index 0000000..7dffab6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/OnboardingScreen/OnboardingScreen.storyboard @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/OnboardingScreen/item/CarouselItem.swift b/frontend/mobile/CommunityMC3/OnboardingScreen/item/CarouselItem.swift new file mode 100644 index 0000000..9cd81d1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/OnboardingScreen/item/CarouselItem.swift @@ -0,0 +1,36 @@ +import Foundation +import UIKit + +@IBDesignable +class CarouselItem: UIView { + static let CAROUSEL_ITEM_NIB = "CarouselItem" + + @IBOutlet var vwContent: UIView! + @IBOutlet var vwBackground: UIView! + @IBOutlet var lblTitle: UILabel! + + // MARK: - Init + + override init(frame: CGRect) { + super.init(frame: frame) + initWithNib() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + initWithNib() + } + + convenience init(titleText: String? = "", background: UIColor? = .red) { + self.init() + lblTitle.text = titleText + vwBackground.backgroundColor = background + } + + fileprivate func initWithNib() { + Bundle.main.loadNibNamed(CarouselItem.CAROUSEL_ITEM_NIB, owner: self, options: nil) + vwContent.frame = bounds + vwContent.autoresizingMask = [.flexibleHeight, .flexibleWidth] + addSubview(vwContent) + } +} diff --git a/frontend/mobile/CommunityMC3/OnboardingScreen/item/CarouselItem.xib b/frontend/mobile/CommunityMC3/OnboardingScreen/item/CarouselItem.xib new file mode 100644 index 0000000..6ed9179 --- /dev/null +++ b/frontend/mobile/CommunityMC3/OnboardingScreen/item/CarouselItem.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/AccountController.swift b/frontend/mobile/CommunityMC3/Profile View/AccountController.swift new file mode 100644 index 0000000..e7c0e3e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/AccountController.swift @@ -0,0 +1,108 @@ +// +// AccountController.swift +// Allegro +// +// Created by Bryanza on 05/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class AccountController: UIViewController { + + @IBOutlet var switchAccountTable: UITableView! + var accounts: [PrimitiveUserDataStruct]! + + override func viewDidLoad() { + super.viewDidLoad() +// dismissView() + setup() + } + + func setup(){ + + switchAccountTable.register(UINib(nibName: "SwitchAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "switchCell") + switchAccountTable.register(UINib(nibName: "AddAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "addCell") + switchAccountTable.allowsMultipleSelection = true + } + + func dismissView() { + let tap: UITapGestureRecognizer = UITapGestureRecognizer( target: self, action: #selector(dismissViewFunc)) + tap.cancelsTouchesInView = false + view.addGestureRecognizer(tap) + } + + @objc func dismissViewFunc(){ + print("dismissView") + view.endEditing(true) + } + + @IBAction func cancelSwitchAccount(_ sender: UIButton) { + let userProfileVC = UserProfileVC() + userProfileVC.overlayView.removeFromSuperview() + + dismiss(animated: true, completion: nil) + } + +} + +extension AccountController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return accounts.count + 1 + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 100 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if(indexPath.row == accounts.count) + { + let cell = switchAccountTable.dequeueReusableCell(withIdentifier: "addCell") as! AddAccountTableViewCell + cell.addAccountLabel.text = NSLocalizedString("Add Account".uppercased(), comment: "") + return cell + }else{ + let cell = switchAccountTable.dequeueReusableCell(withIdentifier: "switchCell") as! SwitchAccountTableViewCell + cell.switchAccountName.text = accounts[indexPath.row].name + cell.switchAccountRole.text = accounts[indexPath.row].role + if let data = NSData(contentsOf: URL(fileURLWithPath: accounts[indexPath.row].profilePicture)) { + cell.switchAccountImage.image = UIImage(data: data as Data) + } + return cell + } + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if(indexPath.row == accounts.count) + { + self.performSegue(withIdentifier: "addAccount", sender: nil) + }else{ + if accounts[indexPath.row].email != "" && accounts[indexPath.row].email != UserDefaults.standard.string(forKey: "email") { +// DataManager.shared().currentUser?.email = accounts[indexPath.row].email +// DataManager.shared().currentUser?.name = accounts[indexPath.row].name +// DataManager.shared().currentUser?.role = accounts[indexPath.row].role +// if let data = NSData(contentsOf: URL(fileURLWithPath: accounts[indexPath.row].profilePicture)) { +// DataManager.shared().currentUser?.profilePicture = UIImage(data: data as Data) +// } + UserDefaults.standard.set(accounts[indexPath.row].email, forKey: "email") + UserDefaults.standard.set(accounts[indexPath.row].password, forKey: "password") + UserDefaults.standard.synchronize() + let data:[String: Bool] = ["data": true] + NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: data) + } + if let loadEmail = UserDefaults.standard.string(forKey: "email"){ + print("changed", loadEmail) +// let userProfileVC = storyboard?.instantiateViewController(withIdentifier: "ProfileStoryboard") as! UserProfileVC + // let userProfileVC = UserProfileVC.shared +// userProfileVC.userNameLabel.text = loadEmail + } + let userProfileVC = UserProfileVC() + userProfileVC.overlayView.removeFromSuperview() + + + dismiss(animated: true, completion: nil) + } + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/CarouselPageViewController.swift b/frontend/mobile/CommunityMC3/Profile View/CarouselPageViewController.swift new file mode 100644 index 0000000..a6dbe25 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/CarouselPageViewController.swift @@ -0,0 +1,80 @@ +// +// CarouselPageViewController.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class CarouselPageViewController: UIPageViewController { + + lazy var items: [UIViewController] = { + let sb = UIStoryboard(name: "UserProfileView", bundle: nil) + + let vc1 = sb.instantiateViewController(withIdentifier: "secondPageView") + let vc2 = sb.instantiateViewController(withIdentifier: "firstPageView") + + return [vc1, vc2] + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.dataSource = nil + self.delegate = nil + + } + + func moveToPage(index:Int) + { + setViewControllers([items[index]], direction: .forward, animated: true, completion: nil) + } +} + +// MARK: - DataSource +extension CarouselPageViewController: UIPageViewControllerDataSource { + func pageViewController(_: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = items.firstIndex(of: viewController) else { + return nil + } + + let previousIndex = viewControllerIndex - 1 + + guard previousIndex >= 0 else { + return items.last + } + + guard items.count > previousIndex else { + return nil + } + + return items[previousIndex] + } + + func pageViewController(_: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = items.firstIndex(of: viewController) else { + return nil + } + + let nextIndex = viewControllerIndex + 1 + guard items.count != nextIndex else { + return items.first + } + + guard items.count > nextIndex else { + return nil + } + + return items[nextIndex] + } + + func presentationIndex(for _: UIPageViewController) -> Int { + guard let firstViewController = viewControllers?.first, + let firstViewControllerIndex = items.firstIndex(of: firstViewController) else { + return 0 + } + + return firstViewControllerIndex + } +} diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/AboutHeaderCell.swift b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/AboutHeaderCell.swift new file mode 100644 index 0000000..6109152 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/AboutHeaderCell.swift @@ -0,0 +1,26 @@ +// +// AboutHeaderCell.swift +// CommunityMC3 +// +// Created by Theofani on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class AboutHeaderCell: UITableViewCell { + + @IBOutlet weak var aboutHeaderLabel: UILabel! + override func awakeFromNib() { + super.awakeFromNib() + aboutHeaderLabel.adjustsFontSizeToFitWidth = true + + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/AboutHeaderCell.xib b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/AboutHeaderCell.xib new file mode 100644 index 0000000..cb5f399 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/AboutHeaderCell.xib @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Contact Information/ContactInfoCell.swift b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Contact Information/ContactInfoCell.swift new file mode 100644 index 0000000..b426410 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Contact Information/ContactInfoCell.swift @@ -0,0 +1,25 @@ +// +// ContactInfoCell.swift +// CommunityMC3 +// +// Created by Theofani on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ContactInfoCell: UITableViewCell { + + @IBOutlet weak var phoneNumberLabel: UILabel! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Contact Information/ContactInfoCell.xib b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Contact Information/ContactInfoCell.xib new file mode 100644 index 0000000..37590c5 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Contact Information/ContactInfoCell.xib @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/FirstPageVC.swift b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/FirstPageVC.swift new file mode 100644 index 0000000..5db9f11 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/FirstPageVC.swift @@ -0,0 +1,116 @@ +// +// FirstPageVC.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +enum AboutSection:Int{ + case MusicGenre = 0 + case ContactInfo = 1 + case SocialMedia = 2 + case Count = 3 +} + +class FirstPageVC: UIViewController { + + @IBOutlet weak var aboutTableView: UITableView! + + var genreLabel:String! + var phoneNumberLabel:String! + var socialMediaLabel:String! + + override func viewDidLoad() { + super.viewDidLoad() + + aboutTableView.register(UINib(nibName: "AboutHeaderCell", bundle: nil), forCellReuseIdentifier: "aboutHeaderCell") + aboutTableView.register(UINib(nibName: "MusicGenreInfoCell", bundle: nil), forCellReuseIdentifier: "musicGenreInfoCell") + aboutTableView.register(UINib(nibName: "ContactInfoCell", bundle: nil), forCellReuseIdentifier: "contactInfoCell") + aboutTableView.register(UINib(nibName: "SocialMediaCell", bundle: nil), forCellReuseIdentifier: "socialMediaCell") + aboutTableView.isUserInteractionEnabled = false + + } + + func updateData(genre:String, + phoneNumber:String, + socialMedia:String) + { + self.genreLabel = genre + self.phoneNumberLabel = phoneNumber + self.socialMediaLabel = socialMedia + + if(aboutTableView != nil) + { + aboutTableView.reloadData() + } + } +} + +extension FirstPageVC: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let cell = aboutTableView.dequeueReusableCell(withIdentifier: "aboutHeaderCell") as! AboutHeaderCell + if(section == AboutSection.MusicGenre.rawValue) + { + cell.aboutHeaderLabel.text = NSLocalizedString("Genre Preferences".uppercased(), comment: "") + } + if(section == AboutSection.ContactInfo.rawValue) + { + cell.aboutHeaderLabel.text = NSLocalizedString("Contact Info".uppercased(), comment: "") + } + if(section == AboutSection.SocialMedia.rawValue) + { + cell.aboutHeaderLabel.text = NSLocalizedString("Social Media".uppercased(), comment: "") + } + return cell + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + 40 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + func numberOfSections(in tableView: UITableView) -> Int { + return AboutSection.Count.rawValue + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if(indexPath.section == AboutSection.MusicGenre.rawValue) + { + let cell = aboutTableView.dequeueReusableCell(withIdentifier: "musicGenreInfoCell") as! MusicGenreInfoCell + + return cell + } + if(indexPath.section == AboutSection.ContactInfo.rawValue) + { + let cell = aboutTableView.dequeueReusableCell(withIdentifier: "contactInfoCell") as! ContactInfoCell + cell.phoneNumberLabel.text = phoneNumberLabel + return cell + } + if(indexPath.section == AboutSection.SocialMedia.rawValue) + { + let cell = aboutTableView.dequeueReusableCell(withIdentifier: "socialMediaCell") as! SocialMediaCell + cell.socialAccountLabel.text = socialMediaLabel + return cell + } + + return aboutTableView.dequeueReusableCell(withIdentifier: "musicGenreInfoCell")! + } + + func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return 20 + } + + func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + let footerView = UIView() + let footerChildView = UIView(frame: CGRect(x: 60, y: 0, width: tableView.frame.width - 60, height: 0.5)) + // footerChildView.backgroundColor = UIColor.darkGray + footerView.addSubview(footerChildView) + return footerView + } +} diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Music Genre/MusicGenreInfoCell.swift b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Music Genre/MusicGenreInfoCell.swift new file mode 100644 index 0000000..4d70a16 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Music Genre/MusicGenreInfoCell.swift @@ -0,0 +1,43 @@ +// +// MusicGenreCell.swift +// CommunityMC3 +// +// Created by Theofani on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class MusicGenreInfoCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource { + + @IBOutlet weak var collectionView: UICollectionView! + + var musicGenreArray = ["Rock","Jazz","Pop","RnB","Acoustic","Blues"] + + override func awakeFromNib() { + super.awakeFromNib() + + self.collectionView.delegate = self + self.collectionView.dataSource = self + self.collectionView.register(UINib(nibName: "MusicGenreCell", bundle: nil), forCellWithReuseIdentifier: "genreCell") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 3 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "genreCell", for: indexPath) as! MusicGenreCell + + cell.musicGenreLabel.text = musicGenreArray[indexPath.row] + setupUIViewForGenre(view: cell, genre: musicGenreArray[indexPath.row]) + + return cell + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Music Genre/MusicGenreInfoCell.xib b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Music Genre/MusicGenreInfoCell.xib new file mode 100644 index 0000000..e3448c3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Music Genre/MusicGenreInfoCell.xib @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Social Media/SocialMediaCell.swift b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Social Media/SocialMediaCell.swift new file mode 100644 index 0000000..663cd9a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Social Media/SocialMediaCell.swift @@ -0,0 +1,25 @@ +// +// SocialMediaCell.swift +// CommunityMC3 +// +// Created by Theofani on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class SocialMediaCell: UITableViewCell { + + @IBOutlet weak var socialAccountLabel: UILabel! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Social Media/SocialMediaCell.xib b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Social Media/SocialMediaCell.xib new file mode 100644 index 0000000..6a2d220 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/FirstPage Content/Social Media/SocialMediaCell.xib @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell 2.xib b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell 2.xib new file mode 100644 index 0000000..cde995d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell 2.xib @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell.swift new file mode 100644 index 0000000..175b85d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell.swift @@ -0,0 +1,35 @@ +// +// MusicTableViewCell.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class MusicTableViewCell: UITableViewCell { + + @IBOutlet weak var trackPlayButton: UIImageView! + @IBOutlet weak var trackTitleLabel: UILabel! +// @IBOutlet weak var artistNameLabel: UILabel! + var callback:(()->Void)! = nil + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + func updateData(track:TrackDataStruct) + { + trackTitleLabel.text = track.name +// artistNameLabel.text = DataManager.shared().currentUser?.name + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell.xib b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell.xib new file mode 100644 index 0000000..8bcea26 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/MusicTableViewCell.xib @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicVC.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicVC.swift new file mode 100644 index 0000000..7038c96 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicVC.swift @@ -0,0 +1,53 @@ +// +// ShowcaseMusicVC.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ShowcaseMusicVC: UIViewController { + + @IBOutlet weak var showcaseMusicTable: UITableView! + var tracksData:[TrackDataStruct]?=[] + override func viewDidLoad() { + super.viewDidLoad() + + showcaseMusicTable.register(UINib(nibName: "MusicTableViewCell", bundle:nil), forCellReuseIdentifier: "musicTableCell") + + } + + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "trackPlayerSegue" + { + if let vc = segue.destination as? TrackPlayerViewController + { + vc.track = sender as? TrackDataStruct + } + } + } +} + +extension ShowcaseMusicVC: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return tracksData!.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = showcaseMusicTable.dequeueReusableCell(withIdentifier: "musicTableCell") as! MusicTableViewCell + cell.updateData(track: tracksData![indexPath.row]) + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + self.performSegue(withIdentifier: "trackPlayerSegue", sender: tracksData![indexPath.row]) + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicView 2.storyboard b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicView 2.storyboard new file mode 100644 index 0000000..f9a048e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicView 2.storyboard @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicView.storyboard b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicView.storyboard new file mode 100644 index 0000000..30e0863 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Music/ShowcaseMusicView.storyboard @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionCell.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionCell.swift new file mode 100644 index 0000000..2d91d1d --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionCell.swift @@ -0,0 +1,19 @@ +// +// PhotosCollectionCell.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class PhotosCollectionCell: UICollectionViewCell { + + @IBOutlet weak var photosCollectionImage: UIImageView! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionCell.xib b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionCell.xib new file mode 100644 index 0000000..a6da9b8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionCell.xib @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionViewCell 2.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionViewCell 2.swift new file mode 100644 index 0000000..72f83b9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionViewCell 2.swift @@ -0,0 +1,18 @@ +// +// PhotosCollectionViewCell.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class PhotosCollectionViewCell: UICollectionViewCell { + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionViewCell 2.xib b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionViewCell 2.xib new file mode 100644 index 0000000..863385f --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosCollectionViewCell 2.xib @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosTableViewCell.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosTableViewCell.swift new file mode 100644 index 0000000..661074e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosTableViewCell.swift @@ -0,0 +1,49 @@ +// +// PhotosTableViewCell.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class PhotosTableViewCell: UITableViewCell { + + + @IBOutlet weak var photosCollectionCell: UICollectionView! + + var photosData:[PhotoDataStruct]? = nil + + override func awakeFromNib() { + super.awakeFromNib() + self.photosCollectionCell.dataSource = self + self.photosCollectionCell.delegate = self + self.photosCollectionCell.register(UINib.init(nibName: "PhotosCollectionCell", bundle: nil), forCellWithReuseIdentifier: "photosCollectionCell") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + func updateData(photosData:[PhotoDataStruct]) + { + self.photosData = photosData + } +} + +extension PhotosTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return min(5, photosData!.count) + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = photosCollectionCell.dequeueReusableCell(withReuseIdentifier: "photosCollectionCell", for: indexPath as IndexPath) as! PhotosCollectionCell + cell.photosCollectionImage.image = photosData![indexPath.row].photosData! + return cell + } + + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosTableViewCell.xib b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosTableViewCell.xib new file mode 100644 index 0000000..4233ce6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/PhotosTableViewCell.xib @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosVC.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosVC.swift new file mode 100644 index 0000000..ab5f530 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosVC.swift @@ -0,0 +1,41 @@ +// +// ShowcasePhotosVC.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ShowcasePhotosVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { + + var photoData:[PhotoDataStruct]? = nil + + @IBOutlet weak var showcasePhotosCollectionView: UICollectionView! + + override func viewDidLoad() { + super.viewDidLoad() + self.showcasePhotosCollectionView.register(UINib.init(nibName: "PhotosCollectionCell", bundle: nil), forCellWithReuseIdentifier: "photosCollectionCell") + + let layout = UICollectionViewFlowLayout() + layout.itemSize = CGSize(width: 200, height: 200) + showcasePhotosCollectionView.collectionViewLayout = layout + + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 5 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = showcasePhotosCollectionView.dequeueReusableCell(withReuseIdentifier: "photosCollectionCell", for: indexPath as IndexPath) as! PhotosCollectionCell + + return cell + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: 200, height: 200) + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosView 2.storyboard b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosView 2.storyboard new file mode 100644 index 0000000..f9a048e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosView 2.storyboard @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosView.storyboard b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosView.storyboard new file mode 100644 index 0000000..4a6e32a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Photos/ShowcasePhotosView.storyboard @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/SecondPageVC.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/SecondPageVC.swift new file mode 100644 index 0000000..e477edb --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/SecondPageVC.swift @@ -0,0 +1,176 @@ +// +// SecondPageVC.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +enum ShowcaseSection:Int{ + case Music = 0 + case Photos = 1 + case Videos = 2 + case Count = 3 +} + +class SecondPageVC: UIViewController { + + @IBOutlet weak var showcaseTableView: UITableView! + + var showcaseMusicSegue: (() -> Void)? = nil + var showcasePhotoSegue: (() -> Void)? = nil + var showcaseVideoSegue: (() -> Void)? = nil + var playMusicSegue: ((Any?) -> Void)? = nil + var playVideoSegue: ((Any?) -> Void)? = nil + + + var tracks:[TrackDataStruct]? = [] + var videos:[VideosDataStruct]? = [] + var photos:[PhotoDataStruct]? = [] + + override func viewDidLoad() { + super.viewDidLoad() + + showcaseTableView.register(UINib(nibName: "ShowcaseHeaderCell", bundle:nil), forCellReuseIdentifier: "showcaseHeaderCell") + showcaseTableView.register(UINib(nibName: "MusicTableViewCell", bundle: nil), forCellReuseIdentifier: "musicTableCell") + showcaseTableView.register(UINib(nibName: "PhotosTableViewCell", bundle: nil), forCellReuseIdentifier: "photosTableCell") + showcaseTableView.register(UINib(nibName: "VideosTableViewCell", bundle: nil), forCellReuseIdentifier: "videosTableCell") + } + + func updateData(tracks:[TrackDataStruct]?, videos:[VideosDataStruct]?, photos:[PhotoDataStruct]?) + { + self.tracks = tracks + self.videos = videos + self.photos = photos + + print("showcase T:\(tracks!.count) V:\(videos!.count) P:\(photos!.count)") + if(showcaseTableView != nil) + { + showcaseTableView.reloadData() + } + + } + +} + +extension SecondPageVC: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let cell = showcaseTableView.dequeueReusableCell(withIdentifier: "showcaseHeaderCell") as! ShowcaseHeaderCell + if(section == ShowcaseSection.Music.rawValue) + { + cell.showcaseSectionHeader.text = NSLocalizedString("Music".uppercased(), comment: "") + cell.callBack = { + self.showcaseMusicSegue!() + } + } + if(section == ShowcaseSection.Photos.rawValue) + { + cell.showcaseSectionHeader.text = NSLocalizedString("Photos".uppercased(), comment: "") + cell.callBack = { + self.showcasePhotoSegue!() + } + } + if(section == ShowcaseSection.Videos.rawValue) + { + cell.showcaseSectionHeader.text = NSLocalizedString("Videos".uppercased(), comment: "") + cell.callBack = { + self.showcaseVideoSegue!() + } + } + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if(indexPath.section == ShowcaseSection.Music.rawValue) + { +// playMusicSegue!(tracks![indexPath.row]) + TrackManager.shared.play(trackData: tracks![indexPath.row]) + } + if(indexPath.section == ShowcaseSection.Videos.rawValue) + { +// playVideoSegue!(videos![indexPath.row]) + TrackManager.shared.playVideo(view: self, videoData: videos![indexPath.row]) + } + + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + 40 + } + + func numberOfSections(in tableView: UITableView) -> Int { + return ShowcaseSection.Count.rawValue + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if(section == ShowcaseSection.Music.rawValue) + { + return min(tracks!.count,3) + } + if(section == ShowcaseSection.Photos.rawValue) + { + return 1 + } + if(section == ShowcaseSection.Videos.rawValue) + { + return min(videos!.count,3) + } + return 0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if(indexPath.section == ShowcaseSection.Music.rawValue) + { + let cell = showcaseTableView.dequeueReusableCell(withIdentifier: "musicTableCell") as! MusicTableViewCell + cell.updateData(track: tracks![indexPath.row]) + return cell + } + if(indexPath.section == ShowcaseSection.Photos.rawValue) + { + let cell = showcaseTableView.dequeueReusableCell(withIdentifier: "photosTableCell") as! PhotosTableViewCell + cell.updateData(photosData: photos!) + return cell + } + if(indexPath.section == ShowcaseSection.Videos.rawValue) + { + let cell = showcaseTableView.dequeueReusableCell(withIdentifier: "videosTableCell") as! VideosTableViewCell + cell.update(videoData: videos![indexPath.row]) + return cell + } + + return showcaseTableView.dequeueReusableCell(withIdentifier: "musicTableCell")! + + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if(indexPath.section == ShowcaseSection.Music.rawValue) + { + return 48 + } + if(indexPath.section == ShowcaseSection.Photos.rawValue) + { + return 220 + } + if(indexPath.section == ShowcaseSection.Videos.rawValue) + { + return 180 + } + return 36 + } + + func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return 20 + } + + func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + let footerView = UIView() + let footerChildView = UIView(frame: CGRect(x: 60, y: 0, width: tableView.frame.width - 60, height: 0.5)) + // footerChildView.backgroundColor = UIColor.darkGray + footerView.addSubview(footerChildView) + return footerView + } + + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell 2.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell 2.swift new file mode 100644 index 0000000..3001758 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell 2.swift @@ -0,0 +1,36 @@ +// +// ShowcaseTableCell.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ShowcaseHeaderCell: UITableViewCell { + + @IBOutlet weak var showcaseSectionHeader: UILabel! + @IBOutlet weak var seeAllButton: UIButton! + + var callBack: (() -> Void)? = nil + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + @IBAction func tapSeeAll(_ sender: Any) { + self.callBack!() + } + + func setCallBack(callback: (() -> Void)?){ + self.callBack = callback + } +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell.swift new file mode 100644 index 0000000..b1a2cff --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell.swift @@ -0,0 +1,36 @@ +// +// ShowcaseTableCell.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ShowcaseHeaderCell: UITableViewCell { + + @IBOutlet weak var showcaseSectionHeader: UILabel! + @IBOutlet weak var seeAllButton: UIButton! + + var callBack: (() -> Void)? = nil + + override func awakeFromNib() { + super.awakeFromNib() + showcaseSectionHeader.adjustsFontSizeToFitWidth = true + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + @IBAction func tapSeeAll(_ sender: Any) { + self.callBack!() + } + + func setCallBack(callback: (() -> Void)?){ + self.callBack = callback + } +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell.xib b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell.xib new file mode 100644 index 0000000..d15e899 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/ShowcaseHeaderCell.xib @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideoView.storyboard b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideoView.storyboard new file mode 100644 index 0000000..7b7d363 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideoView.storyboard @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideosVC 2.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideosVC 2.swift new file mode 100644 index 0000000..4fd2cd0 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideosVC 2.swift @@ -0,0 +1,30 @@ +// +// ShowcaseVideosVC.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ShowcaseVideosVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideosVC.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideosVC.swift new file mode 100644 index 0000000..94fbae6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/ShowcaseVideosVC.swift @@ -0,0 +1,48 @@ +// +// ShowcaseVideosVC.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ShowcaseVideosVC: UIViewController { + + @IBOutlet weak var showcaseVideoTableView: UITableView! + + var videoData:[VideosDataStruct]? = nil + override func viewDidLoad() { + super.viewDidLoad() + + showcaseVideoTableView.register(UINib(nibName: "VideosTableViewCell", bundle:nil), forCellReuseIdentifier: "videosTableCell") + + } + +} + +extension ShowcaseVideosVC: UITableViewDataSource, UITableViewDelegate { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if(videoData != nil) + { + return videoData!.count + } + return 10 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = showcaseVideoTableView.dequeueReusableCell(withIdentifier: "videosTableCell") as! VideosTableViewCell + cell.update(videoData: videoData![indexPath.row]) + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 200 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + TrackManager.shared.playVideo(view: self, videoData: videoData![indexPath.row]) + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell 2.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell 2.swift new file mode 100644 index 0000000..6892524 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell 2.swift @@ -0,0 +1,24 @@ +// +// VideosTableViewCell.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class VideosTableViewCell: UITableViewCell { + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell.swift b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell.swift new file mode 100644 index 0000000..2f65f95 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell.swift @@ -0,0 +1,32 @@ +// +// VideosTableViewCell.swift +// CommunityMC3 +// +// Created by Theofani on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class VideosTableViewCell: UITableViewCell { + + @IBOutlet weak var videoThumbnailView: UIImageView! + override func awakeFromNib() { + super.awakeFromNib() + videoThumbnailView.layer.cornerRadius = 15 + } + + func update(videoData:VideosDataStruct) + { + videoThumbnailView.image = videoData.coverImage + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell.xib b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell.xib new file mode 100644 index 0000000..cf8daaa --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SecondPage Content/Videos/VideosTableViewCell.xib @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/AddAccountTableViewCell.swift b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/AddAccountTableViewCell.swift new file mode 100644 index 0000000..2599191 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/AddAccountTableViewCell.swift @@ -0,0 +1,26 @@ +// +// AddAccountTableViewCell.swift +// Allegro +// +// Created by Bryanza on 05/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class AddAccountTableViewCell: UITableViewCell { + + @IBOutlet weak var addAccountLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/AddAccountTableViewCell.xib b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/AddAccountTableViewCell.xib new file mode 100644 index 0000000..a2f860c --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/AddAccountTableViewCell.xib @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/SwitchAccountTableViewCell.swift b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/SwitchAccountTableViewCell.swift new file mode 100644 index 0000000..874902b --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/SwitchAccountTableViewCell.swift @@ -0,0 +1,28 @@ +// +// SwitchAccountTableViewCell.swift +// Allegro +// +// Created by Bryanza on 05/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class SwitchAccountTableViewCell: UITableViewCell { + + @IBOutlet weak var switchAccountImage: UIImageView! + @IBOutlet weak var switchAccountName: UILabel! + @IBOutlet weak var switchAccountRole: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/SwitchAccountTableViewCell.xib b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/SwitchAccountTableViewCell.xib new file mode 100644 index 0000000..ac31644 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/SwitchAccountTableView/SwitchAccountTableViewCell.xib @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelCell.swift b/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelCell.swift new file mode 100644 index 0000000..bbb0f7a --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelCell.swift @@ -0,0 +1,27 @@ +// +// UploadPanelCell.swift +// Allegro +// +// Created by Rommy Julius Dwidharma on 04/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class UploadPanelCell: UITableViewCell { + + @IBOutlet weak var panelIconImage: UIImageView! + @IBOutlet weak var panelLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelCell.xib b/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelCell.xib new file mode 100644 index 0000000..cd942a8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelCell.xib @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelViewController.swift b/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelViewController.swift new file mode 100644 index 0000000..19bde85 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/UploadPanel/UploadPanelViewController.swift @@ -0,0 +1,108 @@ +// +// UploadPanelViewController.swift +// Allegro +// +// Created by Rommy Julius Dwidharma on 04/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class UploadPanelViewController: UIViewController { + + @IBOutlet weak var tableView: UITableView! + + var optionList = ["Audio", "Photo","Video"] + var iconList = ["audioIcon", "imageIcon", "videoIcon"] + var imgPicker:ImagePicker? + var isUploadVideo = false + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + func setupView(){ + tableView.register(UINib(nibName: "UploadPanelCell", bundle: nil), forCellReuseIdentifier: "uploadPanelCell") + imgPicker = ImagePicker(presentationController: self, delegate: self) + } + + + @IBAction func cancelButtonAction(_ sender: UIButton) { + let userProfileVC = UserProfileVC() + userProfileVC.overlayView.removeFromSuperview() + + dismiss(animated: true, completion: nil) + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "selectFileSegue" + { + let selectVC = segue.destination as! SelectFileView + selectVC.isUploadVideo = isUploadVideo + } + } +} + +extension UploadPanelViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return optionList.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "uploadPanelCell", for: indexPath) as! UploadPanelCell + cell.panelLabel.text = optionList[indexPath.row] + cell.panelIconImage.image = UIImage(imageLiteralResourceName: iconList[indexPath.row]) + + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 100 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.row == 0{ + self.isUploadVideo = false + self.performSegue(withIdentifier: "selectFileSegue", sender: nil) + }else if indexPath.row == 1{ + self.imgPicker?.present(from: self.view) + }else if indexPath.row == 2{ + self.isUploadVideo = true + performSegue(withIdentifier: "selectFileSegue", sender: nil) + } + } + +} +extension UploadPanelViewController: ImagePickerDelegate{ + func didSelect(image: UIImage?) + { +// coverImage?.image = image + var photoData = PhotoDataStruct() + photoData.email = DataManager.shared().currentUser?.email! + photoData.photosData = image + + DataManager.shared().UploadNewPhoto(photoData:photoData) { (isSuccess, errorString) in + if isSuccess + { + print("Upload Photo File Success") + + +// self.dismiss(animated: true, completion: nil) + DispatchQueue.main.async { + self.view.window!.rootViewController?.dismiss(animated: true, completion: nil) + } + AlertViewHelper.createAlertView(type: .OK, rightHandler:nil, leftHandler: nil, replacementString: [strKeyOK_MSG:"Upload Photo File Success"]) + + + } + else + { + print("Upload Photo File Failed") + AlertViewHelper.creteErrorAlert(errorString: "Upload Photo File Failed \(errorString)", view: self) + } + } + } +} diff --git a/frontend/mobile/CommunityMC3/Profile View/UserProfileVC.swift b/frontend/mobile/CommunityMC3/Profile View/UserProfileVC.swift new file mode 100644 index 0000000..31236a6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/UserProfileVC.swift @@ -0,0 +1,498 @@ +// +// UserProfileVC.swift +// CommunityMC3 +// +// Created by Theofani on 24/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class UserProfileVC: UIViewController { + + @IBOutlet weak var profileNavigationItem: UINavigationItem! + @IBOutlet weak var viewContainer: UIView! + @IBOutlet weak var firstTabButton: UIButton! + @IBOutlet weak var secondTabButton: UIButton! + @IBOutlet weak var followButton: UIButton! + @IBOutlet weak var contactButton: UIButton! + @IBOutlet weak var otherMenu: UIBarButtonItem! + @IBOutlet weak var uploadMediaButton: UIButton! + @IBOutlet weak var customNavigationBar: UINavigationBar! +var isNeedUpdate:Bool = false + + var isPersonalProfile:Bool = true + + var userData:UserDataStruct? + + var cVC:CarouselPageViewController? + + var showcaseVC:SecondPageVC? + + var aboutVC:FirstPageVC? + var signOutCallback:(()->Void)? = nil + + + var isUploadVideo = false + var phoneNumber = "087875732888" + + @IBOutlet weak var menuButton: UIBarButtonItem! + @IBOutlet weak var userNameLabel: UILabel! + @IBOutlet weak var userRoleLabel: UILabel! + @IBOutlet weak var totalFollowersLabel: UILabel! + @IBOutlet weak var profilePictureImage: UIImageView! + + var actionSheet:UIAlertController = UIAlertController(title: "", message: "", preferredStyle: .actionSheet) + + var actionSheetToCall: UIAlertController = UIAlertController(title: "Contact Me", message: "", preferredStyle: .actionSheet) + + let userDefault = UserDefaults.standard + + var imgPicker:ImagePicker? + + let overlayView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)) + + override func viewDidLoad() { + super.viewDidLoad() + + NotificationCenter.default.addObserver(self, selector: #selector(listnerFunction(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil) + imgPicker = ImagePicker(presentationController: self, delegate: self) + loadLocalisation() + followButton.layer.cornerRadius = 10 + contactButton.layer.cornerRadius = 10 + setupActionSheet() + setupActionSheetToCall() + + // Do any additional setup after loading the view. + firstTabButton.alpha = 1 + secondTabButton.alpha = 0.5 + cVC?.moveToPage(index: 0) + + followButton.isHidden = isPersonalProfile + contactButton.isHidden = isPersonalProfile + uploadMediaButton.isHidden = !isPersonalProfile + + if(!isPersonalProfile) + { + otherMenu.image = UIImage(color: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 0)) + otherMenu.isEnabled = false + } + else + { + otherMenu.image = UIImage(systemName: "ellipsis") + otherMenu.isEnabled = true + } + // loadNavigationBar() + } + + @objc func listnerFunction(_ notification: NSNotification) { + if let data = notification.userInfo?["data"] as? Bool { + if data { + updateLayout() + let temp:[String: Bool] = ["data": false] + NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: temp) + } + } + } + /* + func loadNavigationBar() { + let navbar = UINavigationBar(frame: CGRect(x: 0, y: 0, + width: UIScreen.main.bounds.size.width, height: 50)) + navbar.tintColor = .lightGray + self.view.addSubview(navbar) + navbar.items = [profileNavigationItem] + } + */ + + func loadLocalisation() { + followButton.titleLabel?.text = NSLocalizedString("Follow".uppercased(), comment: "") + contactButton.titleLabel?.text = NSLocalizedString("Contact".uppercased(), comment: "") + firstTabButton.titleLabel?.text = NSLocalizedString("Showcase".uppercased(), comment: "") + secondTabButton.titleLabel?.text = NSLocalizedString("About", comment: "") + } + + @IBAction func contactButtonTouched(_ sender: Any) { + self.present(actionSheetToCall, animated: true, completion: nil) + + } + + @IBAction func uploadMediaButtonTouched(_ sender: UIButton) { + + let uploadPanelVC = storyboard?.instantiateViewController(identifier: "UploadPanelView") as! UploadPanelViewController + uploadPanelVC.transitioningDelegate = self + uploadPanelVC.modalPresentationStyle = .custom + uploadPanelVC.modalTransitionStyle = .coverVertical + uploadPanelVC.view.layer.cornerRadius = 34 + + // performSegue(withIdentifier: "uploadPanel", sender: self) + self.present(uploadPanelVC, animated: true, completion: nil) + } + + + func updateLayout() + { + + + // userData = UserDataStruct(DataManager.shared().currentUserRec!) + if isPersonalProfile == true + { + userData = DataManager.shared().currentUser + } + print("Name :\(userData!.name!)") + + userNameLabel.text = userData?.name + userRoleLabel.text = userData?.role + totalFollowersLabel.text = "\(userData!.followerCount!) followers" + totalFollowersLabel.isHidden = !(userData!.isArtist) + profilePictureImage.image = userData?.profilePicture + + + + + // about VC + aboutVC?.updateData( + genre: userData!.genre!, + phoneNumber: userData!.phoneNumber!, + socialMedia: userData!.instagram! + ) + + // showcase VC + showcaseVC?.updateData(tracks: userData?.musics, + videos: userData?.videos, + photos: userData?.photos) + + } + + @IBAction func unwindToUserProfile(_ segue:UIStoryboardSegue) + { + print("UNWIND to Profile \(segue.identifier) \(segue.destination)") + updateLayout() + } + + override func viewDidAppear(_ animated: Bool) { + + + super.viewDidAppear(animated) + + + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "container" + { + print("containerSegue") + cVC = (segue.destination as! CarouselPageViewController) + } + else if segue.identifier == "selectFileSegue" + { + let selectVC = segue.destination as! SelectFileView + selectVC.isUploadVideo = isUploadVideo + } + else if segue.identifier == "editProfileSegue" + { + let vc = segue.destination as! SettingController + vc.isEditProfile = true + } + else if segue.identifier == "trackPlayerSegue" { + if let trackPlayerPage = segue.destination as? TrackPlayerViewController { + trackPlayerPage.track = sender as? TrackDataStruct + } + } + else if segue.identifier == "videoPlayerSegue" { + if let videoPlayerPage = segue.destination as? VideoPlayerViewController + { + videoPlayerPage.video = sender as? VideosDataStruct + } + } + else if segue.identifier == "showcaseMusicSegue" + { + if let smVC = segue.destination as? ShowcaseMusicVC + { + smVC.tracksData = userData?.musics + } + } + else if segue.identifier == "showcaseVideoSegue" + { + if let smVC = segue.destination as? ShowcaseVideosVC + { + smVC.videoData = userData?.videos + } + } + else if segue.identifier == "showcasePhotoSegue" + { + if let smVC = segue.destination as? ShowcasePhotosVC + { + smVC.photoData = userData?.photos + } + } + } + + func signOut(action:UIAlertAction) + { + let alert = AlertViewHelper.createAlertView(type: .SignOut, + rightHandler: { (yesAction) in + DataManager.shared().logout() + self.performSegue(withIdentifier: "unwindToExplorerView", sender: nil) + // signOutCallback!() + // self.performSegue(withIdentifier: "logoutUser", sender: nil) + }, + leftHandler: nil, + replacementString: [:]) + present(alert, animated: true, completion: nil) + } + + func setupActionSheet() + { + + + let signOutAction = UIAlertAction(title: NSLocalizedString("Sign Out", comment: ""), style: .destructive, handler: signOut) + actionSheet.addAction(signOutAction) + + let editAction = UIAlertAction(title: NSLocalizedString("Edit".uppercased(), comment: ""), style: .default, + handler: { + action in + self.performSegue(withIdentifier: "editProfileSegue", sender: nil) } + ) + actionSheet.addAction(editAction) + + let switchAccountAction = UIAlertAction(title: NSLocalizedString("Switch Account".uppercased(), comment: ""), style: .default) { (action) in + let switchAccountVC = self.storyboard?.instantiateViewController(identifier: "SwitchAccountVC") as! AccountController + if DataManager.shared().currentUsersPrimitive == nil { + if let loadEmail = self.userDefault.string(forKey: "email"){ + if let loadPassword = self.userDefault.string(forKey: "password"){ + DataManager.shared().currentUsersPrimitive = [PrimitiveUserDataStruct]() + DataManager.shared().registerPrimitiveUserData(email: loadEmail, password: loadPassword, userData: DataManager.shared().currentUser!) + } + } + } + switchAccountVC.accounts = DataManager.shared().currentUsersPrimitive + switchAccountVC.transitioningDelegate = self + switchAccountVC.modalPresentationStyle = .custom + switchAccountVC.modalTransitionStyle = .coverVertical + switchAccountVC.view.layer.cornerRadius = 34 + + self.present(switchAccountVC, animated: true, completion: nil) + } + actionSheet.addAction(switchAccountAction) + + /* + let shareAction = UIAlertAction(title: NSLocalizedString("Share".uppercased(), comment: ""), style: .default) + actionSheet.addAction(shareAction) + + let uploadMusic = UIAlertAction(title: NSLocalizedString("Upload Music".uppercased(), comment: ""), style: .default, + handler: { + action in + self.isUploadVideo = false + self.performSegue(withIdentifier: "selectFileSegue", sender: nil) } + ) + actionSheet.addAction(uploadMusic) + + let uploadVideo = UIAlertAction(title: NSLocalizedString("Upload Video".uppercased(), comment: ""), style: .default, + handler: { + action in + self.isUploadVideo = true + self.performSegue(withIdentifier: "selectFileSegue", sender: nil) } + ) + actionSheet.addAction(uploadVideo) + + let uploadPhotos = UIAlertAction(title: NSLocalizedString("Upload Photos".uppercased(), comment: ""), style: .default, + handler: { + action in + self.imgPicker?.present(from: self.view) } + ) + actionSheet.addAction(uploadPhotos) + */ + + let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) + actionSheet.addAction(cancelAction) + } + + func setupActionSheetToCall(){ + let callAction = UIAlertAction(title: "Make a Phone Call", style: .default, handler: { action in callPhoneNumber(phoneNumber: self.userData!.phoneNumber!) + + }) + actionSheetToCall.addAction(callAction) + + let openInstagramAction = UIAlertAction(title: "Open Instagram", style: .default, handler: { + action in openInstagram(username: self.userData!.instagram!) + }) + actionSheetToCall.addAction(openInstagramAction) + + let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) + actionSheetToCall.addAction(cancelAction) + } + + @objc func returnToExplorerView() + { + performSegue(withIdentifier: "unwindFromUserProfile", sender: nil) + } + + override func viewWillAppear(_ animated: Bool) { + + if(navigationController != nil) + { + customNavigationBar.isHidden = true + navigationController?.setNavigationBarHidden(false, animated: false) + navigationController?.navigationBar.isTranslucent = false + navigationController?.navigationBar.shadowImage = UIImage(color: .white, size: CGSize(width: 1, height: 1)) + + } + else + { + customNavigationBar.isHidden = false + } + + + aboutVC = cVC!.items[1] as? FirstPageVC + + showcaseVC = cVC!.items[0] as? SecondPageVC + showcaseVC?.showcaseVideoSegue = { + self.performSegue(withIdentifier: "showcaseVideoSegue", sender: nil) + } + showcaseVC?.showcasePhotoSegue = { + self.performSegue(withIdentifier: "showcasePhotoSegue", sender: nil) + } + showcaseVC?.showcaseMusicSegue = { + self.performSegue(withIdentifier: "showcaseMusicSegue", sender: nil) + } + showcaseVC?.playMusicSegue = { sender in + self.performSegue(withIdentifier: "trackPlayerSegue", sender: sender) + } + showcaseVC?.playVideoSegue = { sender in + self.performSegue(withIdentifier: "videoPlayerSegue", sender: sender) + } + + super.viewWillAppear(animated) + + + + updateLayout() + + } + + + @IBAction func menuButtonTouched(_ sender: Any) { + self.present(actionSheet, animated: true, completion: nil) + } + + @IBAction func firstPageTapped(_ sender: Any) { + firstTabButton.alpha = 1 + secondTabButton.alpha = 0.5 + + // print(cVC?.a as Any) + cVC?.moveToPage(index: 0) + showcaseVC = cVC!.items[0] as? SecondPageVC + showcaseVC?.showcaseVideoSegue = { + self.performSegue(withIdentifier: "showcaseVideoSegue", sender: nil) + } + showcaseVC?.showcasePhotoSegue = { + self.performSegue(withIdentifier: "showcasePhotoSegue", sender: nil) + } + showcaseVC?.showcaseMusicSegue = { + self.performSegue(withIdentifier: "showcaseMusicSegue", sender: nil) + } + showcaseVC?.playMusicSegue = { sender in + self.performSegue(withIdentifier: "trackPlayerSegue", sender: sender) + } + showcaseVC?.playVideoSegue = { sender in + self.performSegue(withIdentifier: "videoPlayerSegue", sender: sender) + } + + updateLayout() + } + + @IBAction func secondPageTapped(_ sender: Any) { + firstTabButton.alpha = 0.5 + secondTabButton.alpha = 1 + + // print(cVC?.a as Any) + cVC?.moveToPage(index: 1) + + } +} + + +extension UserProfileVC : UIActionSheetDelegate, UIViewControllerTransitioningDelegate +{ + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + return OverlayPresentationController(presentedViewController:presented, presenting:presenting) + } +} + +extension UserProfileVC:ImagePickerDelegate +{ + func didSelect(image: UIImage?) + { + // coverImage?.image = image + var photoData = PhotoDataStruct() + photoData.email = DataManager.shared().currentUser?.email + photoData.photosData = image + + DataManager.shared().UploadNewPhoto(photoData:photoData) { (isSuccess, errorString) in + if isSuccess + { + print("Upload Photo File Success") + + + // self.dismiss(animated: true, completion: nil) + DispatchQueue.main.async { + self.view.window!.rootViewController?.dismiss(animated: true, completion: nil) + } + AlertViewHelper.createAlertView(type: .OK, rightHandler:nil, leftHandler: nil, replacementString: [strKeyOK_MSG:"Upload Photo File Success"]) + + + } + else + { + print("Upload Photo File Failed") + AlertViewHelper.creteErrorAlert(errorString: "Upload Photo File Failed \(errorString)", view: self) + } + } + } +} + +class OverlayPresentationController: UIPresentationController { + + private let dimmedBackgroundView = UIView() + private let height: CGFloat = 450 + + override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) { + super.init(presentedViewController: presentedViewController, presenting: presentingViewController) + let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(backgroundTapped)) + self.dimmedBackgroundView.addGestureRecognizer(tapGestureRecognizer) + } + + override var frameOfPresentedViewInContainerView: CGRect { + var frame = CGRect.zero + if let containerBounds = containerView?.bounds { + frame = CGRect(x: 0, + y: containerBounds.height/2.3, + width: containerBounds.width, + height: containerBounds.height/1.5) + } + return frame + } + + override func presentationTransitionWillBegin() { + if let containerView = self.containerView, let coordinator = presentingViewController.transitionCoordinator { + containerView.addSubview(self.dimmedBackgroundView) + self.dimmedBackgroundView.backgroundColor = .black + self.dimmedBackgroundView.frame = containerView.bounds + self.dimmedBackgroundView.alpha = 0 + coordinator.animate(alongsideTransition: { _ in + self.dimmedBackgroundView.alpha = 0.5 + }, completion: nil) + } + } + + override func dismissalTransitionDidEnd(_ completed: Bool) { + self.dimmedBackgroundView.removeFromSuperview() + } + + @objc private func backgroundTapped() { + self.presentedViewController.dismiss(animated: true, completion: nil) + } + + +} diff --git a/frontend/mobile/CommunityMC3/Profile View/UserProfileView.storyboard b/frontend/mobile/CommunityMC3/Profile View/UserProfileView.storyboard new file mode 100644 index 0000000..063d269 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Profile View/UserProfileView.storyboard @@ -0,0 +1,545 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/Edit.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/Edit.swift new file mode 100644 index 0000000..277ef59 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/Edit.swift @@ -0,0 +1,171 @@ +// +// EditRandomizerViewController.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 23/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +enum EditRandomizer: Int { + case SortBy = 0 + case Genre = 1 + case Count = 2 +} + +class EditRandomizerViewController: UIViewController { + + @IBOutlet weak var applyButton: UIButton! + @IBOutlet weak var editRandomizerLabel: UILabel! + @IBOutlet weak var clearAllButton: UIButton! + @IBOutlet weak var cancelButton: UIButton! + @IBOutlet weak var sortByTableView: UITableView! + @IBOutlet weak var genreTableView: UITableView! + + var callback:(()->Void)? = nil + + var sortByArray = ["Music", "Artist"] + + var indexTemp = 0 + var sortByTemp = [Int]() + var genreTemp = [Int]() + var selectedIndexSortByBool: [IndexPath: Bool] = [:] + var selectedIndexGenreBool: [IndexPath: Bool] = [:] + let randomSpotlight = RandomSpotlightViewController() + + override func viewDidLoad() { + super.viewDidLoad() + + loadLocalisation() + setup() + + } + + func loadLocalisation() { + editRandomizerLabel.text = NSLocalizedString("Edit randomizer".uppercased(), comment: "") + clearAllButton.titleLabel?.text = NSLocalizedString("Clear All".uppercased(), comment: "") + applyButton.titleLabel?.text = NSLocalizedString("Apply".uppercased(), comment: "") + cancelButton.titleLabel?.text = NSLocalizedString("Cancel", comment: "") + } + + func setup(){ + genreTableView.register(UINib(nibName: "HeaderCellRandomSpotlight", bundle: nil), forCellReuseIdentifier: "headerCellRandom") + genreTableView.register(UINib(nibName: "EditRandomizerContextCell", bundle: nil), forCellReuseIdentifier: "editRandomizerContextCell") + genreTableView.allowsMultipleSelection = true + applyButton.layer.cornerRadius = 5 + } + +// override func prepare(for segue: UIStoryboardSegue, sender: Any?) { +// let destinationSegue = segue.destination as? RandomSpotlightViewController +// for i in sortByTemp{ +// destinationSegue!.musicFilter.append(sortByArray[i]) +// } +// for i in genreTemp{ +// destinationSegue!.genreFilter.append(genreArray[i]) +// } +// } + + @IBAction func cancelButtonAction(_ sender: UIButton) { + dismiss(animated: true, completion: nil) + + + } + + @IBAction func applyButtonAction(_ sender: UIButton) { + dismiss(animated: true, completion: nil) + + callback!() + } + + @IBAction func clearAllButtonAction(_ sender: UIButton) { + let selectedIndex = genreTableView.indexPathsForSelectedRows + + for i in selectedIndex! { + genreTableView.deselectRow(at: i, animated: true) + genreTableView.cellForRow(at: i)?.accessoryType = UITableViewCell.AccessoryType.none + } + } + + + +} + +extension EditRandomizerViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + if section == EditRandomizer.SortBy.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") as! HeaderCellRandomSpotlight + cell.headerTitle.text = "Sort by".uppercased() + cell.headerTitle.textColor = UIColor.black + return cell + }else if section == EditRandomizer.Genre.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") as! HeaderCellRandomSpotlight + cell.headerTitle.text = "Genre".uppercased() + cell.headerTitle.textColor = UIColor.black + return cell + } + return tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") + } + +// func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { +// return +// } + + func numberOfSections(in tableView: UITableView) -> Int { + return EditRandomizer.Count.rawValue + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if section == EditRandomizer.SortBy.rawValue { + return sortByArray.count + }else if section == EditRandomizer.Genre.rawValue{ + return musicGenreArray.count + } + return 0 + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 25 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if indexPath.section == EditRandomizer.SortBy.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "editRandomizerContextCell", for: indexPath) as! EditRandomizerContextCell + cell.contextLabel.text = sortByArray[indexPath.row] + return cell + }else if indexPath.section == EditRandomizer.Genre.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "editRandomizerContextCell", for: indexPath) as! EditRandomizerContextCell + cell.contextLabel.text = musicGenreArray[indexPath.row] + return cell + } + + return tableView.dequeueReusableCell(withIdentifier: "editRandomizerContextCell")! + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 35 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.section == EditRandomizer.SortBy.rawValue{ + if sortByTemp.contains(indexPath.row){ + self.sortByTemp.remove(at: self.sortByTemp.firstIndex(of: indexPath.row)!) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + }else{ + self.sortByTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } + print(sortByTemp) + }else if indexPath.section == EditRandomizer.Genre.rawValue{ + if genreTemp.contains(indexPath.row){ + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + self.genreTemp.remove(at: self.genreTemp.firstIndex(of: indexPath.row)!) + }else{ + self.genreTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } + print(genreTemp) + } + } +} diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerTableCell/EditRandomizerContextCell.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerTableCell/EditRandomizerContextCell.swift new file mode 100644 index 0000000..38755c3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerTableCell/EditRandomizerContextCell.swift @@ -0,0 +1,25 @@ +// +// EditRandomizerContextCell.swift +// Allegro +// +// Created by Rommy Julius Dwidharma on 05/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class EditRandomizerContextCell: UITableViewCell { + + @IBOutlet weak var contextLabel: UILabel! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerTableCell/EditRandomizerContextCell.xib b/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerTableCell/EditRandomizerContextCell.xib new file mode 100644 index 0000000..600c9c4 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerTableCell/EditRandomizerContextCell.xib @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerViewController.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerViewController.swift new file mode 100644 index 0000000..831e934 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/EditRandomizerViewController.swift @@ -0,0 +1,195 @@ +// +// EditRandomizerViewController.swift +// Allegro +// +// Created by Rommy Julius Dwidharma on 05/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// +import UIKit + +enum EditRandomizer: Int { + case SortBy = 0 + case Genre = 1 + case Count = 2 +} + +class EditRandomizerViewController: UIViewController { + + @IBOutlet weak var applyButton: UIButton! + @IBOutlet weak var editRandomizerLabel: UILabel! + @IBOutlet weak var clearAllButton: UIButton! + @IBOutlet weak var cancelButton: UIButton! + @IBOutlet weak var sortByTableView: UITableView! + @IBOutlet weak var genreTableView: UITableView! + @IBOutlet weak var tableView: UITableView! + + var callback:((Bool)->Void)? = nil + + var sortByArray = ["Music", "Artist"] + + var indexTemp = 0 + var sortByTemp = [Int]() + var genreTemp = [Int]() + var selectedIndexSortByBool: [IndexPath: Bool] = [:] + var selectedIndexGenreBool: [IndexPath: Bool] = [:] + let randomSpotlight = RandomSpotlightViewController() + + override func viewDidLoad() { + super.viewDidLoad() + + loadLocalisation() + setup() + + } + + func loadLocalisation() { + editRandomizerLabel.text = NSLocalizedString("Edit randomizer".uppercased(), comment: "") + clearAllButton.titleLabel?.text = NSLocalizedString("Clear All".uppercased(), comment: "") + applyButton.titleLabel?.text = NSLocalizedString("Apply".uppercased(), comment: "") + cancelButton.titleLabel?.text = NSLocalizedString("Cancel", comment: "") + } + + func setup(){ + tableView.register(UINib(nibName: "HeaderCellRandomSpotlight", bundle: nil), forCellReuseIdentifier: "headerCellRandom") + tableView.register(UINib(nibName: "EditRandomizerContextCell", bundle: nil), forCellReuseIdentifier: "editRandomizerContextCell") + tableView.allowsMultipleSelection = true + applyButton.layer.cornerRadius = 5 + } + +// override func prepare(for segue: UIStoryboardSegue, sender: Any?) { +// let destinationSegue = segue.destination as? RandomSpotlightViewController +// for i in sortByTemp{ +// destinationSegue!.musicFilter.append(sortByArray[i]) +// } +// for i in genreTemp{ +// destinationSegue!.genreFilter.append(genreArray[i]) +// } +// } + + @IBAction func cancelButtonAction(_ sender: UIButton) { + dismiss(animated: true, completion: nil) + + + } + + @IBAction func applyButtonAction(_ sender: UIButton) { + dismiss(animated: true, completion: nil) + + callback!(false) + } + + @IBAction func clearAllButtonAction(_ sender: UIButton) { + let selectedIndex = tableView.indexPathsForSelectedRows + + for i in selectedIndex! { + tableView.deselectRow(at: i, animated: true) + tableView.cellForRow(at: i)?.accessoryType = UITableViewCell.AccessoryType.none + + genreTemp.removeAll() + sortByTemp.removeAll() + } + } + + + +} + +extension EditRandomizerViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + if section == EditRandomizer.SortBy.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") as! HeaderCellRandomSpotlight + cell.headerTitle.text = "Sort by".uppercased() + cell.headerTitle.textColor = UIColor.black + return cell + }else if section == EditRandomizer.Genre.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") as! HeaderCellRandomSpotlight + cell.headerTitle.text = "Genre".uppercased() + cell.headerTitle.textColor = UIColor.black + return cell + } + return tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") + } + + func numberOfSections(in tableView: UITableView) -> Int { + return EditRandomizer.Count.rawValue + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if section == EditRandomizer.SortBy.rawValue { + return sortByArray.count + }else if section == EditRandomizer.Genre.rawValue{ + return musicGenreArray.count + } + return 0 + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 25 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if indexPath.section == EditRandomizer.SortBy.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "editRandomizerContextCell", for: indexPath) as! EditRandomizerContextCell + cell.contextLabel.text = sortByArray[indexPath.row] + return cell + }else if indexPath.section == EditRandomizer.Genre.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "editRandomizerContextCell", for: indexPath) as! EditRandomizerContextCell + cell.contextLabel.text = musicGenreArray[indexPath.row] + return cell + } + + return tableView.dequeueReusableCell(withIdentifier: "editRandomizerContextCell")! + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 35 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.section == EditRandomizer.SortBy.rawValue{ + + if sortByTemp.contains(indexPath.row){ + self.sortByTemp.remove(at: self.sortByTemp.firstIndex(of: indexPath.row)!) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + }else{ + self.sortByTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } +// print("music \(sortByTemp)") + }else if indexPath.section == EditRandomizer.Genre.rawValue{ + if genreTemp.contains(indexPath.row){ + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + self.genreTemp.remove(at: self.genreTemp.firstIndex(of: indexPath.row)!) + }else{ + self.genreTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } +// print("genre \(genreTemp)") + } + } + func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { + if indexPath.section == EditRandomizer.SortBy.rawValue{ + + if sortByTemp.contains(indexPath.row){ + self.sortByTemp.remove(at: self.sortByTemp.firstIndex(of: indexPath.row)!) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + }else{ + self.sortByTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } +// print("music \(sortByTemp)") + }else if indexPath.section == EditRandomizer.Genre.rawValue{ + if genreTemp.contains(indexPath.row){ + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + self.genreTemp.remove(at: self.genreTemp.firstIndex(of: indexPath.row)!) + }else{ + self.genreTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } +// print("genre \(genreTemp)") + } + } + +} + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/HeaderCell/HeaderCellRandomSpotlight.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/HeaderCell/HeaderCellRandomSpotlight.swift new file mode 100644 index 0000000..ddeaa6e --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/HeaderCell/HeaderCellRandomSpotlight.swift @@ -0,0 +1,26 @@ +// +// HeaderCellRandomSpotlight.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 24/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class HeaderCellRandomSpotlight: UITableViewCell { + + @IBOutlet weak var headerTitle: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/HeaderCell/HeaderCellRandomSpotlight.xib b/frontend/mobile/CommunityMC3/RandomSpotlightView/HeaderCell/HeaderCellRandomSpotlight.xib new file mode 100644 index 0000000..2f14b85 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/HeaderCell/HeaderCellRandomSpotlight.xib @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlight.storyboard b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlight.storyboard new file mode 100644 index 0000000..f157b8b --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlight.storyboard @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicGenreCell.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicGenreCell.swift new file mode 100644 index 0000000..2e38eb9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicGenreCell.swift @@ -0,0 +1,20 @@ +// +// MusicGenreCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 24/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class MusicGenreCell: UICollectionViewCell { + + @IBOutlet weak var musicGenreLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + +} diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicGenreCell.xib b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicGenreCell.xib new file mode 100644 index 0000000..65bcd68 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicGenreCell.xib @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicListCell.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicListCell.swift new file mode 100644 index 0000000..3a15daa --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicListCell.swift @@ -0,0 +1,38 @@ +// +// MusicListCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 24/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class MusicListCell: UITableViewCell { + + @IBOutlet weak var trackTitle: UILabel! + @IBOutlet weak var trackArtist: UILabel! + @IBOutlet weak var trackCurrent: UILabel! + @IBOutlet weak var playButton: UIButton! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + // playButton.setImage(#imageLiteral(resourceName: "playButton"), for: .normal) + // playButton.setImage(#imageLiteral(resourceName: "Stop"), for: .selected) + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + } + + func update(td:TrackDataStruct) + { + trackTitle.text = td.name + trackArtist.text = td.artistName + trackCurrent.text = td.duration + + } + +} diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicListCell.xib b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicListCell.xib new file mode 100644 index 0000000..3d9cd2d --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/MusicListCell.xib @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/VideoListCell.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/VideoListCell.swift new file mode 100644 index 0000000..20a338c --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/VideoListCell.swift @@ -0,0 +1,33 @@ +// +// VideoListCell.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 24/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class VideoListCell: UITableViewCell { + + @IBOutlet weak var playButton: UIButton! + @IBOutlet weak var videoThumbnailImage: UIImageView! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + + func update(vd:VideosDataStruct) + { + videoThumbnailImage.image = vd.coverImage + videoThumbnailImage.layer.borderWidth = 2 + } +} diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/VideoListCell.xib b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/VideoListCell.xib new file mode 100644 index 0000000..cee64b7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightCell/VideoListCell.xib @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightViewController.swift b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightViewController.swift new file mode 100644 index 0000000..b956625 --- /dev/null +++ b/frontend/mobile/CommunityMC3/RandomSpotlightView/RandomSpotlightViewController.swift @@ -0,0 +1,424 @@ +// +// RandomSpotlightViewController.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVFoundation +import AVKit + +enum RandomSearch: Int { + case Music = 0 + case Video = 1 + case Count = 2 +} + +class RandomSpotlightViewController: UIViewController, AVAudioPlayerDelegate{ + + @IBOutlet weak var contentView: UIView! + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var statusLabel: UILabel! + @IBOutlet weak var editButton: UIButton! + @IBOutlet weak var innerCircleEffectImage: UIImageView! + @IBOutlet weak var outerCircleEffectImage: UIImageView! + @IBOutlet weak var searchButton: UIButton! + + @IBOutlet weak var popUpView: UIView! + @IBOutlet weak var popUpContentView: UIView! + @IBOutlet weak var viewProfileButton: UIButton! + // popup data + + var user:UserDataStruct? = nil + @IBOutlet weak var profilePicture: UIImageView! + @IBOutlet weak var artistName: UILabel! + @IBOutlet weak var roleLabel: UILabel! + var genre:[String]? = [] + @IBOutlet weak var genreCollectionView: UICollectionView! + @IBOutlet weak var musicAndVideoTableView: UITableView! + + var test = false + var trackPlayer: AVAudioPlayer? + var trackIndex = 0 + var musicPlaylist = ["dishes", "tiara", "yorushika"] + var videoList = [""] + var musicFilter = [String]() + var genreFilter = [String]() + var tempInt: Int? + var player2: AVAudioPlayer? + var timer: Timer? + var seconds = 0 + + let overlayView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)) + + override func viewDidLoad() { + super.viewDidLoad() + + setupBackground() + addSwipeGesture() + + + } + + func setupLocalisation() { + editButton.titleLabel?.text = NSLocalizedString("Edit".uppercased(), comment: "") +// nextButton.titleLabel?.text = NSLocalizedString("Next".uppercased(), comment: "") + viewProfileButton.titleLabel?.text = NSLocalizedString("View Profile".uppercased(), comment: "") + } + + func setupBackground(){ + //set gradient background in view + let viewBackground = CAGradientLayer() + viewBackground.colors = [#colorLiteral(red: 0.8862745098, green: 0.03529411765, blue: 0.168627451, alpha: 1).cgColor, #colorLiteral(red: 0.2823529412, green: 0.003921568627, blue: 0.7843137255, alpha: 1).cgColor] + viewBackground.frame = view.frame + view.layer.insertSublayer(viewBackground, at: 0) + view.bringSubviewToFront(contentView) + + //set to white color + titleLabel.textColor = UIColor.white + statusLabel.textColor = UIColor.white + editButton.setTitleColor(UIColor.white, for: .normal) + genreCollectionView.register(UINib(nibName: "MusicGenreCell", bundle: nil), forCellWithReuseIdentifier: "genreCell") + musicAndVideoTableView.register(UINib(nibName: "HeaderCellRandomSpotlight", bundle: nil), forCellReuseIdentifier: "headerCellRandom") + musicAndVideoTableView.register(UINib(nibName: "MusicListCell", bundle: nil), forCellReuseIdentifier: "musicList") + musicAndVideoTableView.register(UINib(nibName: "VideoListCell", bundle: nil), forCellReuseIdentifier: "videoList") + + popUpContentView.layer.cornerRadius = 15 + popUpView.isHidden = false + viewProfileButton.layer.cornerRadius = 15 + +// nextButton.layer.cornerRadius = 20 + } + + + @IBAction func unwindButton(_ sender: Any) { + print("unwindButtonClicked") + } + + func addSwipeGesture() { + if popUpContentView.isHidden == false{ + let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.handleGesture(gesture:))) + swipeLeft.direction = .left + self.view.addGestureRecognizer(swipeLeft) + + let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.handleGesture(gesture:))) + swipeRight.direction = .right + self.view.addGestureRecognizer(swipeRight) + } + } + + @objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void { + if gesture.direction == UISwipeGestureRecognizer.Direction.left { + updatePopupView() + popUpContentView.slideLeft() + } + // else if gesture.direction == UISwipeGestureRecognizer.Direction.right{ + // popUpContentView.slideRight() + // } + } + + override func viewWillAppear(_ animated: Bool) { + startSearch(isFirstStartAnimation: true) + super.viewWillAppear(animated) + } + + func startSearch(isFirstStartAnimation:Bool) + { + var delay:Double = 0.0 + var duration:Double = 0.8 + var transitionDuration:Double = 1.0 + if(isFirstStartAnimation) + { + self.editButton.isHidden = true + self.popUpView.isHidden = true + self.searchButton.isHidden = false + self.innerCircleEffectImage.isHidden = false + self.outerCircleEffectImage.isHidden = false + + delay = 0.0 + duration = 1.2 + transitionDuration = 1.2 + updatePopupView() + } + else + { + UIView.animate(withDuration: 0.8, delay: 0, options: .curveEaseInOut, animations: { + self.popUpView.alpha = 0 + self.statusLabel.alpha = 1 + self.searchButton.alpha = 1 + self.innerCircleEffectImage.alpha = 1 + self.outerCircleEffectImage.alpha = 1 + }, completion: {_ in + self.popUpView.isHidden = true + self.statusLabel.isHidden = false + self.searchButton.isHidden = false + self.innerCircleEffectImage.isHidden = false + self.outerCircleEffectImage.isHidden = false + self.updatePopupView() + + }) + delay = 0.8 + } + + UIView.animate(withDuration: duration,delay: delay, animations: { + UIView.modifyAnimations(withRepeatCount: 0.6, autoreverses: true, animations: { + self.outerCircleEffectImage?.transform = CGAffineTransform (scaleX:1.7 , y: 1.7) + }) + }, completion: {(_ finished: Bool) -> Void in + self.outerCircleEffectImage?.transform = CGAffineTransform(scaleX: 1, y: 1) + }) + + UIView.animate(withDuration: duration,delay: delay, animations: { + UIView.modifyAnimations(withRepeatCount: 0.6, autoreverses: true, animations: { + self.innerCircleEffectImage?.transform = CGAffineTransform (scaleX:1.2 , y: 1.2) + }) + }, completion: {(_ finished: Bool) -> Void in + self.innerCircleEffectImage?.transform = CGAffineTransform(scaleX: 1, y: 1) + }) + UIView.animate(withDuration: duration,delay: delay, animations: { + UIView.modifyAnimations(withRepeatCount: 0.6, autoreverses: true, animations: { + self.searchButton?.transform = CGAffineTransform (scaleX:0.9 , y: 0.9) + }) + }, completion: {(_ finished: Bool) -> Void in + self.searchButton?.transform = CGAffineTransform(scaleX: 1, y: 1) + UIView.animate(withDuration: transitionDuration, delay: 0, options: .transitionCrossDissolve, animations: { + self.popUpView.alpha = 1 + self.statusLabel.alpha = 0 + self.searchButton.alpha = 0 + self.innerCircleEffectImage.alpha = 0 + self.outerCircleEffectImage.alpha = 0 + }, completion: {_ in + self.popUpView.isHidden = false + self.statusLabel.isHidden = true + self.searchButton.isHidden = true + self.innerCircleEffectImage.isHidden = true + self.outerCircleEffectImage.isHidden = true + self.editButton.isHidden = false + }) + }) + } + + func updatePopupView() + { + user = DataManager.shared().randomSpotlightData.randomElement() + profilePicture.image = user?.profilePicture + artistName.text = user?.name + roleLabel.text = user?.role + genre = user?.genre!.components(separatedBy: ",") + + + musicAndVideoTableView.reloadData() + + genreCollectionView.reloadData() + } + + @IBAction func ViewProfileButtonTouched(_ sender: Any) { + + } + @IBAction func searchButtonAction(_ sender: UIButton) { + + startSearch(isFirstStartAnimation: false) + } + + @IBAction func editButtonAction(_ sender: UIButton) { + + let editRandomizerVC = storyboard?.instantiateViewController(identifier: "EditRandomizerVC") as! EditRandomizerViewController + editRandomizerVC.callback = startSearch + editRandomizerVC.transitioningDelegate = self + editRandomizerVC.modalPresentationStyle = .custom + editRandomizerVC.modalTransitionStyle = .coverVertical + editRandomizerVC.view.layer.cornerRadius = 34 + + self.present(editRandomizerVC, animated: true, completion: nil) + + + } + + @IBAction func nextButtonAction(_ sender: UIButton) { + startSearch(isFirstStartAnimation: false) + } + + @IBAction func prevButtonAction(_ sender: UIButton) { + //func +// popUpContentView.slideRight() + } + +} + +extension RandomSpotlightViewController:UITableViewDelegate, UITableViewDataSource +{ + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.section == RandomSearch.Music.rawValue{ + TrackManager.shared.play(trackData: user!.musics![indexPath.row]) + }else if indexPath.section == RandomSearch.Video.rawValue{ + TrackManager.shared.playVideo(view: self, videoData: user!.videos![indexPath.row]) + } + } + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + if section == RandomSearch.Music.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") as! HeaderCellRandomSpotlight + cell.headerTitle.text = NSLocalizedString("Music".uppercased(), comment: "") + return cell + }else if section == RandomSearch.Video.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "headerCellRandom") as! HeaderCellRandomSpotlight + cell.headerTitle.text = NSLocalizedString("Video".uppercased(), comment: "") + return cell + } + return musicAndVideoTableView.dequeueReusableCell(withIdentifier: "headerCellRandom") + } + + func numberOfSections(in tableView: UITableView) -> Int { + return RandomSearch.Count.rawValue + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if section == RandomSearch.Music.rawValue { + return user!.musics!.count//musicPlaylist.count + }else if section == RandomSearch.Video.rawValue{ + return user!.videos!.count// videoList.count + } + return 0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if indexPath.section == RandomSearch.Music.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "musicList", for: indexPath) as! MusicListCell + cell.update(td:user!.musics![indexPath.row]) + /* + cell.playButton.tag = indexPath.row + + let audiopath = Bundle.main.path(forResource: musicPlaylist[indexPath.row], ofType: "mp3") + player2 = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: audiopath!)) + let audioDuration = player2!.duration + let formatterr = DateComponentsFormatter() + formatterr.allowedUnits = [.hour, .minute, .second] + formatterr.unitsStyle = .positional + + let formattedString2 = formatterr.string(from: TimeInterval(audioDuration))! + cell.trackCurrent.text = "\(formattedString2)" + cell.playButton.addTarget(self, action: #selector(RandomSpotlightViewController.clickPlayAudio(_:)), for: .touchUpInside) + cell.playButton.setImage(#imageLiteral(resourceName: "playButton"), for: .normal) + cell.playButton.setImage(#imageLiteral(resourceName: "Stop"), for: .selected) + + if indexPath.row == tempInt{ + + }else{ + cell.playButton.isSelected = false + }*/ + + return cell + }else if indexPath.section == RandomSearch.Video.rawValue{ + let cell = tableView.dequeueReusableCell(withIdentifier: "videoList", for: indexPath) as! VideoListCell + + +// cell.playButton.tag = indexPath.row +// cell.playButton.addTarget(self, action: #selector(RandomSpotlightViewController.clickPlayVideo(_:)), for: .touchUpInside) + + return cell + } + return musicAndVideoTableView.dequeueReusableCell(withIdentifier: "musicList")! + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if indexPath.section == RandomSearch.Music.rawValue{ + return 60 + }else if indexPath.section == RandomSearch.Video.rawValue{ + return 130 + } + return 0 + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 25 + } + + @objc func clickPlayAudio(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + + let audioPath = Bundle.main.path(forResource: "\(musicPlaylist[sender.tag])", ofType: "mp3")! + var error : NSError? = nil + do { + trackPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath)) + + } catch let error1 as NSError { + error = error1 + } + trackPlayer!.delegate = self + + let selectedIndex = IndexPath(row: sender.tag, section: 0) + tempInt = sender.tag + + timer?.invalidate() + + if sender.isSelected == true { + if error == nil { + trackPlayer?.delegate = self + trackPlayer?.prepareToPlay() + trackPlayer?.play() + } + let cell = musicAndVideoTableView.cellForRow(at: selectedIndex) as! MusicListCell + seconds = Int(trackPlayer!.duration) + timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {_ in + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute, .second] + formatter.unitsStyle = .positional + + let formattedString = formatter.string(from: TimeInterval(self.seconds))! + self.seconds -= 1 + cell.trackCurrent.text = "\(formattedString)" + print(self.seconds) + } + + }else if sender.isSelected == false{ + trackPlayer?.stop() + timer!.invalidate() + } + + musicAndVideoTableView.reloadData() + } + + @objc func clickPlayVideo(_ sender: UIButton){ + if let urlString = Bundle.main.path(forResource: "\(videoList[sender.tag])", ofType: "mp4"){ + let video = AVPlayer(url: URL(fileURLWithPath: urlString)) + let videoPlayer = AVPlayerViewController() + videoPlayer.player = video + + //enter video player mode + self.present(videoPlayer, animated: true, completion: { + video.play() + + }) + } + } +} + +extension RandomSpotlightViewController:UICollectionViewDelegate, UICollectionViewDataSource +{ + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int + { + return genre!.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "genreCell", for: indexPath) as! MusicGenreCell + + cell.musicGenreLabel.text = genre![indexPath.row] + + setupUIViewForGenre(view: cell, genre: genre![indexPath.row]) + return cell + } +} + + +extension RandomSpotlightViewController : UIViewControllerTransitioningDelegate +{ + + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + return OverlayPresentationController(presentedViewController:presented, presenting:presenting) + } +} + + diff --git a/frontend/mobile/CommunityMC3/SceneDelegate.swift b/frontend/mobile/CommunityMC3/SceneDelegate.swift new file mode 100644 index 0000000..a9d6f9e --- /dev/null +++ b/frontend/mobile/CommunityMC3/SceneDelegate.swift @@ -0,0 +1,61 @@ +// +// SceneDelegate.swift +// CommunityMC3 +// +// Created by Bryanza on 06/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + let storyboard = UIStoryboard(name: "OnboardingScreen", bundle: nil) + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + if !UserDefaults.standard.bool(forKey: "didSee") { + UserDefaults.standard.set(true, forKey: "didSee") + + let storyboard = UIStoryboard(name: "OnboardingScreen", bundle: nil) + let viewController = storyboard.instantiateViewController(withIdentifier: "OnboardingVC") + self.window?.rootViewController = viewController + self.window?.makeKeyAndVisible() + } + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/frontend/mobile/CommunityMC3/SearchView/All Search/AllSearchVC.swift b/frontend/mobile/CommunityMC3/SearchView/All Search/AllSearchVC.swift new file mode 100644 index 0000000..26ba48c --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/All Search/AllSearchVC.swift @@ -0,0 +1,143 @@ +// +// AllSearchVC.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +enum SearchSection:Int{ + case Artist = 0 + case Music = 1 + case Video = 2 + case Playlist = 3 + case Count = 4 +} + +class AllSearchVC: UIViewController { + + @IBOutlet weak var allSearchTableView: UITableView! + + var dm:DataManager = DataManager.shared() + var callback:((UserDataStruct)->Void)? = nil + + override func viewDidLoad() + { + super.viewDidLoad() + allSearchTableView.separatorStyle = UITableViewCell.SeparatorStyle.none + allSearchTableView.register(UINib(nibName: "SearchHeaderSection", bundle: nil), forCellReuseIdentifier: "searchHeaderSection") + allSearchTableView.register(UINib(nibName: "MusicSearchCell", bundle: nil), forCellReuseIdentifier: "musicSearchCell") + allSearchTableView.register(UINib(nibName: "ArtistSearchCell", bundle: nil), forCellReuseIdentifier: "artistSearchCell") + allSearchTableView.register(UINib(nibName: "VideoSearchCell", bundle: nil), forCellReuseIdentifier: "videoSearchCell") + allSearchTableView.register(UINib(nibName: "PlaylistSearchCell", bundle: nil), forCellReuseIdentifier: "playlistSearchCell") + + dm = DataManager.shared() + } + + override func viewWillAppear(_ animated: Bool) + { + allSearchTableView.reloadData() + super.viewWillAppear(animated) + } + +} + +extension AllSearchVC: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let cell = allSearchTableView.dequeueReusableCell(withIdentifier: "searchHeaderSection") as! SearchHeaderSection + if(section == SearchSection.Artist.rawValue) + { + cell.searchHeaderLabel.text = NSLocalizedString("Artist", comment: "") + } + if(section == SearchSection.Music.rawValue) + { + cell.searchHeaderLabel.text = NSLocalizedString("Music".uppercased(), comment: "") + } + if(section == SearchSection.Video.rawValue) + { + cell.searchHeaderLabel.text = NSLocalizedString("Video".uppercased(), comment: "") + } + if(section == SearchSection.Playlist.rawValue) + { + cell.searchHeaderLabel.text = NSLocalizedString("Playlist", comment: "") + } + return cell + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + 48 + } + + func numberOfSections(in tableView: UITableView) -> Int { + return 3 // (artist, music, video) SearchSection.Count.rawValue + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { +// max 5 + switch section { + case SearchSection.Artist.rawValue: + return min(5, dm.filteredArtist.count) + case SearchSection.Video.rawValue: + return min(5, dm.filteredVideos.count) + case SearchSection.Music.rawValue: + return min(5, dm.filteredTracks.count) + default: + return 0 + } + + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if(indexPath.section == SearchSection.Artist.rawValue) + { + let cell = allSearchTableView.dequeueReusableCell(withIdentifier: "artistSearchCell") as! ArtistSearchCell + cell.updateData(dm.filteredArtist[indexPath.row]) + return cell + } + if(indexPath.section == SearchSection.Music.rawValue) + { + let cell = allSearchTableView.dequeueReusableCell(withIdentifier: "musicSearchCell") as! MusicSearchCell + cell.updateData(dm.filteredTracks[indexPath.row]) + return cell + } + if(indexPath.section == SearchSection.Video.rawValue) + { + let cell = allSearchTableView.dequeueReusableCell(withIdentifier: "videoSearchCell") as! VideoSearchCell + cell.updateData(dm.filteredVideos[indexPath.row]) + return cell + } + if(indexPath.section == SearchSection.Playlist.rawValue) + { + let cell = allSearchTableView.dequeueReusableCell(withIdentifier: "playlistSearchCell") as! PlaylistSearchCell + return cell + } + return allSearchTableView.dequeueReusableCell(withIdentifier: "artistSearchCell")! + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if(indexPath.section == SearchSection.Video.rawValue) + { + return 200 + } + + return 80 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if(indexPath.section == SearchSection.Artist.rawValue) + { + callback!(dm.filteredArtist[indexPath.row]) + } + if(indexPath.section == SearchSection.Music.rawValue) + { + TrackManager.shared.play(trackData: dm.filteredTracks[indexPath.row]) + } + if(indexPath.section == SearchSection.Video.rawValue) + { + TrackManager.shared.playVideo(view: self, videoData: dm.filteredVideos[indexPath.row]) + } + } +} diff --git a/frontend/mobile/CommunityMC3/SearchView/All Search/SearchHeaderSection.swift b/frontend/mobile/CommunityMC3/SearchView/All Search/SearchHeaderSection.swift new file mode 100644 index 0000000..e3f91b7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/All Search/SearchHeaderSection.swift @@ -0,0 +1,36 @@ +// +// SearchHeaderSection.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class SearchHeaderSection: UITableViewCell { + + @IBOutlet weak var searchHeaderLabel: UILabel! + @IBOutlet weak var viewAllButton: UIButton! + + var callBack: (() -> Void)? = nil + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + @IBAction func tapViewAll(_ sender: Any) { + self.callBack!() + } + + func setCallBack(callback: (() -> Void)?){ + self.callBack = callback + } +} diff --git a/frontend/mobile/CommunityMC3/SearchView/All Search/SearchHeaderSection.xib b/frontend/mobile/CommunityMC3/SearchView/All Search/SearchHeaderSection.xib new file mode 100644 index 0000000..7b43caa --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/All Search/SearchHeaderSection.xib @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchCell.swift b/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchCell.swift new file mode 100644 index 0000000..fc028e8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchCell.swift @@ -0,0 +1,49 @@ +// +// ArtistSearchCell.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ArtistSearchCell: UITableViewCell { + + @IBOutlet weak var artistNameLabel: UILabel! + @IBOutlet weak var artistRoleLabel: UILabel! + @IBOutlet weak var artistImageView: UIImageView! + + var artistData:UserDataStruct? = nil + + override func awakeFromNib() { + super.awakeFromNib() + artistImageView.makeRounded() + } + + func updateData(_ artistData:UserDataStruct) + { + self.artistData = artistData + artistImageView.image = artistData.profilePicture! + artistRoleLabel.text = artistData.role + artistNameLabel.text = artistData.name! + } + + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} + +extension UIImageView { + + func makeRounded() { + self.layer.masksToBounds = false + self.layer.borderColor = UIColor.black.cgColor + self.layer.cornerRadius = self.frame.height / 2 + self.clipsToBounds = true + } +} diff --git a/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchCell.xib b/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchCell.xib new file mode 100644 index 0000000..1bd6f1c --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchCell.xib @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchVC.swift b/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchVC.swift new file mode 100644 index 0000000..f26cf06 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Artist Search/ArtistSearchVC.swift @@ -0,0 +1,42 @@ +// +// ArtistSearchVC.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class ArtistSearchVC: UIViewController { + + @IBOutlet weak var artistSeachTableView: UITableView! + + var dm:DataManager? = nil + var callback:((UserDataStruct)->Void)? = nil + + override func viewDidLoad() { + super.viewDidLoad() + artistSeachTableView.separatorStyle = UITableViewCell.SeparatorStyle.none + artistSeachTableView.register(UINib(nibName: "ArtistSearchCell", bundle: nil), forCellReuseIdentifier: "artistSearchCell") + + dm = DataManager.shared() + } +} + +extension ArtistSearchVC: UITableViewDataSource, UITableViewDelegate { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return dm!.filteredArtist.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = artistSeachTableView.dequeueReusableCell(withIdentifier: "artistSearchCell") as! ArtistSearchCell + cell.updateData(dm!.filteredArtist[indexPath.row]) + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + callback!(dm!.filteredArtist[indexPath.row]) + } + +} diff --git a/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchCell.swift b/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchCell.swift new file mode 100644 index 0000000..0700fcf --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchCell.swift @@ -0,0 +1,38 @@ +// +// MusicSearchCell.swift +// CommunityMC3 +// +// Created by Theofani on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class MusicSearchCell: UITableViewCell { + + @IBOutlet weak var trackImageView: UIImageView! + @IBOutlet weak var trackTitleLabel: UILabel! + @IBOutlet weak var artistNameLabel: UILabel! + + var trackData:TrackDataStruct? = nil + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + func updateData(_ trackData:TrackDataStruct) + { + self.trackData = trackData + trackImageView.image = trackData.coverImage + trackTitleLabel.text = trackData.name + artistNameLabel.text = trackData.artistName + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchCell.xib b/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchCell.xib new file mode 100644 index 0000000..c692b41 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchCell.xib @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchVC.swift b/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchVC.swift new file mode 100644 index 0000000..dfca06f --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Music Search/MusicSearchVC.swift @@ -0,0 +1,43 @@ +// +// MusicSearchVC.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class MusicSearchVC: UIViewController { + + @IBOutlet weak var musicSearchTableView: UITableView! + + var dm:DataManager? = nil + + override func viewDidLoad() { + super.viewDidLoad() + + musicSearchTableView.separatorStyle = UITableViewCell.SeparatorStyle.none + musicSearchTableView.register(UINib(nibName: "MusicSearchCell", bundle: nil), forCellReuseIdentifier: "musicSearchCell") + + dm = DataManager.shared() + } + +} + +extension MusicSearchVC: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return dm!.filteredTracks.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = musicSearchTableView.dequeueReusableCell(withIdentifier: "musicSearchCell") as! MusicSearchCell + cell.updateData(dm!.filteredTracks[indexPath.row]) + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + TrackManager.shared.play(trackData: dm!.filteredTracks[indexPath.row]) + } + +} diff --git a/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchCell.swift b/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchCell.swift new file mode 100644 index 0000000..7b906ec --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchCell.swift @@ -0,0 +1,24 @@ +// +// PlaylistSearchCell.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class PlaylistSearchCell: UITableViewCell { + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchCell.xib b/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchCell.xib new file mode 100644 index 0000000..918c8a6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchCell.xib @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchVC.swift b/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchVC.swift new file mode 100644 index 0000000..aab5266 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Playlist Search/PlaylistSearchVC.swift @@ -0,0 +1,32 @@ +// +// PlaylistSearchVC.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class PlaylistSearchVC: UIViewController { + + @IBOutlet weak var playlistSearchTableView: UITableView! + override func viewDidLoad() { + super.viewDidLoad() + playlistSearchTableView.separatorStyle = UITableViewCell.SeparatorStyle.none + playlistSearchTableView.register(UINib(nibName: "PlaylistSearchCell", bundle: nil), forCellReuseIdentifier: "playlistSearchCell") + } + +} + +extension PlaylistSearchVC: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = playlistSearchTableView.dequeueReusableCell(withIdentifier: "playlistSearchCell") as! PlaylistSearchCell + return cell + } + +} diff --git a/frontend/mobile/CommunityMC3/SearchView/Search.storyboard b/frontend/mobile/CommunityMC3/SearchView/Search.storyboard new file mode 100644 index 0000000..07f3989 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Search.storyboard @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + Title + Title + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SearchView/SearchContainerPageVC.swift b/frontend/mobile/CommunityMC3/SearchView/SearchContainerPageVC.swift new file mode 100644 index 0000000..30f677b --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/SearchContainerPageVC.swift @@ -0,0 +1,126 @@ +// +// SeachContainerPageVC.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class SearchContainerPageVC: UIPageViewController { + + var callback:((UserDataStruct)->Void)? = nil + + lazy var items: [UIViewController] = { + let sb = UIStoryboard(name: "Search", bundle: nil) + + let vc1 = sb.instantiateViewController(withIdentifier: "allSearch") + let vc2 = sb.instantiateViewController(withIdentifier: "artistSearch") + let vc3 = sb.instantiateViewController(withIdentifier: "musicSearch") + let vc4 = sb.instantiateViewController(withIdentifier: "videoSearch") + let vc5 = sb.instantiateViewController(withIdentifier: "playlistSearch") + + return [vc1, vc2, vc3, vc4, vc5] + }() + + var cVC:UIViewController? = nil + + override func viewDidLoad() { + super.viewDidLoad() + + self.dataSource = nil + self.delegate = nil + + } + + func moveToPageSearch(index:Int) + { + let nextVC = [items[index]] + cVC = nextVC[0] + + switch index { + case 0: + let currentSearchVC = cVC as! AllSearchVC + currentSearchVC.callback = callback + case 1: + let currentSearchVC = cVC as! ArtistSearchVC + currentSearchVC.callback = callback + default: + print("Other search go here") + } + setViewControllers(nextVC, direction: .forward, animated: false, completion: nil) + } + + func updateResultTable() + { + if cVC is AllSearchVC + { + let currentSearchVC = cVC as! AllSearchVC + currentSearchVC.allSearchTableView.reloadData() + } + else if cVC is ArtistSearchVC + { + let currentSearchVC = cVC as! ArtistSearchVC + currentSearchVC.artistSeachTableView.reloadData() + } + else if cVC is MusicSearchVC + { + let currentSearchVC = cVC as! MusicSearchVC + currentSearchVC.musicSearchTableView.reloadData() + } + else if cVC is VideoSearchVC + { + let currentSearchVC = cVC as! VideoSearchVC + currentSearchVC.videoSearchTableView.reloadData() + } + } + +} + +// MARK: - DataSource +extension SearchContainerPageVC: UIPageViewControllerDataSource { + func pageViewController(_: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = items.firstIndex(of: viewController) else { + return nil + } + + let previousIndex = viewControllerIndex - 1 + + guard previousIndex >= 0 else { + return items.last + } + + guard items.count > previousIndex else { + return nil + } + + return items[previousIndex] + } + + func pageViewController(_: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = items.firstIndex(of: viewController) else { + return nil + } + + let nextIndex = viewControllerIndex + 1 + guard items.count != nextIndex else { + return items.first + } + + guard items.count > nextIndex else { + return nil + } + + return items[nextIndex] + } + + func presentationIndex(for _: UIPageViewController) -> Int { + guard let firstViewController = viewControllers?.first, + let firstViewControllerIndex = items.firstIndex(of: firstViewController) else { + return 0 + } + + return firstViewControllerIndex + } +} diff --git a/frontend/mobile/CommunityMC3/SearchView/SearchView.swift b/frontend/mobile/CommunityMC3/SearchView/SearchView.swift new file mode 100644 index 0000000..498ef89 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/SearchView.swift @@ -0,0 +1,132 @@ +// +// SecondViewController.swift +// CommunityMC3 +// +// Created by Bryanza on 06/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +enum ButtonType:Int{ + case All = 0 + case Artist = 1 + case Music = 2 + case Video = 3 + case Playlist = 4 +} + +class SearchView: UIViewController { + + @IBOutlet var searchCategoryButton: [UIButton]! + + @IBOutlet weak var topButton: UIButton! + var vcSearch:SearchContainerPageVC? + + + override func viewDidLoad() { + super.viewDidLoad() + self.dismissKeyboard() + + + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "searchContainer" + { + vcSearch = (segue.destination as! SearchContainerPageVC) + vcSearch?.callback = { + data in + self.performSegue(withIdentifier: "artistProfileSegue", sender: data) + } + } + else if segue.identifier == "artistProfileSegue" + { + let dest = segue.destination as! UserProfileVC + print("Sender :\(sender as! UserDataStruct)") + dest.userData = sender as? UserDataStruct + dest.isPersonalProfile = false + print("destName \(dest.userData?.name)") + } + } + + func getSelectedActionType() -> ButtonType{ + //Set each button action by index + for (index, button) in searchCategoryButton.enumerated() + { + if button.backgroundColor == #colorLiteral(red: 0.3450980392, green: 0.2, blue: 0.8392156863, alpha: 1) { + vcSearch?.moveToPageSearch(index: index) + } + } + return .All + } + + @IBAction func accountButtonTouched(_ sender: Any) + { + if DataManager.shared().IsUserLogin() + { + self.performSegue(withIdentifier: "userProfileSegue", sender: nil) + } + else + { + self.performSegue(withIdentifier: "loginScreenSegue", sender: nil) + } + } + + @IBAction func searchTabSelected(_ sender: UIButton) { + //Setup the active-inactive button color + searchCategoryButton.forEach({ + setButtonAsUnselected($0) +// $0.backgroundColor = .none +// $0.setTitleColor(#colorLiteral(red: 0.4117647059, green: 0.4745098039, blue: 0.9725490196, alpha: 1), for: .normal) +// $0.titleLabel?.font = UIFont.systemFont(ofSize: 15, weight: .regular) + }) + + setButtonAsSelected(sender) + + //Assign each action button + let _: ButtonType = getSelectedActionType() + } + + func setButtonAsUnselected(_ sender:UIButton) + { + sender.backgroundColor = .none + sender.setTitleColor(#colorLiteral(red: 0.4117647059, green: 0.4745098039, blue: 0.9725490196, alpha: 1), for: .normal) + sender.titleLabel?.font = UIFont.systemFont(ofSize: 15, weight: .regular) + } + + func setButtonAsSelected(_ sender:UIButton) + { + sender.backgroundColor = #colorLiteral(red: 0.3450980392, green: 0.2, blue: 0.8392156863, alpha: 1) + sender.setTitleColor(.white, for: .normal) + sender.layer.cornerRadius = 15 + sender.titleLabel?.font = UIFont.boldSystemFont(ofSize: 15) + } + + func updateResultTable() + { + vcSearch?.updateResultTable() + } +} + +extension SearchView:UISearchBarDelegate +{ + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) + { + DataManager.shared().filterArtist(searchText) + DataManager.shared().filterTracks(searchText) + DataManager.shared().filterVideo(searchText) + updateResultTable() + + if(!searchText.isEmpty) + { + searchTabSelected(topButton) + } + else + { + setButtonAsUnselected(topButton) + } + + + } +} diff --git a/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchCell.swift b/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchCell.swift new file mode 100644 index 0000000..dacc0f7 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchCell.swift @@ -0,0 +1,41 @@ +// +// VideoSearchCell.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class VideoSearchCell: UITableViewCell { + + + @IBOutlet weak var videoThumbnailImage: UIImageView! + @IBOutlet weak var darkGradientOverlay: UIImageView! + + var videoData:VideosDataStruct? = nil + + override func awakeFromNib() { + super.awakeFromNib() + videoThumbnailImage.layer.cornerRadius = 10 + darkGradientOverlay.layer.cornerRadius = 10 + + } + + func updateData(_ videoData:VideosDataStruct) + { + self.videoData = videoData + videoThumbnailImage.image = videoData.coverImage + } + + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} + + diff --git a/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchCell.xib b/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchCell.xib new file mode 100644 index 0000000..b199c9b --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchCell.xib @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchVC.swift b/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchVC.swift new file mode 100644 index 0000000..c4c6ff8 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SearchView/Video Search/VideoSearchVC.swift @@ -0,0 +1,49 @@ +// +// VideoSearchVC.swift +// CommunityMC3 +// +// Created by Theofani on 28/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class VideoSearchVC: UIViewController { + + @IBOutlet weak var videoSearchTableView: UITableView! + + var dm:DataManager? = nil + + + override func viewDidLoad() { + super.viewDidLoad() + videoSearchTableView.separatorStyle = UITableViewCell.SeparatorStyle.none + videoSearchTableView.register(UINib(nibName: "VideoSearchCell", bundle: nil), forCellReuseIdentifier: "videoSearchCell") + + dm = DataManager.shared() + } + +} + +extension VideoSearchVC: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return dm!.filteredVideos.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = videoSearchTableView.dequeueReusableCell(withIdentifier: "videoSearchCell") as! VideoSearchCell + cell.updateData(dm!.filteredVideos[indexPath.row]) + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 200 + + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + TrackManager.shared.playVideo(view: self, videoData: dm!.filteredVideos[indexPath.row]) + } +} + + diff --git a/frontend/mobile/CommunityMC3/SelectFile View/Base.lproj/SelectFileView.storyboard b/frontend/mobile/CommunityMC3/SelectFile View/Base.lproj/SelectFileView.storyboard new file mode 100644 index 0000000..a4e131f --- /dev/null +++ b/frontend/mobile/CommunityMC3/SelectFile View/Base.lproj/SelectFileView.storyboard @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SelectFile View/Base.lproj/SelectViewCell.xib b/frontend/mobile/CommunityMC3/SelectFile View/Base.lproj/SelectViewCell.xib new file mode 100644 index 0000000..65f9ff5 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SelectFile View/Base.lproj/SelectViewCell.xib @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SelectFile View/SelectFileView.swift b/frontend/mobile/CommunityMC3/SelectFile View/SelectFileView.swift new file mode 100644 index 0000000..2adbe7c --- /dev/null +++ b/frontend/mobile/CommunityMC3/SelectFile View/SelectFileView.swift @@ -0,0 +1,120 @@ +// +// SelectFileView.swift +// CommunityMC3 +// +// Created by Bernardinus on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class SelectFileView: UIViewController +{ + + @IBOutlet weak var cancelButton: UIButton! + @IBOutlet weak var tableView: UITableView! + @IBOutlet weak var searchBar: UISearchBar! + @IBOutlet weak var selectFileTitleLabel: UILabel! + + var isUploadVideo:Bool = false + + let documentController = DocumentTableViewController.shared + + var fileList:[URL] = [] + + var filteredList:[URL] = [] + var selectedIndex:Int = 0 + + override func viewDidLoad() { + super.viewDidLoad() + + searchBar.delegate = self + + tableView.delegate = self + tableView.dataSource = self + tableView.register(UINib(nibName: "SelectViewCell", bundle:nil), forCellReuseIdentifier: "selectViewCell") + + + + if(isUploadVideo) + { + fileList = FileManagers.getAvailableVideoFiles() + } + else + { + fileList = FileManagers.getAvailableAudioFiles() + } + + + + filteredList = fileList + + cancelButton.titleLabel?.text = NSLocalizedString("Cancel", comment: "") + selectFileTitleLabel.text = NSLocalizedString("Select File", comment: "") + + } + + @IBAction func cancelButtonTouched(_ sender: Any) { + dismiss(animated: true, completion: nil) + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "uploadFileSegue" + { + let uploadFileVC = segue.destination as! UploadFileView + uploadFileVC.prepareData(isUploadVideo: isUploadVideo, + fileURL: filteredList[selectedIndex] + ) +// uploadFileVC.isUploadVideo = isUploadVideo +// uploadFileVC.fileURL = filteredList[selectedIndex] + } + } + + func filter(filterText:String) + { + print("asd+\(filterText)+asd") + if(filterText.isEmpty || filterText == "") + { + filteredList = fileList + } + else + { + filteredList = fileList.filter{$0.lastPathComponent.lowercased().contains(filterText.lowercased())} + } + tableView.reloadData() + } + +} + + +extension SelectFileView:UISearchBarDelegate +{ + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) + { + filter(filterText: searchText) + } +} + +extension SelectFileView:UITableViewDelegate, UITableViewDataSource +{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int + { + filteredList.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell + { + let cell = tableView.dequeueReusableCell(withIdentifier: "selectViewCell") as! SelectViewCell + cell.fileName.text = filteredList[indexPath.row].lastPathComponent + print("\(indexPath.row)") + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) + { + selectedIndex = indexPath.row + performSegue(withIdentifier: "uploadFileSegue", sender:nil) + // documentController.uploadTrack(email: "mnb@mnb", genre: "Rock", name: "track", fileURL: filteredList[indexPath.row]) + // performSegue(withIdentifier: "uploadTest", sender:nil) + } +} diff --git a/frontend/mobile/CommunityMC3/SelectFile View/SelectViewCell.swift b/frontend/mobile/CommunityMC3/SelectFile View/SelectViewCell.swift new file mode 100644 index 0000000..ce7f985 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SelectFile View/SelectViewCell.swift @@ -0,0 +1,28 @@ +// +// SelecVileCell.swift +// CommunityMC3 +// +// Created by Bernardinus on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class SelectViewCell: UITableViewCell { + + + @IBOutlet weak var fileName: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} + diff --git a/frontend/mobile/CommunityMC3/SelectFile View/en.lproj/SelectFileView.strings b/frontend/mobile/CommunityMC3/SelectFile View/en.lproj/SelectFileView.strings new file mode 100644 index 0000000..cd872f3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SelectFile View/en.lproj/SelectFileView.strings @@ -0,0 +1,6 @@ + +/* Class = "UIButton"; normalTitle = "Cancel"; ObjectID = "ng1-1q-r9p"; */ +"ng1-1q-r9p.normalTitle" = "Cancel"; + +/* Class = "UILabel"; text = "Label"; ObjectID = "zDH-bD-AfV"; */ +"zDH-bD-AfV.text" = "Label"; diff --git a/frontend/mobile/CommunityMC3/SelectFile View/id.lproj/SelectFileView.strings b/frontend/mobile/CommunityMC3/SelectFile View/id.lproj/SelectFileView.strings new file mode 100644 index 0000000..cd872f3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/SelectFile View/id.lproj/SelectFileView.strings @@ -0,0 +1,6 @@ + +/* Class = "UIButton"; normalTitle = "Cancel"; ObjectID = "ng1-1q-r9p"; */ +"ng1-1q-r9p.normalTitle" = "Cancel"; + +/* Class = "UILabel"; text = "Label"; ObjectID = "zDH-bD-AfV"; */ +"zDH-bD-AfV.text" = "Label"; diff --git a/frontend/mobile/CommunityMC3/Setting View/GenreCollectionView/GenreProfileCollectionViewCell.swift b/frontend/mobile/CommunityMC3/Setting View/GenreCollectionView/GenreProfileCollectionViewCell.swift new file mode 100644 index 0000000..425bf9e --- /dev/null +++ b/frontend/mobile/CommunityMC3/Setting View/GenreCollectionView/GenreProfileCollectionViewCell.swift @@ -0,0 +1,21 @@ +// +// GenreProfileCollectionViewCell.swift +// Allegro +// +// Created by Bryanza on 04/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class GenreProfileCollectionViewCell: UICollectionViewCell { + + @IBOutlet weak var genreProfileCheckbox: UIImageView! + @IBOutlet weak var genreProfileLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + +} diff --git a/frontend/mobile/CommunityMC3/Setting View/GenreCollectionView/GenreProfileCollectionViewCell.xib b/frontend/mobile/CommunityMC3/Setting View/GenreCollectionView/GenreProfileCollectionViewCell.xib new file mode 100644 index 0000000..4371260 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Setting View/GenreCollectionView/GenreProfileCollectionViewCell.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Setting View/GenreProfileController.swift b/frontend/mobile/CommunityMC3/Setting View/GenreProfileController.swift new file mode 100644 index 0000000..840cb15 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Setting View/GenreProfileController.swift @@ -0,0 +1,160 @@ +// +// GenreProfileController.swift +// Allegro +// +// Created by Bryanza on 05/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class GenreProfileController: UIViewController { + + var genreArray = ["Rock", "Jazz", "Pop", "RnB", "Acoutic", "Blues"] + var genreTemp = [Int]() + var selectedIndexGenreBool: [IndexPath: Bool] = [:] + + @IBOutlet weak var genreProfile: UITableView! + @IBOutlet weak var applyButton: UIButton! + @IBOutlet weak var editGenreLabel: UILabel! + @IBOutlet weak var cancelButton: UIButton! + @IBOutlet weak var clearAllButton: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + loadLocalisation() + setup() + } + + func loadLocalisation() { + editGenreLabel.text = NSLocalizedString("Edit genre".uppercased(), comment: "") + clearAllButton.titleLabel?.text = NSLocalizedString("Clear All".uppercased(), comment: "") + applyButton.titleLabel?.text = NSLocalizedString("Apply".uppercased(), comment: "") + cancelButton.titleLabel?.text = NSLocalizedString("Cancel", comment: "") + } + + func setup(){ +// genreProfile.register(UINib(nibName: "GenreProfileCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "genreProfile") + genreProfile.register(UINib(nibName: "GenreProfileTableViewCell", bundle: nil), forCellReuseIdentifier: "genreProfileContextCell") + genreProfile.allowsMultipleSelection = true + + applyButton.layer.cornerRadius = 5 + } + + @IBAction func cancelGenreProfile(_ sender: UIButton) { + dismiss(animated: true, completion: nil) + } + + @IBAction func clearAllGenreProfile(_ sender: UIButton) { +// let selectedGenre = genreProfile.indexPathsForSelectedRows +// +// for indexPath in selectedGenre! { +// let cell = genreProfile.cellForItem(at: indexPath) as! GenreProfileCollectionViewCell +// genreProfile.deselectItem(at: indexPath, animated: true) +// cell.genreProfileCheckbox.image = nil +// cell.genreProfileCheckbox.layer.borderWidth = 1 +// genreTemp.removeAll() +// } + let selectedIndex = genreProfile.indexPathsForSelectedRows + + for i in selectedIndex! { + genreProfile.deselectRow(at: i, animated: true) + genreProfile.cellForRow(at: i)?.accessoryType = UITableViewCell.AccessoryType.none + + genreTemp.removeAll() + } + } + + + @IBAction func saveGenreProfile(_ sender: UIButton) { + var temp = "" + var idx = 0 + for genre in genreArray { + if genreTemp.contains(idx) { + temp += genre + "," + } + idx += 1 + } + if let presenter = presentingViewController as? SettingController { + presenter.genreField.text = String(temp.dropLast()) + } + dismiss(animated: true, completion: nil) + } + +} + +//extension GenreProfileController: UICollectionViewDataSource, UICollectionViewDelegate { +// func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { +// return genreArray.count +// } +// +// func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { +// let cell = genreProfile.dequeueReusableCell(withReuseIdentifier: "genreProfile", for: indexPath) as! GenreProfileCollectionViewCell +// cell.genreProfileLabel.text = genreArray[indexPath.row] +// cell.genreProfileCheckbox.layer.borderColor = UIColor.lightGray.cgColor +// cell.genreProfileCheckbox.layer.masksToBounds = true +// cell.genreProfileCheckbox.layer.borderWidth = 1 +// cell.genreProfileCheckbox.layer.cornerRadius = 6 +// +// return cell +// } +// func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { +// if genreTemp.contains(indexPath.row){ +// let cell = genreProfile.cellForItem(at: indexPath) as! GenreProfileCollectionViewCell +// self.genreTemp.remove(at: self.genreTemp.firstIndex(of: indexPath.row)!) +// cell.genreProfileCheckbox.image = nil +// cell.genreProfileCheckbox.layer.borderWidth = 1 +// }else{ +// let cell = genreProfile.cellForItem(at: indexPath) as! GenreProfileCollectionViewCell +// self.genreTemp.append(indexPath.row) +// cell.genreProfileCheckbox.image = #imageLiteral(resourceName: "checkBox") +// cell.genreProfileCheckbox.layer.borderWidth = 0 +// } +// } +// func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { +// selectedIndexGenreBool[indexPath] = false +// } +//} + +extension GenreProfileController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return genreArray.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "genreProfileContextCell", for: indexPath) as! GenreProfileTableViewCell + cell.genreProfileLabel.text = genreArray[indexPath.row] + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 35 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if genreTemp.contains(indexPath.row){ + print("genre remove") + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + self.genreTemp.remove(at: self.genreTemp.firstIndex(of: indexPath.row)!) + }else{ + print("genre aadd") + self.genreTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } + print("genre \(genreTemp)") + } + func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { + if genreTemp.contains(indexPath.row){ + print("genre remove") + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none + self.genreTemp.remove(at: self.genreTemp.firstIndex(of: indexPath.row)!) + }else{ + print("genre add") + self.genreTemp.append(indexPath.row) + tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark + } + print("genre \(genreTemp)") + } + +} diff --git a/frontend/mobile/CommunityMC3/Setting View/GenreTableView/GenreProfileTableViewCell.swift b/frontend/mobile/CommunityMC3/Setting View/GenreTableView/GenreProfileTableViewCell.swift new file mode 100644 index 0000000..6aef3a9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Setting View/GenreTableView/GenreProfileTableViewCell.swift @@ -0,0 +1,26 @@ +// +// GenreProfileTableViewCell.swift +// Allegro +// +// Created by Bryanza on 06/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class GenreProfileTableViewCell: UITableViewCell { + + @IBOutlet weak var genreProfileLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/Setting View/GenreTableView/GenreProfileTableViewCell.xib b/frontend/mobile/CommunityMC3/Setting View/GenreTableView/GenreProfileTableViewCell.xib new file mode 100644 index 0000000..7cb9324 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Setting View/GenreTableView/GenreProfileTableViewCell.xib @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Setting View/SettingController.swift b/frontend/mobile/CommunityMC3/Setting View/SettingController.swift new file mode 100644 index 0000000..478ddbf --- /dev/null +++ b/frontend/mobile/CommunityMC3/Setting View/SettingController.swift @@ -0,0 +1,340 @@ +// +// SettingController.swift +// CommunityMC3 +// +// Created by Bryanza on 16/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +//import Foundation +import UIKit +import CloudKit + +class SettingController: UIViewController { + + @IBOutlet weak var settingTitleLabel: UILabel! + @IBOutlet weak var nameTitleLabel: UILabel! + @IBOutlet weak var emailTitleLabel: UILabel! + @IBOutlet weak var genreTitleLabel: UILabel! + @IBOutlet weak var saveButton: UIButton! + @IBOutlet weak var signOutButton: UIButton! + @IBOutlet weak var settingImage: UIImageView! + @IBOutlet weak var nameField: UITextField! + @IBOutlet weak var emailField: UITextField! + @IBOutlet weak var genreField: UITextField! + @IBOutlet weak var menuButton: UIButton! + @IBOutlet weak var phoneNumberLabel: UILabel! + @IBOutlet weak var phoneNumberField: UITextField! + @IBOutlet weak var instagramLabel: UILabel! + @IBOutlet weak var instagramField: UITextField! + + var isEditProfile:Bool = true + var emailAddr:String = "" + var password:String = "" + var selectedGenre:String = "" + + // let documentController = DocumentTableViewController.shared + let uploadController = UploadController.shared + let userDefault = UserDefaults.standard + + override func viewDidLoad() { + super.viewDidLoad() + self.dismissKeyboard() + +// let uploadTap = UITapGestureRecognizer(target: self, action: #selector(self.handleUploadTap(_:))) +// settingImage.addGestureRecognizer(uploadTap) +// menuButton.isHidden = !isEditProfile + if let loadEmail = userDefault.string(forKey: "email"){ + emailField.text = loadEmail + } + handleLocalisation() + +// let pickerView:UIPickerView = UIPickerView() +// pickerView.delegate = self +// genreField?.delegate = self +// genreField?.inputView = pickerView + let genreTap = UITapGestureRecognizer(target: self, action: #selector(self.handleGenreTap(_:))) + genreField.addGestureRecognizer(genreTap) + + let toolBar = UIToolbar() + toolBar.sizeToFit() + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let button = UIBarButtonItem(title: NSLocalizedString("Done".uppercased(), comment: ""), style: .plain, target: self, action: #selector(self.action)) + toolBar.setItems([flexibleSpace,button], animated: true) + toolBar.isUserInteractionEnabled = true + genreField!.inputAccessoryView = toolBar + + /* + documentController.getProfilesFromCloudKit { (profiles) in + for profile in profiles { + print(profile.name, profile.email, profile.genre) + } + } + uploadController.getPhotosFromCloudKit { (photos) in + for photo in photos { + if photo.email == self.emailField.text { + if let data = NSData(contentsOf: photo.fileURL) { + DispatchQueue.main.async { + self.settingImage.image = UIImage(data: data as Data) + } + } + } + } + } + */ + /* + uploadController.getUsersDataFromCloudKit { (usersData) in + for userData in usersData { + if userData.email == self.emailField.text { + if let data = NSData(contentsOf: userData.fileURL!) { + DispatchQueue.main.async { + self.nameField.text = userData.name + self.genreField.text = userData.genre + self.settingImage.image = UIImage(data: data as Data) + } + } + } + } + } + */ + + + } + + override func viewWillAppear(_ animated: Bool) { + if(isEditProfile) + { + updateField() + } + else + { + nameField.text = "" + genreField.text = "" + emailField.text = emailAddr + + settingImage.image = UIImage(systemName: "person.circle") + phoneNumberField.text = "" + instagramField.text = "" + } + super.viewWillAppear(animated) + } + + func updateField() + { + let data:UserDataStruct = DataManager.shared().currentUser! + nameField.text = data.name + genreField.text = data.genre + settingImage.image = data.profilePicture + phoneNumberField.text = data.phoneNumber + instagramField.text = data.instagram + } + + @IBAction func chooseGenre(_ sender: UIButton) { + let genreProfileVC = storyboard?.instantiateViewController(identifier: "GenreProfileVC") as! GenreProfileController + genreProfileVC.transitioningDelegate = self + genreProfileVC.modalPresentationStyle = .custom + genreProfileVC.modalTransitionStyle = .coverVertical + genreProfileVC.view.layer.cornerRadius = 34 + + self.present(genreProfileVC, animated: true, completion: nil) + } + + func handleLocalisation() { + settingTitleLabel.text = NSLocalizedString("Settings", comment: "") + nameTitleLabel.text = NSLocalizedString("Name".uppercased(), comment: "") + emailTitleLabel.text = NSLocalizedString("Email".uppercased(), comment: "") + genreTitleLabel.text = NSLocalizedString("Genre", comment: "") + saveButton.titleLabel?.text = NSLocalizedString("Save", comment: "") + phoneNumberLabel.text = NSLocalizedString("Phone Number", comment: "") + instagramLabel.text = NSLocalizedString("Instagram", comment: "") + + } + @IBAction func backButtonTouched(_ sender: Any) { + handleUnwind() + } + + func handleUnwind() + { + if(isEditProfile) + { + performSegue(withIdentifier: "unwindToUserProfile", sender: nil) + } + else + { + performSegue(withIdentifier: "unwindToRegister", sender: nil) + } + } + + @objc func handleUploadTap(_ sender: UITapGestureRecognizer? = nil) { + self.openCameraAndLibrary() + } + + @objc func handleGenreTap(_ sender: UITapGestureRecognizer? = nil) { + let genreProfileVC = storyboard?.instantiateViewController(identifier: "GenreProfileVC") as! GenreProfileController + genreProfileVC.transitioningDelegate = self + genreProfileVC.modalPresentationStyle = .custom + genreProfileVC.modalTransitionStyle = .coverVertical + genreProfileVC.view.layer.cornerRadius = 34 + + self.present(genreProfileVC, animated: true, completion: nil) + } + + @IBAction func logoutUser(_ sender: UIButton) { + loadAlert() + } + + @IBAction func saveSetting(_ sender: UIButton) { + if(isEditProfile) + { + // documentController.uploadProfile(name: nameField.text!, email: emailField.text!, genre: genreField.text!, myImage: settingImage.image!) + // uploadController.uploadPhoto(email: emailField.text!, myImage: settingImage.image!) + let data:UserDataStruct = DataManager.shared().currentUser! + data.name = nameField.text + data.genre = selectedGenre + data.profilePicture = settingImage.image + data.phoneNumber = phoneNumberField.text + data.instagram = instagramField.text + + let dataRec:CKRecord = DataManager.shared().currentUserRec! + dataRec.setValuesForKeys(data.asDict()) + + DataManager.shared().savecurrentUserRec() + handleUnwind() + + } + else + { + + let data:UserDataStruct = UserDataStruct() + data.name = nameField.text + data.genre = selectedGenre + data.profilePicture = settingImage.image + data.phoneNumber = phoneNumberField.text + data.instagram = instagramField.text + + // first time registering + DataManager.shared().registerToCloudKit(email: emailAddr, + password: password, + userData: data) + { (isSuccess, errorString, record) in + if(isSuccess) + { + DispatchQueue.main.async { + self.performSegue(withIdentifier: "userProfileSegue", sender: nil) + } + } + else + { + DispatchQueue.main.async { + print("ErrorString :\(errorString)") + let alert:UIAlertController = AlertViewHelper.createAlertView(type: .Error, + rightHandler: nil, + leftHandler: nil, + replacementString: [strKeyErrorMSG : errorString] + ) + self.present(alert, animated: true, completion: nil) + } + } + + } + + } + } + + @objc func action() { + view.endEditing(true) + } + + func loadAlert() { + // let alertTitle = NSLocalizedString("Welcome", comment: "") + let alertTitle = "Tiana Rosser" + let alertMessage = NSLocalizedString("Are you sure want to sign out?", comment: "") + let cancelButtonText = NSLocalizedString("Cancel", comment: "") + let signupButtonText = NSLocalizedString("Sign Out", comment: "") + + let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert) + let cancelAction = UIAlertAction(title: cancelButtonText, style: UIAlertAction.Style.cancel, handler: nil) + let signupAction = UIAlertAction(title: signupButtonText, style: UIAlertAction.Style.default, handler: { + (action: UIAlertAction) in + self.userDefault.removeObject(forKey: "email") + self.performSegue(withIdentifier: "logoutUser", sender: self) + }) + alert.addAction(cancelAction) + alert.addAction(signupAction) + self.present(alert, animated: true, completion: nil) + } + +} + +// Extension to make more structured +extension SettingController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { + // MARK: Func to open camera and library function + func openCameraAndLibrary() { + let imagePicker = UIImagePickerController() + imagePicker.delegate = self + let actionAlert = UIAlertController(title: NSLocalizedString("Browse attachment".uppercased(), comment: ""), message: "Choose source", preferredStyle: .alert) + actionAlert.addAction(UIAlertAction(title: NSLocalizedString("Camera".uppercased(), comment: ""), style: .default, handler: { + (action:UIAlertAction) in + if UIImagePickerController.isSourceTypeAvailable(.camera) { + imagePicker.sourceType = .camera + self.present(imagePicker, animated:true, completion: nil) + }else{ + print("Camera is not available at this device") + } + })) // give an option in alert controller to open camera + + actionAlert.addAction(UIAlertAction(title: NSLocalizedString("Photo library".uppercased(), comment: ""), style: .default, handler: { (action: UIAlertAction) in + imagePicker.sourceType = .photoLibrary + imagePicker.mediaTypes = ["public.image"] + self.present(imagePicker, animated:true, completion: nil) + })) // give the second option in alert controller to open Photo library + + actionAlert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)) // give the third option in alert controller to cancel the form + + self.present(actionAlert, animated: true, completion: nil) + } + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + // let videoURL = info[UIImagePickerController.InfoKey.phAsset] as? URL + // print(videoURL) + if let imageTaken = info[.originalImage] as? UIImage { + picker.dismiss(animated: true) { + self.settingImage?.image = imageTaken + } + } + } +} + +extension SettingController:UITextFieldDelegate +{ + func textFieldDidBeginEditing(_ textField: UITextField) { + + } +} + +extension SettingController:UIPickerViewDelegate, UIPickerViewDataSource +{ + func numberOfComponents(in pickerView: UIPickerView) -> Int { + 1 + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + musicGenreArray.count + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + musicGenreArray[row] + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + selectedGenre = musicGenreArray[row] + genreField?.text = selectedGenre + } + +} + +extension SettingController: UIViewControllerTransitioningDelegate { + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + return OverlayPresentationController(presentedViewController:presented, presenting:presenting) + } +} diff --git a/frontend/mobile/CommunityMC3/Setting View/SettingScreen.storyboard b/frontend/mobile/CommunityMC3/Setting View/SettingScreen.storyboard new file mode 100644 index 0000000..4936dc1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Setting View/SettingScreen.storyboard @@ -0,0 +1,684 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/SplashcreenLoading.storyboard b/frontend/mobile/CommunityMC3/SplashcreenLoading.storyboard new file mode 100644 index 0000000..26be0ef --- /dev/null +++ b/frontend/mobile/CommunityMC3/SplashcreenLoading.storyboard @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/Test File/dishes.mp3 b/frontend/mobile/CommunityMC3/Test File/dishes.mp3 new file mode 100644 index 0000000..34a3d95 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Test File/dishes.mp3 differ diff --git a/frontend/mobile/CommunityMC3/Test File/tiara.mp3 b/frontend/mobile/CommunityMC3/Test File/tiara.mp3 new file mode 100644 index 0000000..2321dc2 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Test File/tiara.mp3 differ diff --git a/frontend/mobile/CommunityMC3/Test File/yorushika.mp3 b/frontend/mobile/CommunityMC3/Test File/yorushika.mp3 new file mode 100644 index 0000000..da06619 Binary files /dev/null and b/frontend/mobile/CommunityMC3/Test File/yorushika.mp3 differ diff --git a/frontend/mobile/CommunityMC3/TrackPlayer View/TrackPlayer.storyboard b/frontend/mobile/CommunityMC3/TrackPlayer View/TrackPlayer.storyboard new file mode 100644 index 0000000..820bd52 --- /dev/null +++ b/frontend/mobile/CommunityMC3/TrackPlayer View/TrackPlayer.storyboard @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/TrackPlayer View/TrackPlayerViewController.swift b/frontend/mobile/CommunityMC3/TrackPlayer View/TrackPlayerViewController.swift new file mode 100644 index 0000000..2b2c482 --- /dev/null +++ b/frontend/mobile/CommunityMC3/TrackPlayer View/TrackPlayerViewController.swift @@ -0,0 +1,345 @@ +// +// TrackPlayerViewController.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVFoundation + +class TrackPlayerViewController: UIViewController, AVAudioPlayerDelegate{ + + @IBOutlet weak var trackCoverImageView: UIImageView! + @IBOutlet weak var trackTitleLabel: UILabel! + @IBOutlet weak var prevButton: UIButton! + @IBOutlet weak var nextButton: UIButton! + @IBOutlet weak var trackProgressSlider: UISlider! + @IBOutlet weak var trackCurrentTimeLabel: UILabel! + @IBOutlet weak var trackDurationLabel: UILabel! + @IBOutlet weak var repeatButtonNonActive: UIButton! + @IBOutlet weak var repeatButtonActive: UIButton! + @IBOutlet weak var repeatOneTrackOnlyButton: UIButton! + @IBOutlet weak var shuffleButton: UIButton! + @IBOutlet weak var artistButton: UIButton! + @IBOutlet weak var favoriteButton: UIButton! + @IBOutlet weak var playAndPauseButton: UIButton! + + var track: TrackDataStruct! + let documentController = DocumentTableViewController.shared + var email: String = "" + var tracks = [PrimitiveTrackDataStruct]() + + var trackPlayer: AVAudioPlayer? + var displayLink : CADisplayLink! = nil + var counter = 0 + var trackListTemp = [String]() + var trackShuffleTemp = [String]() + var trackPlaylist = [String]() + var repeatPlaylistBoolean = true + var playAndPauseBoolean = false + var miniTrackDelegate: MiniTrackPlayerDelegate? + + var favoriteBool: Bool { + return favoriteButton.isSelected + } + + override func viewDidLoad() { + super.viewDidLoad() + if let loadEmail = UserDefaults.standard.string(forKey: "email"){ + email = loadEmail + } + + navigationController?.setNavigationBarHidden(false, animated: false) + retreiveTrack() + retreiveFavorites() + prepareTrack() + prepareAndCustomizeSlider() + buttonStateChange() + receiveButtonState(state: playAndPauseBoolean) + trackDismiss() + } + + func receiveButtonState(state: Bool?){ + playAndPauseButton.isSelected = state! + } + + func trackDismiss(){ + if playAndPauseButton.isSelected == true{ + miniTrackDelegate?.miniTrackPlayerButtonState(state: true) + }else{ + miniTrackDelegate?.miniTrackPlayerButtonState(state: false) + } + self.dismiss(animated: true, completion: nil) + } + + func changeFavourites() { + let temp = PrimitiveTrackDataStruct( + genre: track.genre, + name: track.name, + email: track.email + ) + var counter = 0 + var flag = false + for track in tracks { + if track.name == self.track.name { + flag = true + tracks.remove(at: counter) + } + counter += 1 + } + if !flag { + tracks.append(temp) + } + + documentController.uploadFavorite(id: email, track: tracks) + } + + func retreiveFavorites() { + /* + documentController.getFavoritesFromCloudKit { (favourites) in + for favourite in favourites { + if self.email != "" && favourite.id == self.email { + self.tracks = favourite.track! + } + } + print("current", self.tracks.count) + for track in self.tracks { + if track.name == self.track.name { + DispatchQueue.main.async { + self.favoriteButton.isSelected = !self.favoriteButton.isSelected + } + } + } + } + */ + } + + func retreiveTrack() { + if track != nil { + trackTitleLabel.text = track.name + artistButton.setTitle(track.email, for: .normal) + } + } + + func prepareTrack() { + var error : NSError? = nil + if track != nil { + let audioPath = track.fileData!.fileURL + do { + trackPlayer = try AVAudioPlayer(contentsOf: audioPath!) + + } catch let error1 as NSError { + error = error1 + } + }else { + print("track nil") + let audioPath = Bundle.main.path(forResource: "\(trackPlaylist[counter])", ofType: "mp3")! + // let audioPath = Bundle.main.path(forResource: "", ofType: "mp3")! + + do { + trackPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath)) + } catch let error1 as NSError { + error = error1 + } + } + let seconds = Int(trackPlayer!.duration) + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute, .second] + formatter.unitsStyle = .positional + + let formattedString = formatter.string(from: TimeInterval(seconds))! + trackDurationLabel.text = "\(formattedString)" + print(seconds) + + print(trackProgressSlider.maximumValue) + displayLink = CADisplayLink(target: self, selector: #selector(updateAudioProgressView)) + displayLink.preferredFramesPerSecond = 1 + displayLink.add(to: RunLoop.current, forMode: RunLoop.Mode.default) + trackProgressSlider.setThumbImage(#imageLiteral(resourceName: "trackThumbTint"), for: .normal) + trackPlayer!.delegate = self + if error == nil { + trackPlayer!.delegate = self + trackPlayer!.prepareToPlay() + trackPlayer!.play() + } + } + + func prepareAndCustomizeSlider() { + //Slider customization + trackProgressSlider.setThumbImage(#imageLiteral(resourceName: "trackThumbTint"), for: .normal) + + //Slider display track progress + displayLink = CADisplayLink(target: self, selector: #selector(updateAudioProgressView)) + displayLink.preferredFramesPerSecond = 1 + displayLink.add(to: RunLoop.current, forMode: RunLoop.Mode.default) + } + + @objc func updateAudioProgressView() + { + if trackPlayer?.isPlaying == true + { + trackProgressSlider.minimumValue = 0.0 + trackProgressSlider.maximumValue = Float(trackPlayer!.duration) + trackProgressSlider.setValue(Float(trackPlayer!.currentTime), animated: true) + + let minute = Int(trackPlayer!.duration / 60) + let second = Int(trackPlayer!.duration) - minute * 60 + + trackCurrentTimeLabel.text = "\(minute):\(String(format: "%2d", second))" + } + } + + func buttonStateChange(){ + + favoriteButton.setImage(#imageLiteral(resourceName: "HeartUnfill"), for: .normal) + favoriteButton.setImage(#imageLiteral(resourceName: "HeartFill"), for: .selected) + + playAndPauseButton.setImage(#imageLiteral(resourceName: "Play"), for: .normal) + playAndPauseButton.setImage(#imageLiteral(resourceName: "pause"), for: .selected) + + shuffleButton.setImage(#imageLiteral(resourceName: "shuffle"), for: .normal) + shuffleButton.setImage(#imageLiteral(resourceName: "shuffleActive"), for: .selected) + } + + func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool){ + + if flag { + counter+=1 + } + + if (counter == trackPlaylist.count) { + counter = 0 + } + prepareTrack() + } + + + + @IBAction func pauseAndPlayButtonAction(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + + if sender.isSelected == true{ + trackPlayer!.play() + playAndPauseButton.isSelected = true + }else{ + trackPlayer!.pause() + playAndPauseButton.isSelected = false + } + } + + @IBAction func prevAndNextButtonAction(_ sender: UIButton) { + if sender == prevButton{ + if counter == 0{ + trackPlayer!.currentTime = 0 + trackPlayer!.play() + }else{ + counter -= 1 + prepareTrack() + } + }else if sender == nextButton{ + if counter == trackPlaylist.count-1 { + if repeatPlaylistBoolean == true{ + counter = 0 + prepareTrack() + }else { + counter = 0 + prepareTrack() + trackPlayer!.currentTime = 0 + trackPlayer!.stop() + playAndPauseButton.isSelected = false + } + }else{ + counter += 1 + prepareTrack() + } + } + } + + @IBAction func trackProgressSliderAction(_ sender: UISlider) { + trackPlayer!.stop() + trackPlayer!.currentTime = TimeInterval(trackProgressSlider.value) + trackPlayer!.prepareToPlay() + trackPlayer!.play() + trackCurrentTimeLabel.text = "\( TimeInterval(trackProgressSlider.value))" + } + + @IBAction func repeatButtonAction(_ sender: UIButton) { + if sender == repeatButtonNonActive { + repeatOneTrackOnlyButton.isHidden = true + repeatButtonActive.isHidden = false + repeatButtonNonActive.isHidden = true + + repeatPlaylistBoolean = true + }else if sender == repeatButtonActive{ + repeatButtonNonActive.isHidden = true + repeatButtonActive.isHidden = true + repeatOneTrackOnlyButton.isHidden = false + + repeatPlaylistBoolean = false + trackPlayer!.numberOfLoops = -1 + }else if sender == repeatOneTrackOnlyButton{ + repeatOneTrackOnlyButton.isHidden = true + repeatButtonNonActive.isHidden = true + repeatButtonNonActive.isHidden = false + + repeatPlaylistBoolean = false + trackPlayer!.numberOfLoops = 0 + } + } + + @IBAction func shuffleButtonAction(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + + if sender.isSelected == true{ + shuffleButton.isSelected = true + + trackPlaylist.removeAll() + trackPlaylist.append(contentsOf: trackListTemp) + + trackShuffleTemp.removeAll() + trackShuffleTemp.append(contentsOf: trackListTemp) + trackShuffleTemp.shuffle() + trackPlaylist.removeAll() + trackPlaylist.append(contentsOf: (trackShuffleTemp)) + }else{ + shuffleButton.isSelected = false + + trackPlaylist.removeAll() + trackPlaylist.append(contentsOf: trackListTemp) + + trackShuffleTemp.removeAll() + trackShuffleTemp.append(contentsOf: trackListTemp) + trackShuffleTemp.shuffle() + trackPlaylist.removeAll() + trackPlaylist.append(contentsOf: (trackShuffleTemp)) + } + } + + @IBAction func artistButton(_ sender: UIButton) { + + } + + @IBAction func favoriteButtonAction(_ sender: UIButton) { + favoriteButton.isSelected = !favoriteButton.isSelected + changeFavourites() + print(favoriteBool) + } + + @IBAction func dismissButton(_ sender: UIButton) { + if playAndPauseButton.isSelected == true{ + miniTrackDelegate?.miniTrackPlayerButtonState(state: true) + }else{ + miniTrackDelegate?.miniTrackPlayerButtonState(state: false) + } + + dismiss(animated: true, completion: nil) + } + +// override func viewWillDisappear(_ animated: Bool) { +// navigationController?.setNavigationBarHidden(true, animated: false) +// trackPlayer?.stop() +// super .viewWillDisappear(animated) +// } +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Album /AlbumSelectorVC.swift b/frontend/mobile/CommunityMC3/UploadFileView/Album /AlbumSelectorVC.swift new file mode 100644 index 0000000..7293ede --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Album /AlbumSelectorVC.swift @@ -0,0 +1,63 @@ +// +// AlbumSelectorVC.swift +// CommunityMC3 +// +// Created by Bernardinus on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import CloudKit + +class AlbumSelectorVC: UIViewController { + + var albumArr:[CKRecord]? = [] + + @IBOutlet weak var availableAlbumTable: UITableView! + @IBOutlet weak var titleLabel: UILabel! + + override func viewDidLoad() { + super.viewDidLoad() + + // Uncomment the following line to preserve selection between presentations + // self.clearsSelectionOnViewWillAppear = false + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem + titleLabel.text = NSLocalizedString("Album".uppercased(), comment: "") + availableAlbumTable.register(albumListTableViewCell.nib(), forCellReuseIdentifier: albumListTableViewCell.identifier) + } + + func UpdateAlbum() + { + + } + +} + +extension AlbumSelectorVC:UITableViewDelegate, UITableViewDataSource +{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return albumArr!.count+1 + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + 87 + } + + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let customCell = tableView.dequeueReusableCell(withIdentifier: albumListTableViewCell.identifier, for : indexPath) as! albumListTableViewCell + // customCell.configure(with: "Album title", imageName: "no_album") + + if(indexPath.row > 0) + { + + } + + return customCell + + } + + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Album /albumListTableViewCell.swift b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumListTableViewCell.swift new file mode 100644 index 0000000..4024446 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumListTableViewCell.swift @@ -0,0 +1,47 @@ +// +// albumListTableViewCell.swift +// MC3 Table View Test +// +// Created by Nur Minnuri Qalbi on 22/07/20. +// Copyright © 2020 Nur Minnuri Qalbi. All rights reserved. +// + +import UIKit + +class albumListTableViewCell: UITableViewCell { + + + static let identifier = "albumListTableViewCell" + + static func nib() -> UINib { + return UINib(nibName: "albumListTableViewCell", bundle: nil) + } + + public func configure (with title: String, imageName: String) { + albumTitleLabel.text = title + albumTrackLabel.text = title + albumCoverImage.image = UIImage(named: imageName) + } + + @IBOutlet weak var albumCoverImage: UIImageView! + @IBOutlet weak var albumTitleLabel: UILabel! + @IBOutlet weak var albumTrackLabel: UILabel! + @IBOutlet weak var noAlbumTextField: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + albumCoverImage.image = UIImage(named: "no_album") + albumTitleLabel.isHidden = true + albumTrackLabel.isHidden = true + noAlbumTextField.isHidden = false + selectionStyle = .none + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Album /albumListTableViewCell.xib b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumListTableViewCell.xib new file mode 100644 index 0000000..3030704 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumListTableViewCell.xib @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Album /albumTitleTableViewCell.swift b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumTitleTableViewCell.swift new file mode 100644 index 0000000..86a38ae --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumTitleTableViewCell.swift @@ -0,0 +1,40 @@ +// +// albumTitleTableViewCell.swift +// MC3 Table View Test +// +// Created by Nur Minnuri Qalbi on 22/07/20. +// Copyright © 2020 Nur Minnuri Qalbi. All rights reserved. +// + +import UIKit + +class albumTitleTableViewCell: UITableViewCell { + + + static let identifier = "albumTitleTableViewCell" + + static func nib() -> UINib { + return UINib(nibName: "albumTitleTableViewCell", bundle: nil) + } + + public func configure (with title: String, imageName: String) { + albumTitleLabel.text = title + + } + + @IBOutlet var albumTitleLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + selectionStyle = .none + albumTitleLabel.text = NSLocalizedString("Album".uppercased(), comment: "") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Album /albumTitleTableViewCell.xib b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumTitleTableViewCell.xib new file mode 100644 index 0000000..846cee6 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Album /albumTitleTableViewCell.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Description/descTitleTableViewCell.swift b/frontend/mobile/CommunityMC3/UploadFileView/Description/descTitleTableViewCell.swift new file mode 100644 index 0000000..0018d94 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Description/descTitleTableViewCell.swift @@ -0,0 +1,46 @@ +// +// descTitleTableViewCell.swift +// MC3 Table View Test +// +// Created by Nur Minnuri Qalbi on 22/07/20. +// Copyright © 2020 Nur Minnuri Qalbi. All rights reserved. +// + +import UIKit + +class descTitleTableViewCell: UITableViewCell { + + static let identifier = "descTitleTableViewCell" + @IBOutlet weak var descTextView: UITextView! + + static func nib() -> UINib { + return UINib(nibName: "descTitleTableViewCell", bundle: nil) + } + + public func configure (with title: String, imageName: String) { + descTitleLabel.text = title + } + + @IBOutlet var descTitleLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + descTitleLabel.text = NSLocalizedString("Description".uppercased(), comment: "") + + descTextView.text = "" + descTextView.layer.borderWidth = 1 + descTextView.layer.cornerRadius = 5 + descTextView.layer.borderColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1) + + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Description/descTitleTableViewCell.xib b/frontend/mobile/CommunityMC3/UploadFileView/Description/descTitleTableViewCell.xib new file mode 100644 index 0000000..a8f2a04 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Description/descTitleTableViewCell.xib @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Genre/GenreTableViewCell.swift b/frontend/mobile/CommunityMC3/UploadFileView/Genre/GenreTableViewCell.swift new file mode 100644 index 0000000..3bc7675 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Genre/GenreTableViewCell.swift @@ -0,0 +1,41 @@ +// +// GenreTableViewCell.swift +// MC3 Table View Test +// +// Created by Nur Minnuri Qalbi on 22/07/20. +// Copyright © 2020 Nur Minnuri Qalbi. All rights reserved. +// + +import UIKit + +class GenreTableViewCell: UITableViewCell { + + static let identifier = "GenreTableViewCell" + @IBOutlet weak var genreTextField: UITextField! + + static func nib() -> UINib { + return UINib(nibName: "GenreTableViewCell", bundle: nil) + } + + public func configure (with label: String, title: String) { + genreLabel.text = label + //genreTextField.text = title + } + + @IBOutlet var genreLabel: UILabel! +// @IBOutlet var genreTextField: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + selectionStyle = .none + genreLabel.text = NSLocalizedString("Genre", comment: "") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Genre/GenreTableViewCell.xib b/frontend/mobile/CommunityMC3/UploadFileView/Genre/GenreTableViewCell.xib new file mode 100644 index 0000000..6b62183 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Genre/GenreTableViewCell.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Upload track/AddCoverTableViewCell.swift b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/AddCoverTableViewCell.swift new file mode 100644 index 0000000..c57f80a --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/AddCoverTableViewCell.swift @@ -0,0 +1,41 @@ +// +// AddCoverTableViewCell.swift +// MC3 Table View Test +// +// Created by Nur Minnuri Qalbi on 20/07/20. +// Copyright © 2020 Nur Minnuri Qalbi. All rights reserved. +// + +import UIKit + +class AddCoverTableViewCell: UITableViewCell { + + static let identifier = "AddCoverTableViewCell" + + static func nib() -> UINib { + return UINib(nibName: "AddCoverTableViewCell", bundle: nil) + } + + public func configure (with title: String, imageName: String) + { + addCoverLabel.text = title + addCoverImage.image = UIImage(named: imageName) + } + + @IBOutlet var addCoverImage: UIImageView! + @IBOutlet var addCoverLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + selectionStyle = .none + addCoverLabel.text = "Cover image" + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Upload track/AddCoverTableViewCell.xib b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/AddCoverTableViewCell.xib new file mode 100644 index 0000000..97a1d83 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/AddCoverTableViewCell.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Upload track/UploadTableViewCell.swift b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/UploadTableViewCell.swift new file mode 100644 index 0000000..0605e1c --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/UploadTableViewCell.swift @@ -0,0 +1,44 @@ +// +// UploadTableViewCell.swift +// MC3 Table View Test +// +// Created by Nur Minnuri Qalbi on 20/07/20. +// Copyright © 2020 Nur Minnuri Qalbi. All rights reserved. +// + +import UIKit + +class UploadTableViewCell: UITableViewCell { + + static let identifier = "UploadTableViewCell" + + static func nib() -> UINib { + return UINib(nibName: "UploadTableViewCell", bundle: nil) + } + + public func configure (with title: String, imageName: String) { + trackCoverTextField.text = title + //trackCoverImage.image = UIImage(systemName: imageName) + trackCoverImage.image = UIImage(named: imageName) + } + + @IBOutlet var trackCoverImage: UIImageView! + @IBOutlet var trackCoverTextField: UITextField! + + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + trackCoverTextField.text = "" + trackCoverTextField.placeholder = NSLocalizedString("Write the title".uppercased(), comment: "") + trackCoverImage.image = UIImage(named: "playButton") + selectionStyle = .none + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/Upload track/UploadTableViewCell.xib b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/UploadTableViewCell.xib new file mode 100644 index 0000000..93262b9 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/Upload track/UploadTableViewCell.xib @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/UploadFileHeaderCell/UploadFileHeaderCell.swift b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileHeaderCell/UploadFileHeaderCell.swift new file mode 100644 index 0000000..7f4e2c3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileHeaderCell/UploadFileHeaderCell.swift @@ -0,0 +1,31 @@ +// +// UploadFileHeaderCell.swift +// CommunityMC3 +// +// Created by Bernardinus on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit + +class UploadFileHeaderCell: UITableViewCell { + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + selectionStyle = .none + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + static let identifier = "uploadFileHeaderCell" + + static func nib() -> UINib { + return UINib(nibName: "uploadFileHeaderCell", bundle: nil) + } + +} diff --git a/frontend/mobile/CommunityMC3/UploadFileView/UploadFileHeaderCell/UploadFileHeaderCell.xib b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileHeaderCell/UploadFileHeaderCell.xib new file mode 100644 index 0000000..6f50d8e --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileHeaderCell/UploadFileHeaderCell.xib @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/UploadFileView.storyboard b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileView.storyboard new file mode 100644 index 0000000..e4d0fbb --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileView.storyboard @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/UploadFileView/UploadFileView.swift b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileView.swift new file mode 100644 index 0000000..ba393af --- /dev/null +++ b/frontend/mobile/CommunityMC3/UploadFileView/UploadFileView.swift @@ -0,0 +1,357 @@ +// +// ViewController.swift +// MC3 Table View Test +// +// Created by Nur Minnuri Qalbi on 20/07/20. +// Copyright © 2020 Nur Minnuri Qalbi. All rights reserved. +// + +import UIKit +import CloudKit + +class UploadFileView: UIViewController +{ + @IBOutlet var table: UITableView! + @IBOutlet weak var cancel: UIButton! + @IBOutlet weak var uploadFileTitleLabel: UILabel! + @IBOutlet weak var postButton: UIButton! + + var videoData:VideosDataStruct? + var trackData:TrackDataStruct? + var isUploadVideo:Bool = false + + var cvrImg:UIImage? = nil + var coverImage:UIImageView? + var tapRecognizer:UIGestureRecognizer? + + var imgPicker:ImagePicker? + + var fileURL:URL? + var nameTextField:UITextField? + // genre + var selectedGenre:String = "" + var genreTextField:UITextField? + var pickerView:UIPickerView = UIPickerView() + + var selectedAlbum:CKRecord? = nil + + override func viewDidLoad() + { + super.viewDidLoad() + self.dismissKeyboard() + imgPicker = ImagePicker(presentationController: self, delegate: self) + + pickerView.delegate = self + prepareLocalisation() + uploadFileTitleLabel.text = NSLocalizedString("Upload".uppercased(), comment: "") + + table.register(UploadTableViewCell.nib(), forCellReuseIdentifier: UploadTableViewCell.identifier) + table.register(AddCoverTableViewCell.nib(), forCellReuseIdentifier: AddCoverTableViewCell.identifier) + table.register(GenreTableViewCell.nib(), forCellReuseIdentifier: GenreTableViewCell.identifier) + table.register(albumTitleTableViewCell.nib(), forCellReuseIdentifier: albumTitleTableViewCell.identifier) + table.register(albumListTableViewCell.nib(), forCellReuseIdentifier: albumListTableViewCell.identifier) + table.register(descTitleTableViewCell.nib(), forCellReuseIdentifier: descTitleTableViewCell.identifier) + table.register(UploadFileHeaderCell.nib(), forCellReuseIdentifier: UploadFileHeaderCell.identifier) + + table.delegate = self + table.dataSource = self + table.isScrollEnabled = false + // table.allowsSelection = false + + table.separatorColor = UIColor.clear + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + func prepareLocalisation() { + cancel.titleLabel?.text = NSLocalizedString("Cancel", comment: "") + postButton.titleLabel?.text = NSLocalizedString("Post".uppercased(), comment: "") + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "selectAlbum" + { + let saVC = segue.destination as! AlbumSelectorVC + saVC.UpdateAlbum() + } + } + + func prepareData(isUploadVideo:Bool,fileURL:URL) + { + self.isUploadVideo = isUploadVideo + self.fileURL = fileURL + cvrImg = nil + if isUploadVideo + { + cvrImg = generateThumbnail(path: fileURL) + } + } + + @IBAction func unwindToUploadFile(_ segue:UIStoryboardSegue) + { + if segue.identifier == "selectAlbum" + { +// segue.source + table.reloadData() + } + } + + @IBAction func cancelButtonTouched(_ sender: Any) { + dismiss(animated: true, completion: nil) + } + + @objc func didChangeSwitch(_ sender: UISwitch!) + { + if sender.isOn + { + print("Cover song selected") + } + else + { + print("Cover song not selected") + } + + } + + @IBAction func uploadFileButtonTouched() + { + // documentController.uploadTrack(email: "mnb@mnb", genre: "Rock", name: "track", fileURL: filteredList[indexPath.row]) + if isUploadVideo + { + var videoData = VideosDataStruct( + genre: genreTextField!.text!, + name: nameTextField!.text!, + email: (DataManager.shared().currentUser?.email!)!, + fileURL: fileURL!) + videoData.coverImage = coverImage?.image + + DataManager.shared().UploadNewVideo(videoData:videoData) { (isSuccess, errorString) in + if isSuccess + { + print("Upload Video File Success") + + +// self.dismiss(animated: true, completion: nil) + DispatchQueue.main.async { + self.view.window!.rootViewController?.dismiss(animated: true, completion: nil) + } + + + } + else + { + print("Upload Video File Failed") + AlertViewHelper.creteErrorAlert(errorString: "UploadVideoFile Failed \(errorString)", view: self) + } + } + } + else + { + trackData = TrackDataStruct( + genre: genreTextField!.text!, + name: nameTextField!.text!, + email: (DataManager.shared().currentUser?.email!)!, + fileURL: fileURL!) + trackData?.coverImage = coverImage?.image + + DataManager.shared().UploadNewTrack(trackData:trackData!) { (isSuccess, errorString) in + if isSuccess + { + print("Upload File Success") + DispatchQueue.main.async { + self.view.window!.rootViewController?.dismiss(animated: true, completion: nil) + } + } + else + { + AlertViewHelper.creteErrorAlert(errorString: "UploadTrackFile Failed \(errorString)", view: self) + + } + } + } + } + +} + +// MARK: EXTENSION +extension UploadFileView:ImagePickerDelegate +{ + func didSelect(image: UIImage?) + { + coverImage?.image = image + } +} + +extension UploadFileView:UITextViewDelegate +{ + +} + +extension UploadFileView:UITableViewDelegate, UITableViewDataSource +{ + // func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { + // false + // } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.row == 1 + { + imgPicker?.present(from: self.view) + } + else if indexPath.row == 3 + { + print("select album") + performSegue(withIdentifier: "selectAlbum", sender: nil) + } + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int + { + return 7 + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if indexPath.row == 0 + { + return 85 // 70 + } + if indexPath.row == 1 + { + return 87 // 70 + } + if indexPath.row == 2 // Album Header + { + return 0//46 + } + if indexPath.row == 3 + { + return 0//87 + } + if indexPath.row == 4 // Genre Selector + { + return 110 + } + if indexPath.row == 5 + { + + return 0//225 + } + if indexPath.row == 6 + { + + return 44 + } + return 44 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell + { + if indexPath.row == 0 + { + let customCell = tableView.dequeueReusableCell(withIdentifier: UploadTableViewCell.identifier, for : indexPath) as! UploadTableViewCell + nameTextField = customCell.trackCoverTextField + + return customCell + + } + else if indexPath.row == 1 + { + let customCell = tableView.dequeueReusableCell(withIdentifier: AddCoverTableViewCell.identifier, for : indexPath) as! AddCoverTableViewCell + // customCell.configure(with: "Add Cover", imageName: "camera 1") + + coverImage = customCell.addCoverImage + coverImage!.image = cvrImg + + + return customCell + } + else if indexPath.row == 2 // Album Header + { + let customCell = tableView.dequeueReusableCell(withIdentifier: albumTitleTableViewCell.identifier, for : indexPath) as! albumTitleTableViewCell + // customCell.configure(with: "ALBUM", imageName: "picture") + + return customCell + } + else if indexPath.row == 3 // Album Title + { + let customCell = tableView.dequeueReusableCell(withIdentifier: albumListTableViewCell.identifier, for : indexPath) as! albumListTableViewCell + // customCell.configure(with: "Album title", imageName: "no_album") + return customCell + } + else if indexPath.row == 4 // Genre + { + let customCell = tableView.dequeueReusableCell(withIdentifier: GenreTableViewCell.identifier, for : indexPath) as! GenreTableViewCell + // customCell.configure(with: "GENRE", title: "choose the genre") + + genreTextField = customCell.genreTextField + genreTextField?.delegate = self + genreTextField?.inputView = pickerView + + let toolBar = UIToolbar() + toolBar.sizeToFit() + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let button = UIBarButtonItem(title: NSLocalizedString("Done".uppercased(), comment: ""), style: .plain, target: self, action: #selector(self.action)) + toolBar.setItems([flexibleSpace,button], animated: true) + toolBar.isUserInteractionEnabled = true + genreTextField!.inputAccessoryView = toolBar + + + return customCell + } + else if indexPath.row == 5 // Description + { + let customCell = tableView.dequeueReusableCell(withIdentifier: descTitleTableViewCell.identifier, for : indexPath) as! descTitleTableViewCell + customCell.descTextView.delegate = self + // customCell.configure(with: "DESCRIPTION", imageName: "Write a description") + return customCell + } + else + { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) + cell.textLabel?.text = NSLocalizedString("Cover Song".uppercased(), comment: "") + + let switchView = UISwitch(frame: .zero) + switchView.setOn(false, animated: true) + switchView.tag = indexPath.row // for detect which row switch Changed + switchView.addTarget(self, action: #selector(self.didChangeSwitch(_:)), for: .valueChanged) + cell.accessoryView = switchView + + return cell + } + + } + @objc func action() { + view.endEditing(true) + } + +} + +extension UploadFileView:UITextFieldDelegate +{ + func textFieldDidBeginEditing(_ textField: UITextField) { + + } +} + +extension UploadFileView:UIPickerViewDelegate, UIPickerViewDataSource +{ + func numberOfComponents(in pickerView: UIPickerView) -> Int { + 1 + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + musicGenreArray.count + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + musicGenreArray[row] + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + selectedGenre = musicGenreArray[row] + genreTextField?.text = selectedGenre + } + +} diff --git a/frontend/mobile/CommunityMC3/Utilities/AlertViewHelper.swift b/frontend/mobile/CommunityMC3/Utilities/AlertViewHelper.swift new file mode 100644 index 0000000..07555a2 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/AlertViewHelper.swift @@ -0,0 +1,122 @@ +// +// AlertViewHelper.swift +// CommunityMC3 +// +// Created by Bernardinus on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit + +enum AlertViewType +{ + case OK + case Error + case ConfirmExitEditing + case SignOut +} + +// custom key +//var strKeyMilestone = "#milestone" +var strKeyErrorMSG = "#errorMSG" +var strKeyOK_TITLE = "#ok_TITLE" +var strKeyOK_MSG = "#ok_MSG" + + +class AlertViewHelper +{ + var a:(()->Void)? = nil + + class func creteAlert(_ view:UIViewController, title:String, msg:String) + { + let alert:UIAlertController = AlertViewHelper.createAlertView(type: .OK, + rightHandler: nil, + leftHandler: nil, + replacementString: [strKeyOK_MSG : msg, strKeyOK_TITLE:title] + ) + view.present(alert,animated: true, completion: nil) + } + + class func creteErrorAlert(errorString:String, view:UIViewController) -> UIAlertController + { + let alert:UIAlertController = AlertViewHelper.createAlertView(type: .Error, + rightHandler: nil, + leftHandler: nil, + replacementString: [strKeyErrorMSG : errorString] + ) + view.present(alert,animated: true, completion: nil) + return alert + } + + class func createAlertView(type:AlertViewType, + rightHandler:((UIAlertAction) -> Void)? = nil, + leftHandler:((UIAlertAction) -> Void)? = nil, + replacementString:[String:String] = [:] + ) -> UIAlertController + { + var alertView:UIAlertController = UIAlertController(title: "", message: "", preferredStyle: .alert) + loadAlertCopy(type, &(alertView.title)!, &(alertView.message)!) + loadAlertAction(type, &alertView, rightCompletionHandler: rightHandler, leftCompletionHandler: leftHandler) + + if replacementString.count > 0 + { + for item in replacementString + { + alertView.title = alertView.title?.replacingOccurrences(of: item.key, with: item.value) + alertView.message = alertView.message?.replacingOccurrences(of: item.key, with: item.value) + } + } + + + return alertView + } + + internal class func loadAlertCopy(_ type:AlertViewType,_ alertTitle:inout String, _ alertMSG:inout String) + { + switch type + { + + // Approve project + case .ConfirmExitEditing: + alertTitle = "Exit edit mode" + alertMSG = "You will lose all your edited data" + case .Error: + alertTitle = "Error" + alertMSG = strKeyErrorMSG + case .OK: + alertTitle = strKeyOK_TITLE + alertMSG = strKeyOK_MSG + case .SignOut : + alertTitle = "Sign out" + alertMSG = "Are you sure?" + + } + + } + + internal class func loadAlertAction(_ type:AlertViewType, + _ alertView:inout UIAlertController, + rightCompletionHandler:((UIAlertAction) -> Void)?, + leftCompletionHandler:((UIAlertAction) -> Void)? + ) + { + switch type + { + case .ConfirmExitEditing: + let rightAction:UIAlertAction = UIAlertAction(title: "Yes", style: .default, handler: rightCompletionHandler) + alertView.addAction(rightAction) + let leftAction:UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel, handler: leftCompletionHandler) + alertView.addAction(leftAction) + case .SignOut: + let rightAction:UIAlertAction = UIAlertAction(title: "Yes", style: .destructive, handler: rightCompletionHandler) + alertView.addAction(rightAction) + let leftAction:UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel, handler: leftCompletionHandler) + alertView.addAction(leftAction) + default: + let okAction:UIAlertAction = UIAlertAction(title: "OK", style: .default, handler: rightCompletionHandler) + alertView.addAction(okAction) + } + } +} + diff --git a/frontend/mobile/CommunityMC3/Utilities/CloudKitUtil.swift b/frontend/mobile/CommunityMC3/Utilities/CloudKitUtil.swift new file mode 100644 index 0000000..9547e41 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/CloudKitUtil.swift @@ -0,0 +1,98 @@ +// +// CloudKitUtil.swift +// CommunityMC3 +// +// Created by Bernardinus on 29/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import CloudKit + +class CloudKitUtil +{ + private static var instance:CloudKitUtil! + static func shared() -> CloudKitUtil + { + if instance == nil + { + instance = CloudKitUtil() + } + return instance + } + + var container:CKContainer? + var publicDB:CKDatabase? + + + + private init() + { + + } + + func setup(cloudKitContainerID:String) + { + container = CKContainer(identifier: cloudKitContainerID) + publicDB = container?.publicCloudDatabase + } + + func saveRecordToPublicDB(record:CKRecord,completionHandler:@escaping (Bool, String, CKRecord?)->Void) + { + publicDB?.save(record, completionHandler: { (record, error) in + if let error = error + { + completionHandler(false, error.localizedDescription, nil) + } + else + { + completionHandler(true, "Success", record) + } + }) + } + + func loadRecordFromPublicDB(query:CKQuery, completionHandler:@escaping(Bool, String, [CKRecord])->Void) + { + publicDB?.perform(query, inZoneWith: nil, completionHandler: { (records, error) in + if error != nil + { + completionHandler(false, error!.localizedDescription, []) + } + else + { + completionHandler(true, "Success", records!) + } + }) + } + + func loadRecordFromPublicDB(recordID:CKRecord.ID, completionHandler:@escaping(Bool, String, CKRecord?)->Void) + { + publicDB?.fetch(withRecordID: recordID, completionHandler: { (record, error) in + if error != nil + { + completionHandler(false, error!.localizedDescription,nil) + } + else + { + completionHandler(true, "", record) + } + }) + } + + func loadRecordFromPublicDB(recordType:String,recordName:[CKRecord.Reference], completionHandler:@escaping(Bool, String, [CKRecord])->Void) + { + let predicate = NSPredicate(format: "recordID IN %@", recordName) + let query = CKQuery(recordType: recordType, predicate: predicate) + publicDB?.perform(query, inZoneWith: nil, completionHandler: { (records, error) in + if error != nil + { + completionHandler(false, error!.localizedDescription, []) + } + else + { + completionHandler(true, "Success", records!) + } + }) + } + +} diff --git a/frontend/mobile/CommunityMC3/Utilities/CoreDataHelper.swift b/frontend/mobile/CommunityMC3/Utilities/CoreDataHelper.swift new file mode 100644 index 0000000..34c6b06 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/CoreDataHelper.swift @@ -0,0 +1,144 @@ +// +// CoreDataHelper.swift +// CommunityMC3 +// +// Created by Bernardinus on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import CoreData +import UIKit + +/* + struct CoreDataHelper { + var context: NSManagedObjectContext + + func fetchAll() -> [T] { + let request = T.fetchRequest() + do { + return try context.fetch(request) as? [T] ?? [] + } catch { + return [] + } + } + } + */ + + +class CoreDataHelper +{ + private static var instance:CoreDataHelper! + + internal static func shared() -> CoreDataHelper + { + if instance == nil + { + instance = CoreDataHelper() + } + return instance + } + + var persistentContainer:NSPersistentContainer + var objContext:NSManagedObjectContext + + private init() + { + persistentContainer = NSPersistentContainer(name: "FreelancerApp") + persistentContainer.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error as NSError?{ + print(error) + } + print(storeDescription) + }) + + objContext = persistentContainer.viewContext + } + + + static func fetchAll(_ entity:String) -> [T] + { + let request = NSFetchRequest(entityName: entity) + let result = try? shared().objContext.fetch(request) + return result as? [T] ?? [] + } + + // return all data in full + static func fetchFullData(_ entity:String) -> [T] + { + let request = NSFetchRequest(entityName: entity) + request.returnsObjectsAsFaults = false + let result = try? shared().objContext.fetch(request) + return result as? [T] ?? [] + } + + static func fetchQuery(_ entity:String, predicate:NSPredicate) -> [T] + { + let request = NSFetchRequest(entityName: entity) + request.predicate = predicate + request.returnsObjectsAsFaults = false + + var result:[T] + do { + + result = try shared().objContext.fetch(request) + } catch let error as NSError{ + + print("FetchError : \(error)") + return [] + } + + return result as? [T] ?? [] + + } + + static func save(value:[String:Any]) -> T? + { + let model = T(context: shared().objContext) + + for (k,v) in value + { + model.setValue(v, forKey: k) + } + + do{ + try shared().objContext.save() + return model + } catch{ + return nil + } + + } + + + static func saveData() + { + if shared().objContext.hasChanges { + do { + try shared().objContext.save() + } catch { + let nserror = error as NSError + fatalError("Unresolved error \(nserror), \(nserror.userInfo)") + } + } + } + + static func deleteAllRecords(in entityName:String) + { + let request = NSFetchRequest(entityName: entityName) + let deleteRequest = NSBatchDeleteRequest(fetchRequest: request) + let _ = try? shared().objContext.execute(deleteRequest) + } + + // static func deleteAllRecords() + // { + // let model:NSManagedObjectModel = NSManagedObjectModel.mergedModel(from: nil)! + // for entity in model.entities + // { + // + // deleteAllRecords(in: "\(entity.name)") + // } + // + // } + +} diff --git a/frontend/mobile/CommunityMC3/Utilities/FileSystemManager.swift b/frontend/mobile/CommunityMC3/Utilities/FileSystemManager.swift new file mode 100644 index 0000000..eb74851 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/FileSystemManager.swift @@ -0,0 +1,355 @@ +// +// FileSystemManager.swift +// iOS File Management +// +// Created by Andrew L. Jaffee on 4/20/18. +// +/* + + Copyright (c) 2018 Andrew L. Jaffee, microIT Infrastructure, LLC, and iosbrain.com. + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +import Foundation + +enum AppDirectories : String +{ + case Documents = "Documents" + case Inbox = "Inbox" + case Library = "Library" + case Temp = "tmp" +} + +protocol AppDirectoryNames +{ + func documentsDirectoryURL() -> URL + + func inboxDirectoryURL() -> URL + + func libraryDirectoryURL() -> URL + + func tempDirectoryURL() -> URL + + func getURL(for directory: AppDirectories) -> URL + + func buildFullPath(forFileName name: String, inDirectory directory: AppDirectories) -> URL +} // end protocol AppDirectoryNames + +extension AppDirectoryNames +{ + func documentsDirectoryURL() -> URL + { + return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + //return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] + } + + func inboxDirectoryURL() -> URL + { + return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(AppDirectories.Inbox.rawValue) // "Inbox") + } + + func libraryDirectoryURL() -> URL + { + return FileManager.default.urls(for: FileManager.SearchPathDirectory.libraryDirectory, in: .userDomainMask).first! + } + + func tempDirectoryURL() -> URL + { + return FileManager.default.temporaryDirectory + //urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(AppDirectories.Temp.rawValue) //"tmp") + } + + func getURL(for directory: AppDirectories) -> URL + { + switch directory + { + case .Documents: + return documentsDirectoryURL() + case .Inbox: + return inboxDirectoryURL() + case .Library: + return libraryDirectoryURL() + case .Temp: + return tempDirectoryURL() + } + } + + func buildFullPath(forFileName name: String, inDirectory directory: AppDirectories) -> URL + { + return getURL(for: directory).appendingPathComponent(name) + } +} // end extension AppDirectoryNames + +protocol AppFileStatusChecking +{ + func isWritable(file at: URL) -> Bool + + func isReadable(file at: URL) -> Bool + + func exists(file at: URL) -> Bool +} + +extension AppFileStatusChecking +{ + func isWritable(file at: URL) -> Bool + { + if FileManager.default.isWritableFile(atPath: at.path) + { + print(at.path) + return true + } + else + { + print(at.path) + return false + } + } + + func isReadable(file at: URL) -> Bool + { + if FileManager.default.isReadableFile(atPath: at.path) + { + print(at.path) + return true + } + else + { + print(at.path) + return false + } + } + + func exists(file at: URL) -> Bool + { + if FileManager.default.fileExists(atPath: at.path) + { + return true + } + else + { + return false + } + } +} // end extension AppFileStatusChecking + +protocol AppFileSystemMetaData +{ + func list(directory at: URL) -> [String] + + func attributes(ofFile atFullPath: URL) -> [FileAttributeKey : Any] +} + +extension AppFileSystemMetaData +{ + func list(directory at: URL) -> [String] + { + var arr = [String]() + let listing = try! FileManager.default.contentsOfDirectory(atPath: at.path) + + if listing.count > 0 + { + print("\n----------------------------") + print("LISTING: \(at.path)") + print("") + for file in listing + { + arr.append(file.debugDescription) + print("File: \(file.debugDescription)") + } + print("") + print("----------------------------\n") + } + return arr + } + + func attributes(ofFile atFullPath: URL) -> [FileAttributeKey : Any] + { + return try! FileManager.default.attributesOfItem(atPath: atFullPath.path) + } +} // end extension AppFileSystemMetaData + +protocol AppFileManipulation : AppDirectoryNames +{ + func writeFile(containing: String, to path: AppDirectories, withName name: String) -> Bool + + func readFile(at path: AppDirectories, withName name: String) -> String + + func deleteFile(at path: AppDirectories, withName name: String) -> Bool + + func renameFile(at path: AppDirectories, with oldName: String, to newName: String) -> Bool + + func moveFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -> Bool + + func copyFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -> Bool + + func changeFileExtension(withName name: String, inDirectory: AppDirectories, toNewExtension newExtension: String) -> Bool +} + +extension AppFileManipulation +{ + func writeFile(containing: String, to path: AppDirectories, withName name: String) -> Bool + { + let filePath = getURL(for: path).path + "/" + name + let rawData: Data? = containing.data(using: .utf8) + return FileManager.default.createFile(atPath: filePath, contents: rawData, attributes: nil) + } + + func readFile(at path: AppDirectories, withName name: String) -> String + { + let filePath = getURL(for: path).path + "/" + name + let fileContents = FileManager.default.contents(atPath: filePath) + let fileContentsAsString = String(bytes: fileContents!, encoding: .utf8) + print(fileContentsAsString!) + return fileContentsAsString! + } + + func deleteFile(at path: AppDirectories, withName name: String) -> Bool + { + let filePath = buildFullPath(forFileName: name, inDirectory: path) + try! FileManager.default.removeItem(at: filePath) + return true + } + + func renameFile(at path: AppDirectories, with oldName: String, to newName: String) -> Bool + { + let oldPath = getURL(for: path).appendingPathComponent(oldName) + let newPath = getURL(for: path).appendingPathComponent(newName) + try! FileManager.default.moveItem(at: oldPath, to: newPath) + + // highlights the limitations of using return values + return true + } + + func moveFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -> Bool + { + let originURL = buildFullPath(forFileName: name, inDirectory: inDirectory) + let destinationURL = buildFullPath(forFileName: name, inDirectory: directory) + // warning: constant 'success' inferred to have type '()', which may be unexpected + // let success = + try! FileManager.default.moveItem(at: originURL, to: destinationURL) + return true + } + + func copyFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -> Bool + { + let originURL = buildFullPath(forFileName: name, inDirectory: inDirectory) + let destinationURL = buildFullPath(forFileName: name+"1", inDirectory: directory) + try! FileManager.default.copyItem(at: originURL, to: destinationURL) + return true + } + + func changeFileExtension(withName name: String, inDirectory: AppDirectories, toNewExtension newExtension: String) -> Bool + { + var newFileName = NSString(string:name) + newFileName = newFileName.deletingPathExtension as NSString + newFileName = (newFileName.appendingPathExtension(newExtension) as NSString?)! + let finalFileName:String = String(newFileName) + + let originURL = buildFullPath(forFileName: name, inDirectory: inDirectory) + let destinationURL = buildFullPath(forFileName: finalFileName, inDirectory: inDirectory) + + try! FileManager.default.moveItem(at: originURL, to: destinationURL) + + return true + } +} // end extension AppFileManipulation + +struct AppFile : AppFileManipulation, AppFileStatusChecking, AppFileSystemMetaData +{ + + let fileName: String + + init(fileName: String) + { + self.fileName = fileName + } + + init() + { + fileName = "N/A" + } + + func moveToDocuments() + { + _ = moveFile(withName: fileName, inDirectory: .Inbox, toDirectory: .Documents) + } + + func deleteTempFile() + { + _ = deleteFile(at: .Temp, withName: fileName) + } + + func write() -> Bool + { + _ = writeFile(containing: "This file was written on 5/23/18.\n\nThis file should show up in the Files app.", to: .Documents, withName: "myFileApp.txt") + //writeFile(containing: "We were talking\nAbout the space\nBetween us all", to: .Documents, withName: "karma.txt") + // writeFile(containing: "And the people\nWho hide themselves\nBehind a wall", to: .Documents, withName: "dharma.txt") + return true + } + + func list() -> [String] + { + return list(directory: getURL(for: .Documents)) + } + + func getAttribs() + { + let attribs = attributes(ofFile: buildFullPath(forFileName: "karma.txt", inDirectory: .Documents)) + for (key, value) in attribs + { + print("\(key) value is \(value)") + } + } + + /* + func delete() + { + deleteFile(at: .Documents, withName: "karma.txt") + } + func read() + { + readFile(at: .Documents, withName: "text2.txt") + } + func list() -> Bool + { + return list(directory: getURL(for: .Documents)) + } + func rename() + { + renameFile(at: .Documents, with: "text2.txt", to: "karma.txt") + } + func move() + { + // moveFile(withName: "text2.txt", inDirectory: .Temp, toDirectory: .Documments) WORKS + moveFile(withName: "text2.txt", inDirectory: .Inbox, toDirectory: .Documents) + } + func copy() -> Bool + { + return copyFile(withName: "karma", inDirectory: .Documents, toDirectory: .Documents) + } + func doesExist() -> Bool + { + return exists(file: buildFullPath(forFileName: "karma.txt", inDirectory: .Documents)) + } + func getAttribs() + { + let attribs = attributes(ofFile: buildFullPath(forFileName: "karma.txt", inDirectory: .Documents)) + for (key, value) in attribs + { + print("\(key) value is \(value)") + } + } + func changeExtension() + { + changeFileExtension(withName: "text1.txt", inDirectory: .Documents, toNewExtension: "html") + } + */ +} + + diff --git a/frontend/mobile/CommunityMC3/Utilities/ImagePicker.swift b/frontend/mobile/CommunityMC3/Utilities/ImagePicker.swift new file mode 100644 index 0000000..8427148 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/ImagePicker.swift @@ -0,0 +1,95 @@ +// +// Utilities.swift +// CommunityMC3 +// +// Created by Bernardinus on 21/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit + +public protocol ImagePickerDelegate: class { + func didSelect(image: UIImage?) +} + +open class ImagePicker: NSObject { + + private let pickerController: UIImagePickerController + private weak var presentationController: UIViewController? + private weak var delegate: ImagePickerDelegate? + + public init(presentationController: UIViewController, delegate: ImagePickerDelegate) { + self.pickerController = UIImagePickerController() + + super.init() + + self.presentationController = presentationController + self.delegate = delegate + + self.pickerController.delegate = self + self.pickerController.allowsEditing = true + self.pickerController.mediaTypes = ["public.image"] + } + + private func action(for type: UIImagePickerController.SourceType, title: String) -> UIAlertAction? { + guard UIImagePickerController.isSourceTypeAvailable(type) else { + return nil + } + + return UIAlertAction(title: title, style: .default) { [unowned self] _ in + self.pickerController.sourceType = type + self.presentationController?.present(self.pickerController, animated: true) + } + } + + public func present(from sourceView: UIView) { + + let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + + if let action = self.action(for: .camera, title: NSLocalizedString("Take photo".uppercased(), comment: "")) { + alertController.addAction(action) + } + if let action = self.action(for: .savedPhotosAlbum, title: NSLocalizedString("Camera roll".uppercased(), comment: "")) { + alertController.addAction(action) + } + if let action = self.action(for: .photoLibrary, title: NSLocalizedString("Photo library".uppercased(), comment: "")) { + alertController.addAction(action) + } + + alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)) + + if UIDevice.current.userInterfaceIdiom == .pad { + alertController.popoverPresentationController?.sourceView = sourceView + alertController.popoverPresentationController?.sourceRect = sourceView.bounds + alertController.popoverPresentationController?.permittedArrowDirections = [.down, .up] + } + + self.presentationController?.present(alertController, animated: true) + } + + private func pickerController(_ controller: UIImagePickerController, didSelect image: UIImage?) { + controller.dismiss(animated: true, completion: nil) + + self.delegate?.didSelect(image: image) + } +} + +extension ImagePicker: UIImagePickerControllerDelegate { + + public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + self.pickerController(picker, didSelect: nil) + } + + public func imagePickerController(_ picker: UIImagePickerController, + didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { + guard let image = info[.editedImage] as? UIImage else { + return self.pickerController(picker, didSelect: nil) + } + self.pickerController(picker, didSelect: image) + } +} + +extension ImagePicker: UINavigationControllerDelegate { + +} diff --git a/frontend/mobile/CommunityMC3/Utilities/StringExtension.swift b/frontend/mobile/CommunityMC3/Utilities/StringExtension.swift new file mode 100644 index 0000000..d8a58a3 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/StringExtension.swift @@ -0,0 +1,18 @@ +// +// StringExtension.swift +// Allegro +// +// Created by Bernardinus on 07/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation + +extension String +{ + func containsInsesitive(string:String) -> Bool + { + if let _ = self.range(of: string, options: .caseInsensitive){return true} + return false + } +} diff --git a/frontend/mobile/CommunityMC3/Utilities/UIImageExtension.swift b/frontend/mobile/CommunityMC3/Utilities/UIImageExtension.swift new file mode 100644 index 0000000..ab16ff1 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/UIImageExtension.swift @@ -0,0 +1,25 @@ +// +// UIImage+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 27/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit + + +extension UIImage { + public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) { + let rect = CGRect(origin: .zero, size: size) + UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) + color.setFill() + UIRectFill(rect) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + guard let cgImage = image?.cgImage else { return nil } + self.init(cgImage: cgImage) + } +} diff --git a/frontend/mobile/CommunityMC3/Utilities/UIViewControllerExtension.swift b/frontend/mobile/CommunityMC3/Utilities/UIViewControllerExtension.swift new file mode 100644 index 0000000..f63d466 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/UIViewControllerExtension.swift @@ -0,0 +1,32 @@ +// +// UIViewController+Extension.swift +// CommunityMC3 +// +// Created by Bernardinus on 22/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import CoreData +import UIKit + +extension UIViewController { + + func getViewContext() -> NSManagedObjectContext { + let appDelegate = UIApplication.shared.delegate as! AppDelegate + let context = appDelegate.persistentContainer.viewContext + return context + } + + func dismissKeyboard() { + let tap: UITapGestureRecognizer = UITapGestureRecognizer( target: self, action: #selector(UIViewController.dismissKeyboardFunc)) + tap.cancelsTouchesInView = false; view.addGestureRecognizer(tap) + + } + + @objc func dismissKeyboardFunc(){ + print("dismissKeyboard") + view.endEditing(true) + } + +} diff --git a/frontend/mobile/CommunityMC3/Utilities/UIViewExtension.swift b/frontend/mobile/CommunityMC3/Utilities/UIViewExtension.swift new file mode 100644 index 0000000..8c5df26 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/UIViewExtension.swift @@ -0,0 +1,41 @@ +// +// UIView+Extension.swift +// Allegro +// +// Created by Bernardinus on 07/08/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit + +extension UIView { + func slideLeft(duration: TimeInterval = 1.0, completionDelegate: AnyObject? = nil) { + let slideFromRightToLeft = CATransition() + + if let delegate: AnyObject = completionDelegate { + slideFromRightToLeft.delegate = (delegate as! CAAnimationDelegate) + } + slideFromRightToLeft.type = CATransitionType.push + slideFromRightToLeft.subtype = CATransitionSubtype.fromRight + slideFromRightToLeft.duration = duration + slideFromRightToLeft.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) + slideFromRightToLeft.fillMode = CAMediaTimingFillMode.removed + + self.layer.add(slideFromRightToLeft, forKey: "slideFromRightToLeft") + } + // func slideRight(duration: TimeInterval = 1.0, completionDelegate: AnyObject? = nil){ + // let slideFromLeftToRight = CATransition() + // + // if let delegate: AnyObject = completionDelegate { + // slideFromLeftToRight.delegate = (delegate as! CAAnimationDelegate) + // } + // slideFromLeftToRight.type = CATransitionType.push + // slideFromLeftToRight.subtype = CATransitionSubtype.fromLeft + // slideFromLeftToRight.duration = duration + // slideFromLeftToRight.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) + // slideFromLeftToRight.fillMode = CAMediaTimingFillMode.removed + // + // self.layer.add(slideFromLeftToRight, forKey: "slideFromLeftToRight") + // } +} diff --git a/frontend/mobile/CommunityMC3/Utilities/Utilities.swift b/frontend/mobile/CommunityMC3/Utilities/Utilities.swift new file mode 100644 index 0000000..8f42759 --- /dev/null +++ b/frontend/mobile/CommunityMC3/Utilities/Utilities.swift @@ -0,0 +1,118 @@ +// +// Utilities.swift +// CommunityMC3 +// +// Created by Bernardinus on 30/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import Foundation +import UIKit +import AVFoundation +import AVKit + +func openInstagram(username:String) +{ + let instagramURL = URL(string:"instagram://user?username=\(username)") + if UIApplication.shared.canOpenURL(instagramURL!) + { + UIApplication.shared.open(instagramURL!, options: [:], completionHandler: { (success) in + print("open url \(instagramURL!) status \(success)") + }) + } + else + { + print("can't open url \(instagramURL!)") + } +} + +func sendMessageInWhatsApp(message:String) +{ + let whatsappURL = URL(string:"whatsapp://send?text=\(message)") + if UIApplication.shared.canOpenURL(whatsappURL!) + { + UIApplication.shared.open(whatsappURL!, options: [:], completionHandler: { (success) in + print("open url \(whatsappURL!) status \(success)") + }) + } + else + { + print("can't open url \(whatsappURL!)") + } +} + +func callPhoneNumber(phoneNumber:String) +{ + let phoneNumberURL = URL(string:"tel://\(phoneNumber)") + if UIApplication.shared.canOpenURL(phoneNumberURL!) + { + UIApplication.shared.open(phoneNumberURL!, options: [:], completionHandler: { (success) in + print("open url \(phoneNumberURL!) status \(success)") + }) + } + else + { + print("can't open url \(phoneNumberURL!)") + } +} + + +func setupUIViewForGenre(view:UIView, genre:String) +{ + view.layer.borderWidth = 1.5 + view.layer.cornerRadius = 12 + view.layer.borderColor = genreBorderColor[genre] +} + +/* +func genreBorderColor(genre:String) -> CGColor +{ + var color:CGColor? = nil + + switch genre + { + case "RnB": + color = #colorLiteral(red: 0, green: 0.768627451, blue: 0.5490196078, alpha: 1) + case "Jazz": + color = #colorLiteral(red: 0.4117647059, green: 0.4745098039, blue: 0.9725490196, alpha: 1) + case "Pop": + color = #colorLiteral(red: 0.7019607843, green: 0, blue: 0.09411764706, alpha: 1) + case "Rock": + color = #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1) + case "Acoustic": + color = #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1) + case "Blues": + color = #colorLiteral(red: 0.07843137255, green: 0.2745098039, blue: 0.737254902, alpha: 1) + default: + color = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1) + } + + return color! +} + */ + +let genreBorderColor:[String:CGColor] = [ + "RnB": #colorLiteral(red: 0, green: 0.768627451, blue: 0.5490196078, alpha: 1), + "Jazz": #colorLiteral(red: 0.4117647059, green: 0.4745098039, blue: 0.9725490196, alpha: 1), + "Pop": #colorLiteral(red: 0.7019607843, green: 0, blue: 0.09411764706, alpha: 1), + "Rock": #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1), + "Acoustic": #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1), + "Blues": #colorLiteral(red: 0.07843137255, green: 0.2745098039, blue: 0.737254902, alpha: 1), +] + +// to generate video thumbnail +func generateThumbnail(path: URL) -> UIImage? { + do { + let asset = AVURLAsset(url: path, options: nil) + let imgGenerator = AVAssetImageGenerator(asset: asset) + imgGenerator.appliesPreferredTrackTransform = true + let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 5, timescale: 1), actualTime: nil) + let thumbNail = UIImage(cgImage: cgImage) + return thumbNail + } catch let error { + print("*** Error generating thumbnail: \(error.localizedDescription)") + return nil + } +} + + diff --git a/frontend/mobile/CommunityMC3/VideoPlayer View/VideoPlayer.storyboard b/frontend/mobile/CommunityMC3/VideoPlayer View/VideoPlayer.storyboard new file mode 100644 index 0000000..f973643 --- /dev/null +++ b/frontend/mobile/CommunityMC3/VideoPlayer View/VideoPlayer.storyboard @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/VideoPlayer View/VideoPlayerViewController.swift b/frontend/mobile/CommunityMC3/VideoPlayer View/VideoPlayerViewController.swift new file mode 100644 index 0000000..da3bf8b --- /dev/null +++ b/frontend/mobile/CommunityMC3/VideoPlayer View/VideoPlayerViewController.swift @@ -0,0 +1,92 @@ +// +// VideoPlayerViewController.swift +// CommunityMC3 +// +// Created by Rommy Julius Dwidharma on 20/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import UIKit +import AVKit +import CloudKit + +class VideoPlayerViewController: UIViewController { + + @IBOutlet weak var videoThumbnailImageView: UIImageView! + + static let shared = VideoPlayerViewController() + + var video: VideosDataStruct! + + override func viewWillAppear(_ animated: Bool) { + navigationController?.setNavigationBarHidden(false, animated: false) + super.viewWillAppear(animated) + } + + override func viewDidLoad() { + super.viewDidLoad() + + video.fileData = CKAsset(fileURL:retrieveVideo(video: video)!) + loadThumbnail() + } + + func retrieveVideo(video: VideosDataStruct?) -> URL? { + if video != nil { + let videoURL = video!.fileData?.fileURL! + let videoData = NSData(contentsOf: videoURL! as URL) + + let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + let destinationPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent(video!.name + ".mov", isDirectory: false) //This is where I messed up. + + FileManager.default.createFile(atPath: (destinationPath?.path)!, contents:videoData as Data?, attributes:nil) + + return destinationPath! + } + return video?.fileData?.fileURL + } + + func loadThumbnail() { + + let urls: URL? + + if video != nil { + urls = video.fileData?.fileURL + }else { + let videoUrl = Bundle.main.path(forResource: " ", ofType: "mp4") + urls = URL(fileURLWithPath: videoUrl!) + } + + //insert generateThumbnail function to imageView + self.videoThumbnailImageView.image = generateThumbnail(path: urls!) + + } + + + + + + @IBAction func playVideoButtonAction(_ sender: UIButton) { + let video:AVPlayer? + + if self.video != nil { + let urls = self.video.fileData?.fileURL + video = AVPlayer(url: urls!) + }else { + if let urlString = Bundle.main.path(forResource: " ", ofType: "mp4"){ + video = AVPlayer(url: URL(fileURLWithPath: urlString)) + }else{ + video = nil + } + } + if video != nil { + let videoPlayer = AVPlayerViewController() + videoPlayer.player = video! + + //enter video player mode + self.present(videoPlayer, animated: true, completion: { + video!.play() + }) + } + } + +} diff --git a/frontend/mobile/CommunityMC3/en.lproj/Localizable.strings b/frontend/mobile/CommunityMC3/en.lproj/Localizable.strings new file mode 100644 index 0000000..1cd0130 --- /dev/null +++ b/frontend/mobile/CommunityMC3/en.lproj/Localizable.strings @@ -0,0 +1,142 @@ +/* + Localizable.strings + CommunityMC3 + + Created by Bryanza on 16/07/20. + Copyright © 2020 Apple Developer Academy. All rights reserved. +*/ + +// Tab Bar +"TAB_Explore" = "Explore"; +"TAB_Search" = "Search"; +"TAB_Favourites" = "Favourites"; + +// Explore View +"Explore" = "Explore"; +"Trending Now" = "Trending Now"; +"See more >" = "See more >"; +"Discover New" = "Discover New"; +"Latest Upload" = "Latest Upload"; +"Featured Artist" = "Featured Artist"; +"More artist >" = "More Artist >"; +"Featured Upload" = "Featured Upload"; +"More videos >" = "More videos >"; + + +"Highlights" = "Highlights"; +"Show all" = "Show all"; +"New Comer" = "New Comer"; +"Search" = "Search"; +"Activity" = "Activity"; +"Profile" = "Profile"; + +"new notifications" = "new notifications"; +"followed you" = "followed you"; +"posted" = "posted"; +"new audio" = "new audio"; +"new video" = "new video"; + +"Guitarist" = "Guitarist"; +"Vocalist" = "Vocalist"; +"Violin" = "Violin"; + +"Random Spotlight" = "Random Spotlight"; +"Pianist" = "Pianist"; +"View" = "View"; +"Randomize" = "Randomize"; + +"Artist" = "Artist"; +"Playlist" = "Playlist"; +"Drummer" = "Drummer"; +"followers" = "followers"; +"following" = "following"; +"Band" = "Band"; + +"Sign In" = "Sign In"; +"Signing up to see our top picks for you" = "Signing up to see our top picks for you"; +"Email Address" = "Email Address"; +"Password" = "Password"; +"Let's" = "Let's"; +"Full Name" = "Full Name"; +"Get Started" = "Get Started"; + +"About" = "About"; +"Audio" = "Audio"; +"Gallery" = "Gallery"; +"History" = "History"; +"Settings" = "Settings"; +"Genre" = "Genre"; +"Classic" = "Classic"; +"Photo" = "Photo"; + +"Sign Out" = "Sign Out"; +"Are you sure want to sign out?" = "Are you sure want to sign out?"; +"Cancel" = "Cancel"; +"Save" = "Save"; + +// Select File View +"Select File" = "Select File"; + +// Profile View +"GENRE PREFERENCES" = "Genre Preferences"; +"CONTACT INFO" = "Contact Info"; +"SOCIAL MEDIA" = "Social Media"; +"MUSIC" = "Music"; +"PHOTOS" = "Photos"; +"VIDEOS" = "Videos"; +"EDIT" = "Edit"; +"SHARE" = "Share"; +"UPLOAD MUSIC" = "Upload Music"; +"UPLOAD VIDEO" = "Upload Video"; +"UPLOAD PHOTOS" = "Upload Photos"; + +"FOLLOW" = "Follow"; +"CONTACT" = "Contact"; +"SHOWCASE" = "Showcase"; +"VIDEO" = "Video"; +"NEXT" = "Next"; +"VIEW PROFILE" = "View Profile"; + +"EDIT RANDOMIZER" = "Edit randomizer"; +"SORT BY" = "Sort by"; +"CLEAR ALL" = "Clear All"; +"APPLY" = "Apply"; + +"WRITE THE TITLE" = "Write the title"; +"ALBUM" = "Album"; +"DESCRIPTION" = "Description"; +"POST" = "Post"; +"UPLOAD" = "Upload"; +"DONE" = "Done"; +"COVER SONG" = "Cover Song"; + +"TAKE PHOTO" = "Take photo"; +"CAMERA ROLL" = "Camera roll"; +"PHOTO LIBRARY" = "Photo library"; +"CAMERA" = "Camera"; +"BROWSE ATTACHMENT" = "Browse attachment"; + +"NAME" = "Name"; +"EMAIL" = "Email"; +"SIGN IN DESCRIPTION" = "Sign in or login to see the latest highlights"; +"FORGOT PASSWORD" = "Forgot password?"; +"CREATE ACCOUNT" = "Create new account!"; +"SIGN UP DESCRIPTION" = "Sign up or register to see the latest highlights"; +"REGISTER NOW" = "Register Now"; +"HAVE ACCOUNT" = "Already have account?"; + +"SUPRISE" = "Tap to surprise!"; +"EDIT GENRE" = "Edit genre"; +"SWITCH ACCOUNT" = "Switch Account"; +"ADD ACCOUNT" = "Add Account"; + + + + + + + + + + + diff --git a/frontend/mobile/CommunityMC3/id.lproj/LaunchScreen.strings b/frontend/mobile/CommunityMC3/id.lproj/LaunchScreen.strings new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/frontend/mobile/CommunityMC3/id.lproj/LaunchScreen.strings @@ -0,0 +1 @@ + diff --git a/frontend/mobile/CommunityMC3/id.lproj/Localizable.strings b/frontend/mobile/CommunityMC3/id.lproj/Localizable.strings new file mode 100644 index 0000000..8bd0424 --- /dev/null +++ b/frontend/mobile/CommunityMC3/id.lproj/Localizable.strings @@ -0,0 +1,134 @@ +/* + Localizable.strings + CommunityMC3 + + Created by Bryanza on 16/07/20. + Copyright © 2020 Apple Developer Academy. All rights reserved. +*/ + + + +// Common + +// Tab Bar +"TAB_Explore" = "Jelajahi"; +"TAB_Search" = "Pencarian"; +"TAB_Favourites" = "Favorit"; + +// Explore View +"Explore" = "Jelajahi"; +"Trending Now" = "Tren Saat Ini"; +"See more >" = "Lihat lainnya >"; +"Discover New" = "Temukan Yang Baru"; +"Latest Upload" = "Unggahan Terbaru"; +"Featured Artist" = "Artis Unggulan"; +"More artist >" = "Artis lainnya >"; +"Featured Upload" = "Unggahan Unggul"; +"More videos >" = "Video lainnya >"; + +"Highlights" = "Terkini"; +"Show all" = "Lihat Semua"; +"New Comer" = "Terbaru"; +"Latest Video" = "Video Terbaru"; +"Activity" = "Aktivitas"; +"Profile" = "Profil"; + +"new notifications" = "notifikasi baru"; +"followed you" = "mengikuti kamu"; +"posted" = "merilis"; +"new audio" = "musik baru"; +"new video" = "video baru"; + +"Guitarist" = "Gitaris"; +"Vocalist" = "Vokalis"; +"Violin" = "Pemain Biola"; + +"Random Spotlight" = "Sorotan Acak"; +"Pianist" = "Pemain Piano"; +"View" = "Lihat"; +"Randomize" = "Acak"; + +"Artist" = "Musisi"; +"Playlist" = "Kumpulan Musik"; +"Drummer" = "Pemain Drum"; +"followers" = "pengikut"; +"following" = "mengikuti"; +"Band" = "Group"; + +"Sign In" = "Masuk"; +"Signing up to see our top picks for you" = "Daftar untuk melihat koleksi unggulan kami"; +"Email Address" = "Alamat E-mail"; +"Password" = "Kata Sandi"; +"Let's" = "Ayo"; +"Full Name" = "Nama Lengkap"; +"Get Started" = "Mulai"; + +"About" = "Tentang"; +"Audio" = "Musik"; +"Gallery" = "Galeri"; +"History" = "Riwayat"; +"Settings" = "Setelan"; +"Genre" = "Genre"; +"Classic" = "Klasik"; +"Photo" = "Foto"; + +"Sign Out" = "Keluar"; +"Are you sure want to sign out?" = "Apakah anda yakin ingin keluar?"; +"Cancel" = "Batalkan"; +"Save" = "Simpan"; + +// Select File View +"Select File" = "Pilih File"; + +// Profile View +"GENRE PREFERENCES" = "Preferensi Genre"; +"CONTACT INFO" = "Info Kontak"; +"SOCIAL MEDIA" = "Media Sosial"; +"MUSIC" = "Musik"; +"PHOTOS" = "Foto"; +"VIDEOS" = "Video"; +"EDIT" = "Ubah"; +"SHARE" = "Bagikan"; +"UPLOAD MUSIC" = "Unggah Musik"; +"UPLOAD VIDEO" = "Unggah Video"; +"UPLOAD PHOTOS" = "Unggah Foto"; + +"FOLLOW" = "Ikuti"; +"CONTACT" = "Kontak"; +"SHOWCASE" = "Etalase"; +"VIDEO" = "Video"; +"NEXT" = "Selanjutnya"; +"VIEW PROFILE" = "Lihat Profil"; + +"EDIT RANDOMIZER" = "Ubah acakan"; +"SORT BY" = "Urut berdasarkan"; +"CLEAR ALL" = "Hapus Semua"; +"APPLY" = "Simpan"; + +"WRITE THE TITLE" = "Tulis judul disini"; +"ALBUM" = "Album"; +"DESCRIPTION" = "Deskripsi"; +"POST" = "Tempel"; +"UPLOAD" = "Unggah"; +"DONE" = "Selesai"; +"COVER SONG" = "Lagu Cover"; + +"TAKE PHOTO" = "Ambil foto"; +"CAMERA ROLL" = "Galeri kamera"; +"PHOTO LIBRARY" = "Perpustakaan foto"; +"CAMERA" = "Kamera"; +"BROWSE ATTACHMENT" = "Pilih unggahan"; + +"NAME" = "Nama"; +"EMAIL" = "Email"; +"SIGN IN DESCRIPTION" = "Daftar atau masuk untuk melihat musik terkini"; +"FORGOT PASSWORD" = "Lupa kata sandi?"; +"CREATE ACCOUNT" = "Buat akun baru!"; +"SIGN UP DESCRIPTION" = "Masuk atau daftar untuk melihat musik terkini"; +"REGISTER NOW" = "Daftar Sekarang"; +"HAVE ACCOUNT" = "Sudah punya akun?"; + +"SUPRISE" = "Tekan untuk kejutan!"; +"EDIT GENRE" = "Ubah genre"; +"SWITCH ACCOUNT" = "Ganti Akun"; +"ADD ACCOUNT" = "Tambah Akun"; diff --git a/frontend/mobile/CommunityMC3Tests/CommunityMC3Tests.swift b/frontend/mobile/CommunityMC3Tests/CommunityMC3Tests.swift new file mode 100644 index 0000000..099a66c --- /dev/null +++ b/frontend/mobile/CommunityMC3Tests/CommunityMC3Tests.swift @@ -0,0 +1,34 @@ +// +// CommunityMC3Tests.swift +// CommunityMC3Tests +// +// Created by Bryanza on 06/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import XCTest +@testable import CommunityMC3 + +class CommunityMC3Tests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/frontend/mobile/CommunityMC3Tests/Info.plist b/frontend/mobile/CommunityMC3Tests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/frontend/mobile/CommunityMC3Tests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/frontend/mobile/CommunityMC3UITests/CommunityMC3UITests.swift b/frontend/mobile/CommunityMC3UITests/CommunityMC3UITests.swift new file mode 100644 index 0000000..4a9e89f --- /dev/null +++ b/frontend/mobile/CommunityMC3UITests/CommunityMC3UITests.swift @@ -0,0 +1,43 @@ +// +// CommunityMC3UITests.swift +// CommunityMC3UITests +// +// Created by Bryanza on 06/07/20. +// Copyright © 2020 Apple Developer Academy. All rights reserved. +// + +import XCTest + +class CommunityMC3UITests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) { + XCUIApplication().launch() + } + } + } +} diff --git a/frontend/mobile/CommunityMC3UITests/Info.plist b/frontend/mobile/CommunityMC3UITests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/frontend/mobile/CommunityMC3UITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/frontend/mobile/Podfile b/frontend/mobile/Podfile new file mode 100644 index 0000000..5203c37 --- /dev/null +++ b/frontend/mobile/Podfile @@ -0,0 +1,21 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'CommunityMC3' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for CommunityMC3 + pod 'BonsaiController' + pod 'SwipeMenuViewController' + + target 'CommunityMC3Tests' do + inherit! :search_paths + # Pods for testing + end + + target 'CommunityMC3UITests' do + # Pods for testing + end + +end \ No newline at end of file diff --git a/frontend/mobile/Podfile.lock b/frontend/mobile/Podfile.lock new file mode 100644 index 0000000..0ecd01f --- /dev/null +++ b/frontend/mobile/Podfile.lock @@ -0,0 +1,20 @@ +PODS: + - BonsaiController (6.0.0) + - SwipeMenuViewController (4.1.0) + +DEPENDENCIES: + - BonsaiController + - SwipeMenuViewController + +SPEC REPOS: + trunk: + - BonsaiController + - SwipeMenuViewController + +SPEC CHECKSUMS: + BonsaiController: 63410fc39bc5b3a9df5b329dbc848b6b27edf663 + SwipeMenuViewController: 94fac81cc192d9f08f218fe4c0c853569b735e1f + +PODFILE CHECKSUM: 0ddfb5a4645e59b6a195a117a9d88dd7419fe64c + +COCOAPODS: 1.9.1 diff --git a/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/BonsaiController.swift b/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/BonsaiController.swift new file mode 100644 index 0000000..4d4f88d --- /dev/null +++ b/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/BonsaiController.swift @@ -0,0 +1,223 @@ +// +// BonsaiController.swift +// BonsaiController +// +// Created by Warif Akhand Rishi on 22/5/18. +// Copyright © 2018 Warif Akhand Rishi. All rights reserved. +// + +import UIKit + +@objc +public protocol BonsaiControllerDelegate: UIViewControllerTransitioningDelegate { + + /// Returns a frame for presented viewController on containerView + /// + /// - Parameter: containerViewFrame + + func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect + + //@objc(presentationControllerForPresentedViewController:presentingViewController:sourceViewController:) + //func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? + @objc optional func didDismiss() +} + +@objc +public protocol BonsaiTransitionProperties { + var duration: TimeInterval {get set} + var springWithDamping: CGFloat {get set} + var isDisabledDismissAnimation: Bool {get set} +} + +@objc +public class BonsaiController: UIPresentationController, BonsaiTransitionProperties { + + public var duration: TimeInterval = 0.4 + public var springWithDamping: CGFloat = 0.8 + public var isDisabledDismissAnimation: Bool = false + @objc public var isDisabledTapOutside: Bool = false + + /// Availabel only for slide in transition in swift + @nonobjc public var dismissDirection: Direction? = nil + + weak public var sizeDelegate: BonsaiControllerDelegate? + + private var originView: UIView? // For Bubble transition + private var fromDirection: Direction! // For slide Transition + private var blurEffectView: UIVisualEffectView! + private var blurEffectStyle: UIBlurEffect.Style? + private var backgroundColor: UIColor? + + @objc + convenience public init(fromDirection: Direction, blurEffectStyle: UIBlurEffect.Style, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { + self.init(presentedViewController: presentedViewController, presenting: nil) + + self.fromDirection = fromDirection + self.sizeDelegate = delegate + self.blurEffectStyle = blurEffectStyle + setup(presentedViewController: presentedViewController) + } + + + @objc + convenience public init(fromDirection: Direction, backgroundColor: UIColor, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { + self.init(presentedViewController: presentedViewController, presenting: nil) + + self.fromDirection = fromDirection + self.sizeDelegate = delegate + self.backgroundColor = backgroundColor + setup(presentedViewController: presentedViewController) + } + + @objc + convenience public init(fromView: UIView, blurEffectStyle: UIBlurEffect.Style, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { + self.init(presentedViewController: presentedViewController, presenting: nil) + + self.originView = fromView + self.sizeDelegate = delegate + self.blurEffectStyle = blurEffectStyle + setup(presentedViewController: presentedViewController) + } + + @objc + convenience public init(fromView: UIView, backgroundColor: UIColor, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { + self.init(presentedViewController: presentedViewController, presenting: nil) + + self.originView = fromView + self.sizeDelegate = delegate + self.backgroundColor = backgroundColor + setup(presentedViewController: presentedViewController) + } + + override private init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) { + super.init(presentedViewController: presentedViewController, presenting: presentingViewController) + } + + @objc public func dismiss() { + presentedViewController.dismiss(animated: true, completion: nil) + } + + private func setup(presentedViewController: UIViewController) { + + var blurEffect: UIBlurEffect? + if let blurEffectStyle = blurEffectStyle { + blurEffect = UIBlurEffect(style: blurEffectStyle) + blurEffectView = UIVisualEffectView(effect: blurEffect) + } else { + blurEffectView = UIVisualEffectView(effect: nil) + blurEffectView.backgroundColor = self.backgroundColor + } + + blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + blurEffectView.isUserInteractionEnabled = true + + let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap)) + blurEffectView.addGestureRecognizer(tapGestureRecognizer) + + presentedView?.layer.masksToBounds = true + presentedView?.layer.cornerRadius = 10 + + presentedViewController.modalPresentationStyle = .custom + presentedViewController.transitioningDelegate = self + } + + @objc private func handleTap() { + + if !isDisabledTapOutside { + dismiss() + } + } + + override public var frameOfPresentedViewInContainerView: CGRect { + return (sizeDelegate ?? self).frameOfPresentedView(in: containerView!.frame) + } + + override public func dismissalTransitionWillBegin() { + presentedViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] (UIViewControllerTransitionCoordinatorContext) in + self?.blurEffectView.alpha = 0 + }, completion: { [weak self] (UIViewControllerTransitionCoordinatorContext) in + self?.blurEffectView.removeFromSuperview() + self?.sizeDelegate?.didDismiss?() + }) + } + + override public func presentationTransitionWillBegin() { + + blurEffectView.alpha = 0 + blurEffectView.frame = containerView!.bounds + containerView?.addSubview(blurEffectView) + + presentedView?.frame = frameOfPresentedViewInContainerView + + presentedViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] (UIViewControllerTransitionCoordinatorContext) in + self?.blurEffectView.alpha = 1 + }, completion: { (UIViewControllerTransitionCoordinatorContext) in + + }) + } + + public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + + coordinator.animate(alongsideTransition: { [weak self] (contx) in + guard let self = self else { return } + self.presentedView?.frame = self.frameOfPresentedViewInContainerView + self.presentedView?.layoutIfNeeded() + }) + } +} + +extension BonsaiController: BonsaiControllerDelegate { + + public func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { + return CGRect(origin: CGPoint(x: 0, y: containerViewFrame.height/2), size: CGSize(width: containerViewFrame.width, height: containerViewFrame.height/2)) + } + + @objc(presentationControllerForPresentedViewController:presentingViewController:sourceViewController:) public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + return self + } +} + +extension BonsaiController: UIViewControllerTransitioningDelegate { + + private func setupTransitioningProperties(transitioning: BonsaiTransitionProperties?) -> UIViewControllerAnimatedTransitioning? { + transitioning?.duration = duration + transitioning?.springWithDamping = springWithDamping + transitioning?.isDisabledDismissAnimation = isDisabledDismissAnimation + return transitioning as? UIViewControllerAnimatedTransitioning + } + + public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + + if let sizeDelegate = sizeDelegate, sizeDelegate.responds(to:#selector(animationController(forPresented:presenting:source:))) { + return sizeDelegate.animationController?(forPresented: presented, presenting: presenting, source: source) + } + + var transitioning: BonsaiTransitionProperties? + + if let originView = originView { + transitioning = BubbleTransition(originView: originView) + } else { + transitioning = SlideInTransition(fromDirection: fromDirection) + } + + return setupTransitioningProperties(transitioning: transitioning) + } + + public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + + if let sizeDelegate = sizeDelegate, sizeDelegate.responds(to:#selector(animationController(forDismissed:))) { + return sizeDelegate.animationController?(forDismissed:dismissed) + } + + var transitioning: BonsaiTransitionProperties? + + if let originView = originView { + transitioning = BubbleTransition(originView: originView, reverse: true) + } else { + transitioning = SlideInTransition(fromDirection: dismissDirection ?? fromDirection, reverse: true) + } + + return setupTransitioningProperties(transitioning: transitioning) + } +} diff --git a/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/BubbleTransition.swift b/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/BubbleTransition.swift new file mode 100755 index 0000000..1e4de88 --- /dev/null +++ b/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/BubbleTransition.swift @@ -0,0 +1,91 @@ +// +// BubbleTransition.swift +// BonsaiController +// +// Created by Warif Akhand Rishi on 14/6/18. +// Copyright © 2018 Warif Akhand Rishi. All rights reserved. +// + +import Foundation +import UIKit +import AVFoundation + +class BubbleTransition: NSObject, BonsaiTransitionProperties { + + var duration: TimeInterval = 0.3 + var springWithDamping: CGFloat = 0.8 + var isDisabledDismissAnimation: Bool = false + + private let reverse: Bool + private var originView: UIView! + + var dismissCompletion: (()->Void)? + + init(originView: UIView, reverse: Bool = false) { + self.reverse = reverse + self.originView = originView + } +} + +extension BubbleTransition: UIViewControllerAnimatedTransitioning { + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return duration + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + + let viewControllerKey: UITransitionContextViewControllerKey = reverse ? .from : .to + let viewControllerToAnimate = transitionContext.viewController(forKey: viewControllerKey)! + + let viewToAnimate = viewControllerToAnimate.view! + viewToAnimate.frame = transitionContext.finalFrame(for: viewControllerToAnimate) + + var initialFrame = CGRect.zero + + if let originImageView = originView as? UIImageView, originImageView.contentMode == .scaleAspectFit { + let imageSize = originImageView.image!.size + let imageViewRect = originImageView.frame + let frame = AVMakeRect(aspectRatio:imageSize , insideRect: imageViewRect) + initialFrame = ((originView.superview) ?? originView).convert(frame, to: nil) + } else { + initialFrame = ((originView.superview) ?? originView).convert(originView.frame, to: nil) + } + + let finalFrame = viewToAnimate.frame + + let xScaleFactor = initialFrame.width / finalFrame.width + let yScaleFactor = initialFrame.height / finalFrame.height + + let scaleTransform = CGAffineTransform(scaleX: xScaleFactor, y: yScaleFactor) + + if !reverse { + viewToAnimate.transform = scaleTransform + viewToAnimate.center = CGPoint(x: initialFrame.midX, y: initialFrame.midY) + viewToAnimate.clipsToBounds = true + transitionContext.containerView.addSubview(viewToAnimate) + } + + UIView.animate(withDuration: duration, delay:0.0, usingSpringWithDamping: reverse ? 1 : springWithDamping, initialSpringVelocity: 0.0, animations: { [weak self] in + + guard let self = self else { return } + + if self.reverse && self.isDisabledDismissAnimation { + viewToAnimate.alpha = 0 + return + } + + viewToAnimate.transform = self.reverse ? scaleTransform : .identity + + let frame = self.reverse ? initialFrame : finalFrame + viewToAnimate.center = CGPoint(x: frame.midX, y: frame.midY) + + }, completion: { _ in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + + UIView.animate(withDuration: duration/2, delay: duration/2, options: .curveEaseOut, animations: { + viewToAnimate.alpha = self.reverse ? 0.0 : 1 + }) + } +} diff --git a/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/SlideInTransition.swift b/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/SlideInTransition.swift new file mode 100644 index 0000000..092b76a --- /dev/null +++ b/frontend/mobile/Pods/BonsaiController/BonsaiController/Classes/SlideInTransition.swift @@ -0,0 +1,98 @@ +// +// SlideInTransition.swift +// BonsaiController +// +// Created by Warif Akhand Rishi on 9/6/18. +// Copyright © 2018 Warif Akhand Rishi. All rights reserved. +// + +import UIKit + +@objc +public enum Direction: UInt32 { + + case left, right, top, bottom + + public static func randomDirection() -> Direction { + return Direction(rawValue: arc4random_uniform(4))! + } +} + +class SlideInTransition: NSObject, BonsaiTransitionProperties { + + var duration: TimeInterval = 0.3 + var springWithDamping: CGFloat = 0.8 + var isDisabledDismissAnimation: Bool = false + + private let reverse: Bool + private let fromDirection: Direction + + init(fromDirection: Direction, reverse: Bool = false) { + self.reverse = reverse + self.fromDirection = fromDirection + } +} + +extension SlideInTransition: UIViewControllerAnimatedTransitioning { + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + + let viewControllerKey: UITransitionContextViewControllerKey = reverse ? .from : .to + let viewControllerToAnimate = transitionContext.viewController(forKey: viewControllerKey)! + + let viewToAnimate = viewControllerToAnimate.view! + viewToAnimate.frame = transitionContext.finalFrame(for: viewControllerToAnimate) + + let offsetFrame = fromDirection.offsetFrameForView(view: viewToAnimate, containerView: transitionContext.containerView) + + if !reverse { + transitionContext.containerView.addSubview(viewToAnimate) + viewToAnimate.frame = offsetFrame + } + + let options: UIView.AnimationOptions = [.curveEaseOut] + + UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: springWithDamping, initialSpringVelocity: 0.0, options: options, animations: { [weak self] in + + guard let self = self else { return } + + if self.reverse && self.isDisabledDismissAnimation { + viewToAnimate.alpha = 0 + return + } + + if self.reverse == true { + viewToAnimate.frame = offsetFrame + } else { + viewToAnimate.frame = transitionContext.finalFrame(for: viewControllerToAnimate) + } + }, completion: { _ in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + } + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return duration + } +} + +private extension Direction { + + func offsetFrameForView(view: UIView, containerView: UIView) -> CGRect { + + var frame = view.frame + + switch self { + case .left: + frame.origin.x = -frame.width + case .right: + frame.origin.x = containerView.bounds.width + case .top: + frame.origin.y = -frame.height + case .bottom: + frame.origin.y = containerView.bounds.height + } + + return frame + } +} diff --git a/frontend/mobile/Pods/BonsaiController/LICENSE b/frontend/mobile/Pods/BonsaiController/LICENSE new file mode 100644 index 0000000..099ed0a --- /dev/null +++ b/frontend/mobile/Pods/BonsaiController/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 rishi420 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/frontend/mobile/Pods/BonsaiController/README.md b/frontend/mobile/Pods/BonsaiController/README.md new file mode 100644 index 0000000..959f4e5 --- /dev/null +++ b/frontend/mobile/Pods/BonsaiController/README.md @@ -0,0 +1,256 @@ +# Bonsai + +[![Version](https://img.shields.io/cocoapods/v/BonsaiController.svg?style=flat)](https://cocoapods.org/pods/BonsaiController) +[![License](https://img.shields.io/cocoapods/l/BonsaiController.svg?style=flat)](https://cocoapods.org/pods/BonsaiController) +[![Platform](https://img.shields.io/cocoapods/p/BonsaiController.svg?style=flat)](https://cocoapods.org/pods/BonsaiController) + + +**🌲 Bonsai** makes iOS View Controller present modally in any size and any position with cool transition animation. + +![Bonsai](https://user-images.githubusercontent.com/2233857/46226655-cbf61d80-c37e-11e8-9d2b-3d69177988a1.png) + +## Features + +* [x] Makes view controller appear as + - [x] Popup alert (no dismiss on tap outside) + - [x] Notification alert (auto dismiss after delay) + - [x] Side menu (drawer) +* [x] Transition animation + - [x] Slide In from left, right, top and bottom + - [x] Bubble pop from an initial frame or a view +* [x] Blur effect on background + - [x] light, dark, regular, prominent +* [x] Supports Storyboard and Code +* [x] Supports landscape and portrait orientation +* [x] Created with Swift compatible with Objective-C +* [x] Preserves Safe Area and Auto Layout constraints + +

+ + + +

+ + +## Installation with CocoaPods + +BonsaiController is available through [CocoaPods](https://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +use_frameworks! +pod 'BonsaiController' +``` + +## Install Manually + +Drag the `~/BonsaiController` directory anywhere in your project. + + +## How to use + +```Swift +import BonsaiController +``` + +Add (copy paste) `BonsaiControllerDelegate` extension to your view controller + +```Swift +extension YourViewController: BonsaiControllerDelegate { + + // return the frame of your Bonsai View Controller + func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { + + return CGRect(origin: CGPoint(x: 0, y: containerViewFrame.height / 4), size: CGSize(width: containerViewFrame.width, height: containerViewFrame.height / (4/3))) + } + + // return a Bonsai Controller with SlideIn or Bubble transition animator + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + + /// With Background Color /// + + // Slide animation from .left, .right, .top, .bottom + return BonsaiController(fromDirection: .bottom, backgroundColor: UIColor(white: 0, alpha: 0.5), presentedViewController: presented, delegate: self) + + // or Bubble animation initiated from a view + //return BonsaiController(fromView: yourOriginView, backgroundColor: UIColor(white: 0, alpha: 0.5), presentedViewController: presented, delegate: self) + + + /// With Blur Style /// + + // Slide animation from .left, .right, .top, .bottom + //return BonsaiController(fromDirection: .bottom, blurEffectStyle: .light, presentedViewController: presented, delegate: self) + + // or Bubble animation initiated from a view + //return BonsaiController(fromView: yourOriginView, blurEffectStyle: .dark, presentedViewController: presented, delegate: self) + } +} +``` + +## How to present the view controller + +### From Code: + +```Swift +let smallVC = YourViewController() // instantiateViewController(withIdentifier:) +smallVC.transitioningDelegate = self +smallVC.modalPresentationStyle = .custom +present(smallVC, animated: true, completion: nil) +``` + +### From Storyboard: + +```Swift +override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + + if segue.destination is YourViewController { + segue.destination.transitioningDelegate = self + segue.destination.modalPresentationStyle = .custom + } +} +``` + + +## Customize + +### Auto dismiss after delay + +```Swift +let bonsaiController = BonsaiController(... +bonsaiController.perform(#selector(bonsaiController.dismiss), with: nil, afterDelay: 2) +``` + +### Customizable properties (Default values) + +```Swift +bonsaiController.springWithDamping = 0.8 +bonsaiController.duration = 0.4 +bonsaiController.isDisabledTapOutside = false +bonsaiController.isDisabledDismissAnimation = false +bonsaiController.dismissDirection = nil // Reverse direction. Availabel only for slide in transition. +``` + +### Custom transition animation + +If you want to create your own transition animation, implement this protocol in your viewController + +```Swift +extension YourViewController: UIViewControllerTransitioningDelegate { + + func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + // Your presentation animation hear + } + + func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + // Your dismiss animation here + } +} +``` + +## Usage In Objective-C + +```objc +#import "YourModuleName-Swift.h" // only if project created in swift + +@import BonsaiController; +``` + +Add (copy paste) `BonsaiControllerDelegate` extension to your view controller + +```objc +// MARK:- Bonsai Controller Delegate +- (CGRect)frameOfPresentedViewIn:(CGRect)containerViewFrame { + + return CGRectMake(0, containerViewFrame.size.height / 4, containerViewFrame.size.width, containerViewFrame.size.height / (4.0 / 3.0)); +} + +- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source { + + // Slide animation from .left, .right, .top, .bottom + //return [[BonsaiController alloc] initFromDirection:DirectionBottom blurEffectStyle:UIBlurEffectStyleLight presentedViewController:presented delegate:self]; + + // or Bubble animation initiated from a view + return [[BonsaiController alloc] initFromView:self.exampleButton blurEffectStyle:UIBlurEffectStyleDark presentedViewController:presented delegate:self]; +} +``` + +### How to present the view controller(obj-c) + +### From Code: + +```objc +SmallViewController *smallVC = [self.storyboard instantiateViewControllerWithIdentifier:@"SmallVC"]; +smallVC.transitioningDelegate = self; +smallVC.modalPresentationStyle = UIModalPresentationCustom; +[self presentViewController:smallVC animated:true completion:nil]; +``` + +### From Storyboard: + +```objc +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + + if ([segue.destinationViewController isKindOfClass:SmallViewController.class]) { + segue.destinationViewController.transitioningDelegate = self; + segue.destinationViewController.modalPresentationStyle = UIModalPresentationCustom; + } +} +``` + + +## Example + +An example project is included with this repo. To run the example project, clone the repo, and run `pod install` from the Example directory first. + + +## Minimum Requirements + +* Xcode 10.2 with swift5 (check previous releases and pod versions for older xcode) +* iOS 9.3 + + +## Your input is welcome! + +If you have any suggestions, please get in touch with us.
+If you need help or found a bug, please open an issue.
+If you have a new transition animation or want to contribute, please submit a pull request. + + +## Let us know! + +If you like BonsaiController, give it a ★ at the top right of this page.
+Using BonsaiController in your app? Send us a link to your app in the app store! + + +## Credits + +- Jelly - https://github.com/SebastianBoldt/Jelly +- PresentHalfModal - https://github.com/khuong291/PresentHalfModal +- SideMenu - https://github.com/jonkykong/SideMenu +- TransitionTreasury - https://github.com/DianQK/TransitionTreasury +- Transition - https://github.com/Touchwonders/Transition +- StarWars.iOS - https://github.com/Yalantis/StarWars.iOS +- Hero - https://github.com/HeroTransitions/Hero + + +## Thank You + +A special thank you to everyone that has contributed to this library to make it better. Your support is appreciated! + + +## Author + +Developer: Warif Akhand Rishi, rishi420@gmail.com
+Designer: Takmila Tasmim Mim, mim.tasmim93@gmail.com + + +## License + +BonsaiController is available under the MIT license. See the LICENSE file for more info. + + + +## Support Us + +Buy Me A Coffee + diff --git a/frontend/mobile/Pods/Manifest.lock b/frontend/mobile/Pods/Manifest.lock new file mode 100644 index 0000000..0ecd01f --- /dev/null +++ b/frontend/mobile/Pods/Manifest.lock @@ -0,0 +1,20 @@ +PODS: + - BonsaiController (6.0.0) + - SwipeMenuViewController (4.1.0) + +DEPENDENCIES: + - BonsaiController + - SwipeMenuViewController + +SPEC REPOS: + trunk: + - BonsaiController + - SwipeMenuViewController + +SPEC CHECKSUMS: + BonsaiController: 63410fc39bc5b3a9df5b329dbc848b6b27edf663 + SwipeMenuViewController: 94fac81cc192d9f08f218fe4c0c853569b735e1f + +PODFILE CHECKSUM: 0ddfb5a4645e59b6a195a117a9d88dd7419fe64c + +COCOAPODS: 1.9.1 diff --git a/frontend/mobile/Pods/Pods.xcodeproj/project.pbxproj b/frontend/mobile/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..2a13b26 --- /dev/null +++ b/frontend/mobile/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,1203 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 23927711895669357A624B6274C7B486 /* SwipeMenuViewController-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C9556F62C45E8AB3C4C2B31FA73CB0FE /* SwipeMenuViewController-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 29D2D3E7CF0F6DC0CD3AF37B5ACD9C9A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */; }; + 29DE6DB6FCCAB675EDB8C9967EEBB8E3 /* SlideInTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B6F22067357238B7AA3F1991C218DA /* SlideInTransition.swift */; }; + 37E0C66C11901B6F9FB92EB4CBC4F959 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */; }; + 5D9D0DBC11B24B8A7489977321C4FF91 /* Pods-CommunityMC3Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DE3B013BAC511E15130C37BE1729A2E /* Pods-CommunityMC3Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6364EEA17806D3814C2B4DD781FAC9B2 /* Pods-CommunityMC3-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 13ADC8B6C95EB3BFC7398523A6F5FFD1 /* Pods-CommunityMC3-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 77B9153709D33EEAC012E34D88C1E142 /* TabItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88CA96BD8FFEAE1C522E74705A07372 /* TabItemView.swift */; }; + 7FF4F77DE1C0BF3E5197CA742DDFD6FA /* BonsaiController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DF7941F8E6E2736FC34597AC1BECE86 /* BonsaiController-dummy.m */; }; + 8D1CE5000597A547F432AE840A388D95 /* UIEdgeInsetsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBEE01AE6B183E3306F8E164EECC7C09 /* UIEdgeInsetsExtension.swift */; }; + 978B72FA8AC899CEBD07D8D5B1EE2325 /* Pods-CommunityMC3Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4768A2380BC18DCF07021DA92012FC12 /* Pods-CommunityMC3Tests-dummy.m */; }; + 9E97897CB645D4A0ED10AF87A1226193 /* SwipeMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC048EA5DBFAD9A2A7030A621341B747 /* SwipeMenuViewController.swift */; }; + B20A89DA00AC4D69E039FAB653CC96D0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */; }; + B46682AFD3AF846DE969FCFAEB90BEC0 /* SwipeMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FDA433E6C3E39EB653E5EDB8C9BAEDF /* SwipeMenuView.swift */; }; + B8054748ED471B1D05DC0EB10D90FB72 /* Pods-CommunityMC3-CommunityMC3UITests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D488C54F6965C28CCCF9FB09441208E3 /* Pods-CommunityMC3-CommunityMC3UITests-dummy.m */; }; + B83EA801DCBF5885334470E3156FCD2B /* Pods-CommunityMC3-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = DD812AD1C2C0C56C8CC0747D3FC682C5 /* Pods-CommunityMC3-dummy.m */; }; + B8BCD21052B6E65DD4E1C1CB00969721 /* ContentScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E492013F90EA81248A3CB01E7582FC2 /* ContentScrollView.swift */; }; + CB75C8E096148DC8CC2BDCE4662A0F68 /* BonsaiController-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 07BE045D7D492CD3E36A5BB8F05D7EBB /* BonsaiController-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CBF915A558CE3618D96CAA9D9398982C /* Pods-CommunityMC3-CommunityMC3UITests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 20544401EB8E9C3EC240097A0DB5C7BE /* Pods-CommunityMC3-CommunityMC3UITests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D258F210F7840137C23EDA5F2D9D4E1B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */; }; + DACB90AC59EBE6E6C41F87E372866824 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */; }; + DC0A43BF131B4A6C3A3C53F34CB2444E /* BonsaiController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6C2255DA7FEC6B0EE83BB13B373A972 /* BonsaiController.swift */; }; + DDD8609251AFED79B8F7532E3A206F05 /* SwipeMenuViewController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EF05B15F04E91D73BBB5F43A321181 /* SwipeMenuViewController-dummy.m */; }; + E37362A781482A2993DC681CFA753306 /* UIViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DB851848730ED79DAB0DC502341E6D5 /* UIViewExtension.swift */; }; + EA7C4E583BAD402C4D04F87AF5C6F2FB /* BubbleTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 490F777282A1152316FC564BA6591E72 /* BubbleTransition.swift */; }; + F6E4DEF530C0DBAE6EDCA9A721976F26 /* TabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFD70E9A2F625F0186822A421632CB0 /* TabView.swift */; }; + FF63FD182889BE28C253A8D1019982BD /* UIColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4BDC0CF75F542919C2F433CA1CD8FC /* UIColorExtension.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 08FB91DA9326EFD162EDB93F6F1E8947 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2DACB9880823AC6A3C72ED7C7B49473A; + remoteInfo = SwipeMenuViewController; + }; + 774449159A91644B28D739B520485B43 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2FC272E5264771C98573AEA8FB92240D; + remoteInfo = BonsaiController; + }; + 9F59CB9C5B31393F71E19F7F09D40311 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2DACB9880823AC6A3C72ED7C7B49473A; + remoteInfo = SwipeMenuViewController; + }; + A32E66518971723EDC48980C9BB212C1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6FA343366F287D947DC32A8A72B16927; + remoteInfo = "Pods-CommunityMC3"; + }; + ABA41E22CA913AC878C7854976032A42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2FC272E5264771C98573AEA8FB92240D; + remoteInfo = BonsaiController; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 032CAE0A403F5E0BD5A5D742CA038CB0 /* Pods-CommunityMC3-CommunityMC3UITests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-CommunityMC3-CommunityMC3UITests.modulemap"; sourceTree = ""; }; + 07171A20E28037B165C2A045301D91F3 /* SwipeMenuViewController.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwipeMenuViewController.modulemap; sourceTree = ""; }; + 07BE045D7D492CD3E36A5BB8F05D7EBB /* BonsaiController-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BonsaiController-umbrella.h"; sourceTree = ""; }; + 08E09CF621EE03E0B2527845B114D531 /* Pods_CommunityMC3.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_CommunityMC3.framework; path = "Pods-CommunityMC3.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 0AE6F657803079D7F4B2C01817562D9A /* SwipeMenuViewController.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwipeMenuViewController.debug.xcconfig; sourceTree = ""; }; + 13ADC8B6C95EB3BFC7398523A6F5FFD1 /* Pods-CommunityMC3-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-CommunityMC3-umbrella.h"; sourceTree = ""; }; + 1A4BDC0CF75F542919C2F433CA1CD8FC /* UIColorExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UIColorExtension.swift; path = Sources/Classes/UIColorExtension.swift; sourceTree = ""; }; + 20544401EB8E9C3EC240097A0DB5C7BE /* Pods-CommunityMC3-CommunityMC3UITests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-CommunityMC3-CommunityMC3UITests-umbrella.h"; sourceTree = ""; }; + 27B91A616D3E3D080255C6C93A591F62 /* BonsaiController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = BonsaiController.framework; path = BonsaiController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2DE3B013BAC511E15130C37BE1729A2E /* Pods-CommunityMC3Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-CommunityMC3Tests-umbrella.h"; sourceTree = ""; }; + 2DF7941F8E6E2736FC34597AC1BECE86 /* BonsaiController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "BonsaiController-dummy.m"; sourceTree = ""; }; + 3157B5895B481FF835327FCE5C50F493 /* BonsaiController-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "BonsaiController-Info.plist"; sourceTree = ""; }; + 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 40A902BA7F858067ABE8052CF6D62465 /* Pods-CommunityMC3.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CommunityMC3.release.xcconfig"; sourceTree = ""; }; + 40AB971BD9EF804E15C04B4086E21D08 /* Pods-CommunityMC3Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-CommunityMC3Tests.modulemap"; sourceTree = ""; }; + 40F384E6C95AE018929A00B7605F0A95 /* Pods-CommunityMC3-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CommunityMC3-frameworks.sh"; sourceTree = ""; }; + 4768A2380BC18DCF07021DA92012FC12 /* Pods-CommunityMC3Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CommunityMC3Tests-dummy.m"; sourceTree = ""; }; + 490F777282A1152316FC564BA6591E72 /* BubbleTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BubbleTransition.swift; path = BonsaiController/Classes/BubbleTransition.swift; sourceTree = ""; }; + 5653A1CEC6958D9F649D1BB6A936E167 /* Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh"; sourceTree = ""; }; + 5667D56FF69EA8921A31AABB19F7CFA0 /* SwipeMenuViewController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwipeMenuViewController.framework; path = SwipeMenuViewController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5CDF03FBA430A72706777885074B1410 /* SwipeMenuViewController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwipeMenuViewController-prefix.pch"; sourceTree = ""; }; + 5FDA433E6C3E39EB653E5EDB8C9BAEDF /* SwipeMenuView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwipeMenuView.swift; path = Sources/Classes/SwipeMenuView.swift; sourceTree = ""; }; + 61B6F22067357238B7AA3F1991C218DA /* SlideInTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SlideInTransition.swift; path = BonsaiController/Classes/SlideInTransition.swift; sourceTree = ""; }; + 645485A65080D50CAF17FF28B012304D /* Pods-CommunityMC3-CommunityMC3UITests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CommunityMC3-CommunityMC3UITests-Info.plist"; sourceTree = ""; }; + 659923621460D1091FE915D67CB3D57C /* Pods-CommunityMC3-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CommunityMC3-Info.plist"; sourceTree = ""; }; + 661C5F4C4D39086747BA2AF8608B95D5 /* Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.markdown"; sourceTree = ""; }; + 6C5552CC6A31E3F17A0B568D32F3F984 /* Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig"; sourceTree = ""; }; + 71A29E932F7E1A8412554691A511DC29 /* Pods-CommunityMC3Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CommunityMC3Tests.release.xcconfig"; sourceTree = ""; }; + 7A34948E0C9C19FBF36138FC0EDD6E53 /* Pods-CommunityMC3.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-CommunityMC3.modulemap"; sourceTree = ""; }; + 7DB851848730ED79DAB0DC502341E6D5 /* UIViewExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UIViewExtension.swift; path = Sources/Classes/UIViewExtension.swift; sourceTree = ""; }; + 7E492013F90EA81248A3CB01E7582FC2 /* ContentScrollView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ContentScrollView.swift; path = Sources/Classes/ContentScrollView.swift; sourceTree = ""; }; + 7E8763ABB9F29B2BB467B16EF237C589 /* BonsaiController.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BonsaiController.debug.xcconfig; sourceTree = ""; }; + 86A7E98112B90679F3750CA6474BA979 /* Pods-CommunityMC3-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CommunityMC3-acknowledgements.markdown"; sourceTree = ""; }; + 8796CDDDFBFBC74760FCE4CD7803011C /* Pods-CommunityMC3-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CommunityMC3-acknowledgements.plist"; sourceTree = ""; }; + 8E0A7237DA3244C042D134B7ABB8B866 /* BonsaiController.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BonsaiController.release.xcconfig; sourceTree = ""; }; + 8EB3482B2FCECD890C08E94F33E04B7B /* BonsaiController.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = BonsaiController.modulemap; sourceTree = ""; }; + 923029E3C91B440327345AA8C9438B08 /* Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.plist"; sourceTree = ""; }; + 9BE82D28906F353D4A8E149AF5A0C614 /* SwipeMenuViewController.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwipeMenuViewController.release.xcconfig; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + AC048EA5DBFAD9A2A7030A621341B747 /* SwipeMenuViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwipeMenuViewController.swift; path = Sources/Classes/SwipeMenuViewController.swift; sourceTree = ""; }; + B796F239F050249B817A51C51DE2FA92 /* Pods_CommunityMC3_CommunityMC3UITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_CommunityMC3_CommunityMC3UITests.framework; path = "Pods-CommunityMC3-CommunityMC3UITests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + BA077799A8AF35AD952B453048D22F16 /* Pods-CommunityMC3Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-CommunityMC3Tests-acknowledgements.markdown"; sourceTree = ""; }; + C9556F62C45E8AB3C4C2B31FA73CB0FE /* SwipeMenuViewController-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwipeMenuViewController-umbrella.h"; sourceTree = ""; }; + CEAC8F7448FF13E95B2D53C381CF5129 /* Pods-CommunityMC3Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CommunityMC3Tests-acknowledgements.plist"; sourceTree = ""; }; + D0D98792DAA8B5A8CAB28C5E86023188 /* Pods-CommunityMC3.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CommunityMC3.debug.xcconfig"; sourceTree = ""; }; + D488C54F6965C28CCCF9FB09441208E3 /* Pods-CommunityMC3-CommunityMC3UITests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CommunityMC3-CommunityMC3UITests-dummy.m"; sourceTree = ""; }; + D6D0EA47E210C844BEB457BD2217E9A4 /* Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig"; sourceTree = ""; }; + D9EF05B15F04E91D73BBB5F43A321181 /* SwipeMenuViewController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwipeMenuViewController-dummy.m"; sourceTree = ""; }; + DCFD70E9A2F625F0186822A421632CB0 /* TabView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TabView.swift; path = Sources/Classes/TabView.swift; sourceTree = ""; }; + DD812AD1C2C0C56C8CC0747D3FC682C5 /* Pods-CommunityMC3-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-CommunityMC3-dummy.m"; sourceTree = ""; }; + E50862C988E72897C96A139E2C7C9EDD /* Pods_CommunityMC3Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_CommunityMC3Tests.framework; path = "Pods-CommunityMC3Tests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + E6C2255DA7FEC6B0EE83BB13B373A972 /* BonsaiController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BonsaiController.swift; path = BonsaiController/Classes/BonsaiController.swift; sourceTree = ""; }; + E9597A5C8C2F2538DB153243DB94D70C /* Pods-CommunityMC3Tests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-CommunityMC3Tests-Info.plist"; sourceTree = ""; }; + EB598D992CE8290A480F30C2C701C55D /* BonsaiController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BonsaiController-prefix.pch"; sourceTree = ""; }; + F4226F954E7FF462609352001C4613E0 /* SwipeMenuViewController-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwipeMenuViewController-Info.plist"; sourceTree = ""; }; + F61FAF055FDD0DF05901D0B21F4C4568 /* Pods-CommunityMC3Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-CommunityMC3Tests.debug.xcconfig"; sourceTree = ""; }; + F88CA96BD8FFEAE1C522E74705A07372 /* TabItemView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TabItemView.swift; path = Sources/Classes/TabItemView.swift; sourceTree = ""; }; + FBEE01AE6B183E3306F8E164EECC7C09 /* UIEdgeInsetsExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UIEdgeInsetsExtension.swift; path = Sources/Classes/UIEdgeInsetsExtension.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 08159080B1D8FDCFC4CFFAC7372EA32F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 29D2D3E7CF0F6DC0CD3AF37B5ACD9C9A /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2A3B0E9CD3B61E9F924CC2CF8658714E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B20A89DA00AC4D69E039FAB653CC96D0 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6642428493F279623E3F742130118CCA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 37E0C66C11901B6F9FB92EB4CBC4F959 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9955DAB08304A79313BEBDDB2457F0F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D258F210F7840137C23EDA5F2D9D4E1B /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B04076BCD0FD05FDD21F46460F5DA2A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DACB90AC59EBE6E6C41F87E372866824 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1FD0F4608CF275D20B3058DDE650AEFD /* Support Files */ = { + isa = PBXGroup; + children = ( + 07171A20E28037B165C2A045301D91F3 /* SwipeMenuViewController.modulemap */, + D9EF05B15F04E91D73BBB5F43A321181 /* SwipeMenuViewController-dummy.m */, + F4226F954E7FF462609352001C4613E0 /* SwipeMenuViewController-Info.plist */, + 5CDF03FBA430A72706777885074B1410 /* SwipeMenuViewController-prefix.pch */, + C9556F62C45E8AB3C4C2B31FA73CB0FE /* SwipeMenuViewController-umbrella.h */, + 0AE6F657803079D7F4B2C01817562D9A /* SwipeMenuViewController.debug.xcconfig */, + 9BE82D28906F353D4A8E149AF5A0C614 /* SwipeMenuViewController.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwipeMenuViewController"; + sourceTree = ""; + }; + 32D8FD627EE693FC3B4AB5C44D49FC00 /* Pods-CommunityMC3-CommunityMC3UITests */ = { + isa = PBXGroup; + children = ( + 032CAE0A403F5E0BD5A5D742CA038CB0 /* Pods-CommunityMC3-CommunityMC3UITests.modulemap */, + 661C5F4C4D39086747BA2AF8608B95D5 /* Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.markdown */, + 923029E3C91B440327345AA8C9438B08 /* Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.plist */, + D488C54F6965C28CCCF9FB09441208E3 /* Pods-CommunityMC3-CommunityMC3UITests-dummy.m */, + 5653A1CEC6958D9F649D1BB6A936E167 /* Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh */, + 645485A65080D50CAF17FF28B012304D /* Pods-CommunityMC3-CommunityMC3UITests-Info.plist */, + 20544401EB8E9C3EC240097A0DB5C7BE /* Pods-CommunityMC3-CommunityMC3UITests-umbrella.h */, + D6D0EA47E210C844BEB457BD2217E9A4 /* Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig */, + 6C5552CC6A31E3F17A0B568D32F3F984 /* Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig */, + ); + name = "Pods-CommunityMC3-CommunityMC3UITests"; + path = "Target Support Files/Pods-CommunityMC3-CommunityMC3UITests"; + sourceTree = ""; + }; + 514AB5801B3C2F15233501CDEFCF1B2F /* Products */ = { + isa = PBXGroup; + children = ( + 27B91A616D3E3D080255C6C93A591F62 /* BonsaiController.framework */, + 08E09CF621EE03E0B2527845B114D531 /* Pods_CommunityMC3.framework */, + B796F239F050249B817A51C51DE2FA92 /* Pods_CommunityMC3_CommunityMC3UITests.framework */, + E50862C988E72897C96A139E2C7C9EDD /* Pods_CommunityMC3Tests.framework */, + 5667D56FF69EA8921A31AABB19F7CFA0 /* SwipeMenuViewController.framework */, + ); + name = Products; + sourceTree = ""; + }; + 551D80CA40A57DAD015610DECD1A9A3C /* Support Files */ = { + isa = PBXGroup; + children = ( + 8EB3482B2FCECD890C08E94F33E04B7B /* BonsaiController.modulemap */, + 2DF7941F8E6E2736FC34597AC1BECE86 /* BonsaiController-dummy.m */, + 3157B5895B481FF835327FCE5C50F493 /* BonsaiController-Info.plist */, + EB598D992CE8290A480F30C2C701C55D /* BonsaiController-prefix.pch */, + 07BE045D7D492CD3E36A5BB8F05D7EBB /* BonsaiController-umbrella.h */, + 7E8763ABB9F29B2BB467B16EF237C589 /* BonsaiController.debug.xcconfig */, + 8E0A7237DA3244C042D134B7ABB8B866 /* BonsaiController.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/BonsaiController"; + sourceTree = ""; + }; + 5C15227D1BA33831C6EF0D78F4DA3A8F /* BonsaiController */ = { + isa = PBXGroup; + children = ( + E6C2255DA7FEC6B0EE83BB13B373A972 /* BonsaiController.swift */, + 490F777282A1152316FC564BA6591E72 /* BubbleTransition.swift */, + 61B6F22067357238B7AA3F1991C218DA /* SlideInTransition.swift */, + 551D80CA40A57DAD015610DECD1A9A3C /* Support Files */, + ); + name = BonsaiController; + path = BonsaiController; + sourceTree = ""; + }; + 7081F3206D8B938D8B511FEAADC5938B /* Pods-CommunityMC3Tests */ = { + isa = PBXGroup; + children = ( + 40AB971BD9EF804E15C04B4086E21D08 /* Pods-CommunityMC3Tests.modulemap */, + BA077799A8AF35AD952B453048D22F16 /* Pods-CommunityMC3Tests-acknowledgements.markdown */, + CEAC8F7448FF13E95B2D53C381CF5129 /* Pods-CommunityMC3Tests-acknowledgements.plist */, + 4768A2380BC18DCF07021DA92012FC12 /* Pods-CommunityMC3Tests-dummy.m */, + E9597A5C8C2F2538DB153243DB94D70C /* Pods-CommunityMC3Tests-Info.plist */, + 2DE3B013BAC511E15130C37BE1729A2E /* Pods-CommunityMC3Tests-umbrella.h */, + F61FAF055FDD0DF05901D0B21F4C4568 /* Pods-CommunityMC3Tests.debug.xcconfig */, + 71A29E932F7E1A8412554691A511DC29 /* Pods-CommunityMC3Tests.release.xcconfig */, + ); + name = "Pods-CommunityMC3Tests"; + path = "Target Support Files/Pods-CommunityMC3Tests"; + sourceTree = ""; + }; + C0834CEBB1379A84116EF29F93051C60 /* iOS */ = { + isa = PBXGroup; + children = ( + 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; + C1E168B4373E1D728218C754B65E7BE2 /* SwipeMenuViewController */ = { + isa = PBXGroup; + children = ( + 7E492013F90EA81248A3CB01E7582FC2 /* ContentScrollView.swift */, + 5FDA433E6C3E39EB653E5EDB8C9BAEDF /* SwipeMenuView.swift */, + AC048EA5DBFAD9A2A7030A621341B747 /* SwipeMenuViewController.swift */, + F88CA96BD8FFEAE1C522E74705A07372 /* TabItemView.swift */, + DCFD70E9A2F625F0186822A421632CB0 /* TabView.swift */, + 1A4BDC0CF75F542919C2F433CA1CD8FC /* UIColorExtension.swift */, + FBEE01AE6B183E3306F8E164EECC7C09 /* UIEdgeInsetsExtension.swift */, + 7DB851848730ED79DAB0DC502341E6D5 /* UIViewExtension.swift */, + 1FD0F4608CF275D20B3058DDE650AEFD /* Support Files */, + ); + name = SwipeMenuViewController; + path = SwipeMenuViewController; + sourceTree = ""; + }; + C532728BF07F57E77F07E5A7C1C4C82A /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + D8ECE04725A2C3E292AFCADD03C290BC /* Pods-CommunityMC3 */, + 32D8FD627EE693FC3B4AB5C44D49FC00 /* Pods-CommunityMC3-CommunityMC3UITests */, + 7081F3206D8B938D8B511FEAADC5938B /* Pods-CommunityMC3Tests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, + E9379C7E1DEA9C898663BF32D0836214 /* Pods */, + 514AB5801B3C2F15233501CDEFCF1B2F /* Products */, + C532728BF07F57E77F07E5A7C1C4C82A /* Targets Support Files */, + ); + sourceTree = ""; + }; + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + C0834CEBB1379A84116EF29F93051C60 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + D8ECE04725A2C3E292AFCADD03C290BC /* Pods-CommunityMC3 */ = { + isa = PBXGroup; + children = ( + 7A34948E0C9C19FBF36138FC0EDD6E53 /* Pods-CommunityMC3.modulemap */, + 86A7E98112B90679F3750CA6474BA979 /* Pods-CommunityMC3-acknowledgements.markdown */, + 8796CDDDFBFBC74760FCE4CD7803011C /* Pods-CommunityMC3-acknowledgements.plist */, + DD812AD1C2C0C56C8CC0747D3FC682C5 /* Pods-CommunityMC3-dummy.m */, + 40F384E6C95AE018929A00B7605F0A95 /* Pods-CommunityMC3-frameworks.sh */, + 659923621460D1091FE915D67CB3D57C /* Pods-CommunityMC3-Info.plist */, + 13ADC8B6C95EB3BFC7398523A6F5FFD1 /* Pods-CommunityMC3-umbrella.h */, + D0D98792DAA8B5A8CAB28C5E86023188 /* Pods-CommunityMC3.debug.xcconfig */, + 40A902BA7F858067ABE8052CF6D62465 /* Pods-CommunityMC3.release.xcconfig */, + ); + name = "Pods-CommunityMC3"; + path = "Target Support Files/Pods-CommunityMC3"; + sourceTree = ""; + }; + E9379C7E1DEA9C898663BF32D0836214 /* Pods */ = { + isa = PBXGroup; + children = ( + 5C15227D1BA33831C6EF0D78F4DA3A8F /* BonsaiController */, + C1E168B4373E1D728218C754B65E7BE2 /* SwipeMenuViewController */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 26D405FD310853E1D9176FB3DB390EAC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 23927711895669357A624B6274C7B486 /* SwipeMenuViewController-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3E01EEB677465F3601FAF44120BEEC2C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6364EEA17806D3814C2B4DD781FAC9B2 /* Pods-CommunityMC3-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40FC0EFF864CC9A77AB7AD1750BFC844 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 5D9D0DBC11B24B8A7489977321C4FF91 /* Pods-CommunityMC3Tests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 67A6AFFB5C57E2E85F4C61CE46A45603 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF915A558CE3618D96CAA9D9398982C /* Pods-CommunityMC3-CommunityMC3UITests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B45AC7DCD2B3AD633D2A9E79D681D7BB /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + CB75C8E096148DC8CC2BDCE4662A0F68 /* BonsaiController-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 0F34E5E9568F400F7342D2099002C803 /* Pods-CommunityMC3-CommunityMC3UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 70ADA5ADDF5ABE56889DA5751AC0AA3B /* Build configuration list for PBXNativeTarget "Pods-CommunityMC3-CommunityMC3UITests" */; + buildPhases = ( + 67A6AFFB5C57E2E85F4C61CE46A45603 /* Headers */, + 35E3C154213353946EAADD3C7003186D /* Sources */, + B04076BCD0FD05FDD21F46460F5DA2A6 /* Frameworks */, + A1AA5CB4742491D3C68E950865BEE3C1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 184A554ABD7A6AE7DF13897DA4C82EE3 /* PBXTargetDependency */, + 27F168F36CC76AD903D1A67813906693 /* PBXTargetDependency */, + ); + name = "Pods-CommunityMC3-CommunityMC3UITests"; + productName = "Pods-CommunityMC3-CommunityMC3UITests"; + productReference = B796F239F050249B817A51C51DE2FA92 /* Pods_CommunityMC3_CommunityMC3UITests.framework */; + productType = "com.apple.product-type.framework"; + }; + 2DACB9880823AC6A3C72ED7C7B49473A /* SwipeMenuViewController */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2C3D8E8FBA3C7321B9090D88DD887914 /* Build configuration list for PBXNativeTarget "SwipeMenuViewController" */; + buildPhases = ( + 26D405FD310853E1D9176FB3DB390EAC /* Headers */, + F0467B5C0466FC2BF593427338499141 /* Sources */, + 08159080B1D8FDCFC4CFFAC7372EA32F /* Frameworks */, + DC8FC5D9C56CEC714AC05EDD847FE395 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwipeMenuViewController; + productName = SwipeMenuViewController; + productReference = 5667D56FF69EA8921A31AABB19F7CFA0 /* SwipeMenuViewController.framework */; + productType = "com.apple.product-type.framework"; + }; + 2FC272E5264771C98573AEA8FB92240D /* BonsaiController */ = { + isa = PBXNativeTarget; + buildConfigurationList = 439B023EB0FA3E4012D3B860EEFD211C /* Build configuration list for PBXNativeTarget "BonsaiController" */; + buildPhases = ( + B45AC7DCD2B3AD633D2A9E79D681D7BB /* Headers */, + 9870520D6705E305D300E0FE04C59FB5 /* Sources */, + 2A3B0E9CD3B61E9F924CC2CF8658714E /* Frameworks */, + E257465CB68D92F9EBEF0EA650815D16 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BonsaiController; + productName = BonsaiController; + productReference = 27B91A616D3E3D080255C6C93A591F62 /* BonsaiController.framework */; + productType = "com.apple.product-type.framework"; + }; + 4AF7CE5599BA8C5DA85216AA98602E44 /* Pods-CommunityMC3Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F508A19C88F64A500DFDFA57BECF521A /* Build configuration list for PBXNativeTarget "Pods-CommunityMC3Tests" */; + buildPhases = ( + 40FC0EFF864CC9A77AB7AD1750BFC844 /* Headers */, + 3E70D4714F62AAFA8343A7C009558C69 /* Sources */, + 6642428493F279623E3F742130118CCA /* Frameworks */, + 97E71AC84932A068A8C016E67A715AC7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + F03D5C8C6ACD4B43BB89EE850336DF9D /* PBXTargetDependency */, + ); + name = "Pods-CommunityMC3Tests"; + productName = "Pods-CommunityMC3Tests"; + productReference = E50862C988E72897C96A139E2C7C9EDD /* Pods_CommunityMC3Tests.framework */; + productType = "com.apple.product-type.framework"; + }; + 6FA343366F287D947DC32A8A72B16927 /* Pods-CommunityMC3 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2F63707A52D2D931656BD7567868C0B0 /* Build configuration list for PBXNativeTarget "Pods-CommunityMC3" */; + buildPhases = ( + 3E01EEB677465F3601FAF44120BEEC2C /* Headers */, + 92028A023B514D5F9FF3073070FDE155 /* Sources */, + 9955DAB08304A79313BEBDDB2457F0F3 /* Frameworks */, + 1EF823C872E980F26FEC905F6312B700 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B28A77318C8EFDD7F0456F3A9ECE0EB5 /* PBXTargetDependency */, + 9EA21F454733205D1A9BEE7DB467AD7A /* PBXTargetDependency */, + ); + name = "Pods-CommunityMC3"; + productName = "Pods-CommunityMC3"; + productReference = 08E09CF621EE03E0B2527845B114D531 /* Pods_CommunityMC3.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BFDFE7DC352907FC980B868725387E98 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + }; + buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = 514AB5801B3C2F15233501CDEFCF1B2F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2FC272E5264771C98573AEA8FB92240D /* BonsaiController */, + 6FA343366F287D947DC32A8A72B16927 /* Pods-CommunityMC3 */, + 0F34E5E9568F400F7342D2099002C803 /* Pods-CommunityMC3-CommunityMC3UITests */, + 4AF7CE5599BA8C5DA85216AA98602E44 /* Pods-CommunityMC3Tests */, + 2DACB9880823AC6A3C72ED7C7B49473A /* SwipeMenuViewController */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1EF823C872E980F26FEC905F6312B700 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97E71AC84932A068A8C016E67A715AC7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1AA5CB4742491D3C68E950865BEE3C1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC8FC5D9C56CEC714AC05EDD847FE395 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E257465CB68D92F9EBEF0EA650815D16 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 35E3C154213353946EAADD3C7003186D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8054748ED471B1D05DC0EB10D90FB72 /* Pods-CommunityMC3-CommunityMC3UITests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3E70D4714F62AAFA8343A7C009558C69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B72FA8AC899CEBD07D8D5B1EE2325 /* Pods-CommunityMC3Tests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 92028A023B514D5F9FF3073070FDE155 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B83EA801DCBF5885334470E3156FCD2B /* Pods-CommunityMC3-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9870520D6705E305D300E0FE04C59FB5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FF4F77DE1C0BF3E5197CA742DDFD6FA /* BonsaiController-dummy.m in Sources */, + DC0A43BF131B4A6C3A3C53F34CB2444E /* BonsaiController.swift in Sources */, + EA7C4E583BAD402C4D04F87AF5C6F2FB /* BubbleTransition.swift in Sources */, + 29DE6DB6FCCAB675EDB8C9967EEBB8E3 /* SlideInTransition.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F0467B5C0466FC2BF593427338499141 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8BCD21052B6E65DD4E1C1CB00969721 /* ContentScrollView.swift in Sources */, + B46682AFD3AF846DE969FCFAEB90BEC0 /* SwipeMenuView.swift in Sources */, + DDD8609251AFED79B8F7532E3A206F05 /* SwipeMenuViewController-dummy.m in Sources */, + 9E97897CB645D4A0ED10AF87A1226193 /* SwipeMenuViewController.swift in Sources */, + 77B9153709D33EEAC012E34D88C1E142 /* TabItemView.swift in Sources */, + F6E4DEF530C0DBAE6EDCA9A721976F26 /* TabView.swift in Sources */, + FF63FD182889BE28C253A8D1019982BD /* UIColorExtension.swift in Sources */, + 8D1CE5000597A547F432AE840A388D95 /* UIEdgeInsetsExtension.swift in Sources */, + E37362A781482A2993DC681CFA753306 /* UIViewExtension.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 184A554ABD7A6AE7DF13897DA4C82EE3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BonsaiController; + target = 2FC272E5264771C98573AEA8FB92240D /* BonsaiController */; + targetProxy = ABA41E22CA913AC878C7854976032A42 /* PBXContainerItemProxy */; + }; + 27F168F36CC76AD903D1A67813906693 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwipeMenuViewController; + target = 2DACB9880823AC6A3C72ED7C7B49473A /* SwipeMenuViewController */; + targetProxy = 9F59CB9C5B31393F71E19F7F09D40311 /* PBXContainerItemProxy */; + }; + 9EA21F454733205D1A9BEE7DB467AD7A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwipeMenuViewController; + target = 2DACB9880823AC6A3C72ED7C7B49473A /* SwipeMenuViewController */; + targetProxy = 08FB91DA9326EFD162EDB93F6F1E8947 /* PBXContainerItemProxy */; + }; + B28A77318C8EFDD7F0456F3A9ECE0EB5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BonsaiController; + target = 2FC272E5264771C98573AEA8FB92240D /* BonsaiController */; + targetProxy = 774449159A91644B28D739B520485B43 /* PBXContainerItemProxy */; + }; + F03D5C8C6ACD4B43BB89EE850336DF9D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-CommunityMC3"; + target = 6FA343366F287D947DC32A8A72B16927 /* Pods-CommunityMC3 */; + targetProxy = A32E66518971723EDC48980C9BB212C1 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 10199B27233A7CFEB3BD39F9923309A4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7E8763ABB9F29B2BB467B16EF237C589 /* BonsaiController.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/BonsaiController/BonsaiController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/BonsaiController/BonsaiController-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/BonsaiController/BonsaiController.modulemap"; + PRODUCT_MODULE_NAME = BonsaiController; + PRODUCT_NAME = BonsaiController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 16E3289A2F671A585CFBDDA45CF852AC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D6D0EA47E210C844BEB457BD2217E9A4 /* Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 3891F13EFF461566DEF9A35FC8BB1B1D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F61FAF055FDD0DF05901D0B21F4C4568 /* Pods-CommunityMC3Tests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 3F1F1F68B698034E500399068CF8B487 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6C5552CC6A31E3F17A0B568D32F3F984 /* Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 510B057D2E9F059C50D52DA5D90F3ACF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + 804E13245C9FBBE6A340C555CA8B2B4C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 880821F0EBE3077CA6CC933B9D82B238 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9BE82D28906F353D4A8E149AF5A0C614 /* SwipeMenuViewController.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwipeMenuViewController/SwipeMenuViewController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwipeMenuViewController/SwipeMenuViewController-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwipeMenuViewController/SwipeMenuViewController.modulemap"; + PRODUCT_MODULE_NAME = SwipeMenuViewController; + PRODUCT_NAME = SwipeMenuViewController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 929CF96F7ECA7E44069DAAE364ED0FA0 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0AE6F657803079D7F4B2C01817562D9A /* SwipeMenuViewController.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwipeMenuViewController/SwipeMenuViewController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwipeMenuViewController/SwipeMenuViewController-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwipeMenuViewController/SwipeMenuViewController.modulemap"; + PRODUCT_MODULE_NAME = SwipeMenuViewController; + PRODUCT_NAME = SwipeMenuViewController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A868712B1B1941DFB67CBD23E59FA61C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 71A29E932F7E1A8412554691A511DC29 /* Pods-CommunityMC3Tests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + AC844661AE66FDA13171E1756ADDF6B3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D0D98792DAA8B5A8CAB28C5E86023188 /* Pods-CommunityMC3.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + BAE32A248216A7B04B1267B424A41D10 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8E0A7237DA3244C042D134B7ABB8B866 /* BonsaiController.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/BonsaiController/BonsaiController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/BonsaiController/BonsaiController-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/BonsaiController/BonsaiController.modulemap"; + PRODUCT_MODULE_NAME = BonsaiController; + PRODUCT_NAME = BonsaiController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + D14744C3584854497E6ECEF15F45D192 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40A902BA7F858067ABE8052CF6D62465 /* Pods-CommunityMC3.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2C3D8E8FBA3C7321B9090D88DD887914 /* Build configuration list for PBXNativeTarget "SwipeMenuViewController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 929CF96F7ECA7E44069DAAE364ED0FA0 /* Debug */, + 880821F0EBE3077CA6CC933B9D82B238 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2F63707A52D2D931656BD7567868C0B0 /* Build configuration list for PBXNativeTarget "Pods-CommunityMC3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC844661AE66FDA13171E1756ADDF6B3 /* Debug */, + D14744C3584854497E6ECEF15F45D192 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 439B023EB0FA3E4012D3B860EEFD211C /* Build configuration list for PBXNativeTarget "BonsaiController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 10199B27233A7CFEB3BD39F9923309A4 /* Debug */, + BAE32A248216A7B04B1267B424A41D10 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 804E13245C9FBBE6A340C555CA8B2B4C /* Debug */, + 510B057D2E9F059C50D52DA5D90F3ACF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 70ADA5ADDF5ABE56889DA5751AC0AA3B /* Build configuration list for PBXNativeTarget "Pods-CommunityMC3-CommunityMC3UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 16E3289A2F671A585CFBDDA45CF852AC /* Debug */, + 3F1F1F68B698034E500399068CF8B487 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F508A19C88F64A500DFDFA57BECF521A /* Build configuration list for PBXNativeTarget "Pods-CommunityMC3Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3891F13EFF461566DEF9A35FC8BB1B1D /* Debug */, + A868712B1B1941DFB67CBD23E59FA61C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; +} diff --git a/frontend/mobile/Pods/SwipeMenuViewController/LICENSE b/frontend/mobile/Pods/SwipeMenuViewController/LICENSE new file mode 100644 index 0000000..69e40ea --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2017 Yusuke Morishita + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/mobile/Pods/SwipeMenuViewController/README.md b/frontend/mobile/Pods/SwipeMenuViewController/README.md new file mode 100644 index 0000000..3ed5090 --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/README.md @@ -0,0 +1,62 @@ +# SwipeMenuViewController + +[![Platform](http://img.shields.io/badge/platform-iOS-blue.svg?style=for-the-badge)](https://developer.apple.com/iphone/index.action) +[![Cocoapods](https://img.shields.io/badge/Cocoapods-compatible-brightgreen.svg?style=for-the-badge)](https://img.shields.io/badge/Cocoapods-compatible-brightgreen.svg) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=for-the-badge)](https://github.com/Carthage/Carthage) +[![SPM compatible](https://img.shields.io/badge/SPM-Compatible-brightgreen.svg?style=for-the-badge)](https://github.com/apple/swift-package-manager) +[![License](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=for-the-badge)](http://mit-license.org) + +## Overview +SwipeMenuViewController provides `SwipeMenuView` and `SwipeMenuViewController`. +This is very useful to build swipe-based paging UI. +The interface is as simple as UIKit's. + +## Demo +Here are some style of demos using `SwipeMenuView`. + +| Segmented Tab & Underline | Flexible Tab & Underline | Flexible Tab & Circle | +|:---:|:---:|:---:| +| | | | + +## Installation +### CocoaPods +You can integrate via [CocoaPods](https://cocoapods.org). +Add the following line to your `Podfile` : + +``` +pod 'SwipeMenuViewController' +``` + +and run `pod install` + +### Carthage + +You can integrate via [Carthage](https://github.com/carthage/carthage), too. +Add the following line to your `Cartfile` : + +``` +github "yysskk/SwipeMenuViewController" +``` + +and run `carthage update` + +### Swift Package Manager + +You can integrate via [Swift Package Manager](https://github.com/apple/swift-package-manager), too. +See the following site for instructions. + +- [Adding Package Dependencies to Your App](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) + +## Documentation +- See [Usage](Documentation/Usage.md) documentation for all the various properties and options that can be set +- See [Versioning](Documentaion/Versioning.md) for versioning documentation + +## Author +### Yusuke Morishita +- [Github](https://github.com/yysskk) +- [Twitter](https://twitter.com/_yysskk) + +[![Support via PayPal](https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg)](https://www.paypal.me/yysskk/980jpy) + +## License +`SwipeMenuViewController` is available under the MIT license. See the [LICENSE](./LICENSE) file for more info. diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/ContentScrollView.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/ContentScrollView.swift new file mode 100644 index 0000000..9bc8a3a --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/ContentScrollView.swift @@ -0,0 +1,158 @@ +import UIKit + +public protocol ContentScrollViewDataSource { + + func numberOfPages(in contentScrollView: ContentScrollView) -> Int + + func contentScrollView(_ contentScrollView: ContentScrollView, viewForPageAt index: Int) -> UIView? +} + +open class ContentScrollView: UIScrollView { + + open var dataSource: ContentScrollViewDataSource? + + fileprivate var pageViews: [UIView] = [] + + fileprivate var currentIndex: Int = 0 + + fileprivate var options: SwipeMenuViewOptions.ContentScrollView = SwipeMenuViewOptions.ContentScrollView() + + public init(frame: CGRect, default defaultIndex: Int, options: SwipeMenuViewOptions.ContentScrollView? = nil) { + super.init(frame: frame) + + currentIndex = defaultIndex + + if #available(iOS 11.0, *) { + self.contentInsetAdjustmentBehavior = .never + } + + if let options = options { + self.options = options + } + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open override func didMoveToSuperview() { + setup() + } + + override open func layoutSubviews() { + super.layoutSubviews() + + self.contentSize = CGSize(width: frame.width * CGFloat(pageViews.count), height: frame.height) + } + + public func reset() { + pageViews = [] + currentIndex = 0 + } + + public func reload() { + self.didMoveToSuperview() + } + + public func update(_ newIndex: Int) { + currentIndex = newIndex + } + + // MARK: - Setup + + fileprivate func setup() { + + guard let dataSource = dataSource else { return } + if dataSource.numberOfPages(in: self) <= 0 { return } + + setupScrollView() + setupPages() + } + + fileprivate func setupScrollView() { + backgroundColor = options.backgroundColor + showsHorizontalScrollIndicator = false + showsVerticalScrollIndicator = false + isScrollEnabled = options.isScrollEnabled + isPagingEnabled = true + isDirectionalLockEnabled = false + alwaysBounceHorizontal = false + scrollsToTop = false + bounces = false + bouncesZoom = false + setContentOffset(.zero, animated: false) + } + + private func setupPages() { + pageViews = [] + + guard let dataSource = dataSource, dataSource.numberOfPages(in: self) > 0 else { return } + + self.contentSize = CGSize(width: frame.width * CGFloat(dataSource.numberOfPages(in: self)), height: frame.height) + + for i in 0...currentIndex { + guard let pageView = dataSource.contentScrollView(self, viewForPageAt: i) else { return } + pageViews.append(pageView) + addSubview(pageView) + + let leadingAnchor = i > 0 ? pageViews[i - 1].trailingAnchor : self.leadingAnchor + pageView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + pageView.topAnchor.constraint(equalTo: self.topAnchor), + pageView.widthAnchor.constraint(equalTo: self.widthAnchor), + pageView.heightAnchor.constraint(equalTo: self.heightAnchor), + pageView.leadingAnchor.constraint(equalTo: leadingAnchor) + ]) + } + + guard currentIndex < dataSource.numberOfPages(in: self) else { return } + for i in (currentIndex + 1)..= 0 { + return pageViews[currentIndex] + } + + return nil + } + + var nextPage: UIView? { + + if currentIndex < pageViews.count - 1 { + return pageViews[currentIndex + 1] + } + + return nil + } + + var previousPage: UIView? { + + if currentIndex > 0 { + return pageViews[currentIndex - 1] + } + + return nil + } + + public func jump(to index: Int, animated: Bool) { + update(index) + self.setContentOffset(CGPoint(x: self.frame.width * CGFloat(currentIndex), y: 0), animated: animated) + } +} diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/SwipeMenuView.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/SwipeMenuView.swift new file mode 100644 index 0000000..bfa4b19 --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/SwipeMenuView.swift @@ -0,0 +1,473 @@ +import UIKit + +// MARK: - SwipeMenuViewOptions +public struct SwipeMenuViewOptions { + + public struct TabView { + + public enum Style { + case flexible + case segmented + // TODO: case infinity + } + + public enum Addition { + case underline + case circle + case none + } + + public struct ItemView { + /// ItemView width. Defaults to `100.0`. + public var width: CGFloat = 100.0 + + /// ItemView side margin. Defaults to `5.0`. + public var margin: CGFloat = 5.0 + + /// ItemView font. Defaults to `14 pt as bold SystemFont`. + public var font: UIFont = UIFont.boldSystemFont(ofSize: 14) + + /// ItemView clipsToBounds. Defaults to `true`. + public var clipsToBounds: Bool = true + + /// ItemView textColor. Defaults to `.lightGray`. + public var textColor: UIColor = UIColor(red: 170 / 255, green: 170 / 255, blue: 170 / 255, alpha: 1.0) + + /// ItemView selected textColor. Defaults to `.black`. + public var selectedTextColor: UIColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0) + } + + public struct AdditionView { + + public struct Underline { + /// Underline height if addition style select `.underline`. Defaults to `2.0`. + public var height: CGFloat = 2.0 + } + + public struct Circle { + /// Circle cornerRadius if addition style select `.circle`. Defaults to `nil`. + /// `AdditionView.height / 2` in the case of nil. + public var cornerRadius: CGFloat? = nil + + /// Circle maskedCorners if addition style select `.circle`. Defaults to `nil`. + /// It helps to make specific corners rounded. + public var maskedCorners: CACornerMask? = nil + } + + /// AdditionView side margin. Defaults to `0.0`. + @available(*, deprecated, message: "Use `SwipeMenuViewOptions.TabView.AdditionView.padding` instead.") + public var margin: CGFloat = 0.0 + + /// AdditionView paddings. Defaults to `.zero`. + public var padding: UIEdgeInsets = .zero + + /// AdditionView backgroundColor. Defaults to `.black`. + public var backgroundColor: UIColor = .black + + /// AdditionView animating duration. Defaults to `0.3`. + public var animationDuration: Double = 0.3 + + /// AdditionView swipe animation disable feature. Defaults to 'true' + public var isAnimationOnSwipeEnable: Bool = true + + /// Underline style options. + public var underline = Underline() + + /// Circle style options. + public var circle = Circle() + } + + /// TabView height. Defaults to `44.0`. + public var height: CGFloat = 44.0 + + /// TabView side margin. Defaults to `0.0`. + public var margin: CGFloat = 0.0 + + /// TabView background color. Defaults to `.clear`. + public var backgroundColor: UIColor = .clear + + /// TabView clipsToBounds. Defaults to `true`. + public var clipsToBounds: Bool = true + + /// TabView style. Defaults to `.flexible`. Style type has [`.flexible` , `.segmented`]. + public var style: Style = .flexible + + /// TabView addition. Defaults to `.underline`. Addition type has [`.underline`, `.circle`, `.none`]. + public var addition: Addition = .underline + + /// TabView adjust width or not. Defaults to `true`. + public var needsAdjustItemViewWidth: Bool = true + + /// Convert the text color of ItemView to selected text color by scroll rate of ContentScrollView. Defaults to `true`. + public var needsConvertTextColorRatio: Bool = true + + /// TabView enable safeAreaLayout. Defaults to `true`. + public var isSafeAreaEnabled: Bool = true + + /// ItemView options + public var itemView = ItemView() + + /// AdditionView options + public var additionView = AdditionView() + + public init() { } + } + + public struct ContentScrollView { + + /// ContentScrollView backgroundColor. Defaults to `.clear`. + public var backgroundColor: UIColor = .clear + + /// ContentScrollView clipsToBounds. Defaults to `true`. + public var clipsToBounds: Bool = true + + /// ContentScrollView scroll enabled. Defaults to `true`. + public var isScrollEnabled: Bool = true + + /// ContentScrollView enable safeAreaLayout. Defaults to `true`. + public var isSafeAreaEnabled: Bool = true + } + + /// TabView and ContentScrollView Enable safeAreaLayout. Defaults to `true`. + public var isSafeAreaEnabled: Bool = true { + didSet { + tabView.isSafeAreaEnabled = isSafeAreaEnabled + contentScrollView.isSafeAreaEnabled = isSafeAreaEnabled + } + } + + /// TabView options + public var tabView = TabView() + + /// ContentScrollView options + public var contentScrollView = ContentScrollView() + + public init() { } +} + +// MARK: - SwipeMenuViewDelegate + +public protocol SwipeMenuViewDelegate: class { + + /// Called before setup self. + func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewWillSetupAt currentIndex: Int) + + /// Called after setup self. + func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewDidSetupAt currentIndex: Int) + + /// Called before swiping the page. + func swipeMenuView(_ swipeMenuView: SwipeMenuView, willChangeIndexFrom fromIndex: Int, to toIndex: Int) + + /// Called after swiping the page. + func swipeMenuView(_ swipeMenuView: SwipeMenuView, didChangeIndexFrom fromIndex: Int, to toIndex: Int) +} + +extension SwipeMenuViewDelegate { + public func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewWillSetupAt currentIndex: Int) { } + public func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewDidSetupAt currentIndex: Int) { } + public func swipeMenuView(_ swipeMenuView: SwipeMenuView, willChangeIndexFrom fromIndex: Int, to toIndex: Int) { } + public func swipeMenuView(_ swipeMenuView: SwipeMenuView, didChangeIndexFrom fromIndex: Int, to toIndex: Int) { } +} + +// MARK: - SwipeMenuViewDataSource + +public protocol SwipeMenuViewDataSource: class { + + /// Return the number of pages in `SwipeMenuView`. + func numberOfPages(in swipeMenuView: SwipeMenuView) -> Int + + /// Return strings to be displayed at the tab in `SwipeMenuView`. + func swipeMenuView(_ swipeMenuView: SwipeMenuView, titleForPageAt index: Int) -> String + + /// Return a ViewController to be displayed at the page in `SwipeMenuView`. + func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewControllerForPageAt index: Int) -> UIViewController +} + +// MARK: - SwipeMenuView + +open class SwipeMenuView: UIView { + + /// An object conforms `SwipeMenuViewDelegate`. Provide views to populate the `SwipeMenuView`. + open weak var delegate: SwipeMenuViewDelegate? + + /// An object conforms `SwipeMenuViewDataSource`. Provide views and respond to `SwipeMenuView` events. + open weak var dataSource: SwipeMenuViewDataSource? + + open fileprivate(set) var tabView: TabView? { + didSet { + guard let tabView = tabView else { return } + tabView.dataSource = self + tabView.tabViewDelegate = self + addSubview(tabView) + layout(tabView: tabView) + } + } + + open fileprivate(set) var contentScrollView: ContentScrollView? { + didSet { + guard let contentScrollView = contentScrollView else { return } + contentScrollView.delegate = self + contentScrollView.dataSource = self + addSubview(contentScrollView) + layout(contentScrollView: contentScrollView) + } + } + + public var options: SwipeMenuViewOptions + + fileprivate var isLayoutingSubviews: Bool = false + + fileprivate var pageCount: Int { + return dataSource?.numberOfPages(in: self) ?? 0 + } + + fileprivate var isJumping: Bool = false + fileprivate var isPortrait: Bool = true + + /// The index of the front page in `SwipeMenuView` (read only). + open private(set) var currentIndex: Int = 0 + private var jumpingToIndex: Int? + + public init(frame: CGRect, options: SwipeMenuViewOptions? = nil) { + + if let options = options { + self.options = options + } else { + self.options = .init() + } + + super.init(frame: frame) + } + + public required init?(coder aDecoder: NSCoder) { + + self.options = .init() + + super.init(coder: aDecoder) + } + + open override func layoutSubviews() { + + isLayoutingSubviews = true + super.layoutSubviews() + if !isJumping { + reloadData(isOrientationChange: true) + } + } + + open override func didMoveToSuperview() { + super.didMoveToSuperview() + + setup() + } + + /// Reloads all `SwipeMenuView` item views with the dataSource and refreshes the display. + public func reloadData(options: SwipeMenuViewOptions? = nil, default defaultIndex: Int? = nil, isOrientationChange: Bool = false) { + + if let options = options { + self.options = options + } + + isLayoutingSubviews = isOrientationChange + + if !isLayoutingSubviews { + reset() + setup(default: defaultIndex ?? currentIndex) + } + + jump(to: defaultIndex ?? currentIndex, animated: false) + + isLayoutingSubviews = false + } + + /// Jump to the selected page. + public func jump(to index: Int, animated: Bool) { + guard let tabView = tabView, let contentScrollView = contentScrollView else { return } + if currentIndex != index { + delegate?.swipeMenuView(self, willChangeIndexFrom: currentIndex, to: index) + } + jumpingToIndex = index + + tabView.jump(to: index) + contentScrollView.jump(to: index, animated: animated) + } + + /// Notify changing orientaion to `SwipeMenuView` before it. + public func willChangeOrientation() { + isLayoutingSubviews = true + setNeedsLayout() + } + + fileprivate func update(from fromIndex: Int, to toIndex: Int) { + + if !isLayoutingSubviews { + delegate?.swipeMenuView(self, willChangeIndexFrom: fromIndex, to: toIndex) + } + + tabView?.update(toIndex) + contentScrollView?.update(toIndex) + if !isJumping { + // delay setting currentIndex until end scroll when jumping + currentIndex = toIndex + } + + if !isJumping && !isLayoutingSubviews { + delegate?.swipeMenuView(self, didChangeIndexFrom: fromIndex, to: toIndex) + } + } + + // MARK: - Setup + private func setup(default defaultIndex: Int = 0) { + + delegate?.swipeMenuView(self, viewWillSetupAt: defaultIndex) + + backgroundColor = .clear + + tabView = TabView(frame: CGRect(x: 0, y: 0, width: frame.width, height: options.tabView.height), options: options.tabView) + tabView?.clipsToBounds = options.tabView.clipsToBounds + + contentScrollView = ContentScrollView(frame: CGRect(x: 0, y: options.tabView.height, width: frame.width, height: frame.height - options.tabView.height), default: defaultIndex, options: options.contentScrollView) + contentScrollView?.clipsToBounds = options.contentScrollView.clipsToBounds + + tabView?.update(defaultIndex) + contentScrollView?.update(defaultIndex) + currentIndex = defaultIndex + + delegate?.swipeMenuView(self, viewDidSetupAt: defaultIndex) + } + + private func layout(tabView: TabView) { + + tabView.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + tabView.topAnchor.constraint(equalTo: self.topAnchor), + tabView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + tabView.trailingAnchor.constraint(equalTo: self.trailingAnchor), + tabView.heightAnchor.constraint(equalToConstant: options.tabView.height) + ]) + } + + private func layout(contentScrollView: ContentScrollView) { + + contentScrollView.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + contentScrollView.topAnchor.constraint(equalTo: self.topAnchor, constant: options.tabView.height), + contentScrollView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + contentScrollView.trailingAnchor.constraint(equalTo: self.trailingAnchor), + contentScrollView.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ]) + } + + private func reset() { + + if !isLayoutingSubviews { + currentIndex = 0 + } + + if let tabView = tabView, let contentScrollView = contentScrollView { + tabView.removeFromSuperview() + contentScrollView.removeFromSuperview() + tabView.reset() + contentScrollView.reset() + } + } +} + +// MARK: - TabViewDelegate, TabViewDataSource + +extension SwipeMenuView: TabViewDelegate, TabViewDataSource { + + public func tabView(_ tabView: TabView, didSelectTabAt index: Int) { + + guard let contentScrollView = contentScrollView, + currentIndex != index else { return } + + isJumping = true + jumpingToIndex = index + + contentScrollView.jump(to: index, animated: true) + + update(from: currentIndex, to: index) + } + + public func numberOfItems(in menuView: TabView) -> Int { + return dataSource?.numberOfPages(in: self) ?? 0 + } + + public func tabView(_ tabView: TabView, titleForItemAt index: Int) -> String? { + return dataSource?.swipeMenuView(self, titleForPageAt: index) + } +} + +// MARK: - UIScrollViewDelegate + +extension SwipeMenuView: UIScrollViewDelegate { + + public func scrollViewDidScroll(_ scrollView: UIScrollView) { + + if isJumping || isLayoutingSubviews { return } + + // update currentIndex + if scrollView.contentOffset.x >= frame.width * CGFloat(currentIndex + 1) { + update(from: currentIndex, to: currentIndex + 1) + } else if scrollView.contentOffset.x <= frame.width * CGFloat(currentIndex - 1) { + update(from: currentIndex, to: currentIndex - 1) + } + + updateTabViewAddition(by: scrollView) + } + + public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { + + if isJumping || isLayoutingSubviews { + if let toIndex = jumpingToIndex { + delegate?.swipeMenuView(self, didChangeIndexFrom: currentIndex, to: toIndex) + currentIndex = toIndex + jumpingToIndex = nil + } + isJumping = false + isLayoutingSubviews = false + return + } + + updateTabViewAddition(by: scrollView) + } + + /// update addition in tab view + private func updateTabViewAddition(by scrollView: UIScrollView) { + moveAdditionView(scrollView: scrollView) + } + + /// update underbar position + private func moveAdditionView(scrollView: UIScrollView) { + + if let tabView = tabView, let contentScrollView = contentScrollView { + + let ratio = scrollView.contentOffset.x.truncatingRemainder(dividingBy: contentScrollView.frame.width) / contentScrollView.frame.width + + switch scrollView.contentOffset.x { + case let offset where offset >= frame.width * CGFloat(currentIndex): + tabView.moveAdditionView(index: currentIndex, ratio: ratio, direction: .forward) + case let offset where offset < frame.width * CGFloat(currentIndex): + tabView.moveAdditionView(index: currentIndex, ratio: ratio, direction: .reverse) + default: + break + } + } + } +} + +// MARK: - ContentScrollViewDataSource + +extension SwipeMenuView: ContentScrollViewDataSource { + + public func numberOfPages(in contentScrollView: ContentScrollView) -> Int { + return dataSource?.numberOfPages(in: self) ?? 0 + } + + public func contentScrollView(_ contentScrollView: ContentScrollView, viewForPageAt index: Int) -> UIView? { + return dataSource?.swipeMenuView(self, viewControllerForPageAt: index).view + } +} diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/SwipeMenuViewController.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/SwipeMenuViewController.swift new file mode 100644 index 0000000..d58101c --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/SwipeMenuViewController.swift @@ -0,0 +1,68 @@ +import UIKit + +open class SwipeMenuViewController: UIViewController, SwipeMenuViewDelegate, SwipeMenuViewDataSource { + + open var swipeMenuView: SwipeMenuView! + + open override func viewDidLoad() { + super.viewDidLoad() + + swipeMenuView = SwipeMenuView(frame: view.frame) + swipeMenuView.delegate = self + swipeMenuView.dataSource = self + view.addSubview(swipeMenuView) + } + + open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + + swipeMenuView.willChangeOrientation() + } + + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + addSwipeMenuViewConstraints() + } + + private func addSwipeMenuViewConstraints() { + + swipeMenuView.translatesAutoresizingMaskIntoConstraints = false + if #available(iOS 11.0, *), view.hasSafeAreaInsets, swipeMenuView.options.tabView.isSafeAreaEnabled { + NSLayoutConstraint.activate([ + swipeMenuView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + swipeMenuView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + swipeMenuView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + swipeMenuView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } else { + NSLayoutConstraint.activate([ + swipeMenuView.topAnchor.constraint(equalTo: topLayoutGuide.topAnchor), + swipeMenuView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + swipeMenuView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + swipeMenuView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } + } + + // MARK: - SwipeMenuViewDelegate + open func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewWillSetupAt currentIndex: Int) { } + open func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewDidSetupAt currentIndex: Int) { } + open func swipeMenuView(_ swipeMenuView: SwipeMenuView, willChangeIndexFrom fromIndex: Int, to toIndex: Int) { } + open func swipeMenuView(_ swipeMenuView: SwipeMenuView, didChangeIndexFrom fromIndex: Int, to toIndex: Int) { } + + // MARK: - SwipeMenuViewDataSource + + open func numberOfPages(in swipeMenuView: SwipeMenuView) -> Int { + return children.count + } + + open func swipeMenuView(_ swipeMenuView: SwipeMenuView, titleForPageAt index: Int) -> String { + return children[index].title ?? "" + } + + open func swipeMenuView(_ swipeMenuView: SwipeMenuView, viewControllerForPageAt index: Int) -> UIViewController { + let vc = children[index] + vc.didMove(toParent: self) + return vc + } +} diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/TabItemView.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/TabItemView.swift new file mode 100644 index 0000000..4b7d1ff --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/TabItemView.swift @@ -0,0 +1,54 @@ +import UIKit + +final class TabItemView: UIView { + + private(set) var titleLabel: UILabel = UILabel() + + public var textColor: UIColor = UIColor(red: 140/255, green: 140/255, blue: 140/255, alpha: 1.0) + public var selectedTextColor: UIColor = .white + + public var isSelected: Bool = false { + didSet { + if isSelected { + titleLabel.textColor = selectedTextColor + } else { + titleLabel.textColor = textColor + } + } + } + + public override init(frame: CGRect) { + super.init(frame: frame) + + setupLabel() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override public func layoutSubviews() { + super.layoutSubviews() + } + + private func setupLabel() { + titleLabel = UILabel(frame: bounds) + titleLabel.textAlignment = .center + titleLabel.font = UIFont.boldSystemFont(ofSize: 14) + titleLabel.textColor = UIColor(red: 140/255, green: 140/255, blue: 140/255, alpha: 1.0) + titleLabel.backgroundColor = UIColor.clear + addSubview(titleLabel) + layoutLabel() + } + + private func layoutLabel() { + + titleLabel.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + titleLabel.topAnchor.constraint(equalTo: self.topAnchor), + titleLabel.widthAnchor.constraint(equalTo: self.widthAnchor), + titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + titleLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ]) + } +} diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/TabView.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/TabView.swift new file mode 100644 index 0000000..8b20a6e --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/TabView.swift @@ -0,0 +1,548 @@ +import UIKit + +// MARK: - TabViewDelegate + +public protocol TabViewDelegate: class { + + /// Called before selecting the tab. + func tabView(_ tabView: TabView, willSelectTabAt index: Int) + + /// Called after selecting the tab. + func tabView(_ tabView: TabView, didSelectTabAt index: Int) +} + +extension TabViewDelegate { + public func tabView(_ tabView: TabView, willSelectTabAt index: Int) {} + + public func tabView(_ tabView: TabView, didSelectTabAt index: Int) {} +} + +// MARK: - TabViewDataSource + +public protocol TabViewDataSource: class { + + /// Return the number of Items in `TabView`. + func numberOfItems(in tabView: TabView) -> Int + + /// Return strings to be displayed at the tab in `TabView`. + func tabView(_ tabView: TabView, titleForItemAt index: Int) -> String? +} + +open class TabView: UIScrollView { + + open weak var tabViewDelegate: TabViewDelegate? + open weak var dataSource: TabViewDataSource? + + var itemViews: [TabItemView] = [] + + fileprivate let containerView: UIStackView = UIStackView() + + fileprivate var additionView: UIView = .init() + + fileprivate var currentIndex: Int = 0 + + fileprivate(set) var options: SwipeMenuViewOptions.TabView = SwipeMenuViewOptions.TabView() + + private var leftMarginConstraint: NSLayoutConstraint = .init() + private var widthConstraint: NSLayoutConstraint = .init() + + public init(frame: CGRect, options: SwipeMenuViewOptions.TabView? = nil) { + super.init(frame: frame) + + if let options = options { + self.options = options + } + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open override func didMoveToSuperview() { + reloadData() + } + + open override func layoutSubviews() { + super.layoutSubviews() + resetAdditionViewPosition(index: currentIndex) + } + + @available(iOS 11.0, *) + open override func safeAreaInsetsDidChange() { + super.safeAreaInsetsDidChange() + + leftMarginConstraint.constant = options.margin + safeAreaInsets.left + if options.style == .segmented { + widthConstraint.constant = options.margin * -2 - safeAreaInsets.left - safeAreaInsets.right + } + + layoutIfNeeded() + } + + fileprivate func focus(on target: UIView, animated: Bool = true) { + + if options.style == .segmented { return } + + let offset: CGFloat + let contentWidth: CGFloat + + if #available(iOS 11.0, *), options.isSafeAreaEnabled { + offset = target.center.x + options.margin + safeAreaInsets.left - self.frame.width / 2 + contentWidth = containerView.frame.width + options.margin * 2 + safeAreaInsets.left + safeAreaInsets.right + } else { + offset = target.center.x + options.margin - self.frame.width / 2 + contentWidth = containerView.frame.width + options.margin * 2 + } + + if offset < 0 || self.frame.width > contentWidth { + self.setContentOffset(CGPoint(x: 0, y: 0), animated: animated) + } else if contentWidth - self.frame.width < offset { + self.setContentOffset(CGPoint(x: contentWidth - self.frame.width, y: 0), animated: animated) + } else { + self.setContentOffset(CGPoint(x: offset, y: 0), animated: animated) + } + } + + // MARK: - Setup + + /// Reloads all `TabView` item views with the dataSource and refreshes the display. + public func reloadData(options: SwipeMenuViewOptions.TabView? = nil, + default defaultIndex: Int? = nil, + animated: Bool = true) { + + if let options = options { + self.options = options + } + + reset() + + guard let dataSource = dataSource, + dataSource.numberOfItems(in: self) > 0 else { return } + + setupScrollView() + setupContainerView(dataSource: dataSource) + setupTabItemViews(dataSource: dataSource) + setupAdditionView() + + if let defaultIndex = defaultIndex { + moveTabItem(index: defaultIndex, animated: animated) + } + } + + func reset() { + currentIndex = 0 + itemViews.forEach { $0.removeFromSuperview() } + additionView.removeFromSuperview() + containerView.removeFromSuperview() + itemViews = [] + } + + func update(_ index: Int) { + + if currentIndex == index { return } + + currentIndex = index + updateSelectedItem(by: currentIndex) + } + + fileprivate func setupScrollView() { + backgroundColor = options.backgroundColor + showsHorizontalScrollIndicator = false + showsVerticalScrollIndicator = false + isScrollEnabled = true + isDirectionalLockEnabled = true + alwaysBounceHorizontal = false + scrollsToTop = false + bouncesZoom = false + translatesAutoresizingMaskIntoConstraints = false + } + + fileprivate func setupContainerView(dataSource: TabViewDataSource) { + + containerView.alignment = .leading + + switch options.style { + case .flexible: + containerView.distribution = .fill + case .segmented: + containerView.distribution = .fillEqually + } + + let itemCount = dataSource.numberOfItems(in: self) + var containerHeight: CGFloat = 0.0 + + switch options.addition { + case .underline: + containerHeight = frame.height - options.additionView.underline.height - options.additionView.padding.bottom + case .none, .circle: + containerHeight = frame.height + } + + switch options.style { + case .flexible: + let containerWidth = options.itemView.width * CGFloat(itemCount) + if #available(iOS 11.0, *), options.isSafeAreaEnabled { + contentSize = CGSize(width: containerWidth + options.margin * 2 + safeAreaInsets.left + safeAreaInsets.right, height: options.height) + containerView.frame = CGRect(x: 0, y: options.margin + safeAreaInsets.left, width: containerWidth, height: containerHeight) + } else { + contentSize = CGSize(width: containerWidth + options.margin * 2, height: options.height) + containerView.frame = CGRect(x: 0, y: options.margin, width: containerWidth, height: containerHeight) + } + case .segmented: + if #available(iOS 11.0, *), options.isSafeAreaEnabled { + contentSize = CGSize(width: frame.width, height: options.height) + containerView .frame = CGRect(x: 0, y: options.margin + safeAreaInsets.left, width: frame.width - options.margin * 2 - safeAreaInsets.left - safeAreaInsets.right, height: containerHeight) + } else { + contentSize = CGSize(width: frame.width, height: options.height) + containerView .frame = CGRect(x: 0, y: options.margin, width: frame.width - options.margin * 2, height: containerHeight) + } + } + + containerView.backgroundColor = .clear + addSubview(containerView) + } + + fileprivate func setupTabItemViews(dataSource: TabViewDataSource) { + + itemViews = [] + + let itemCount = dataSource.numberOfItems(in: self) + + var xPosition: CGFloat = 0 + + for index in 0.. 0 else { return } + let adjustCellWidth: CGFloat + if #available(iOS 11.0, *), options.isSafeAreaEnabled && safeAreaInsets != .zero { + adjustCellWidth = (frame.width - options.margin * 2 - safeAreaInsets.left - safeAreaInsets.right) / CGFloat(dataSource.numberOfItems(in: self)) - options.additionView.padding.horizontal + } else { + adjustCellWidth = (frame.width - options.margin * 2) / CGFloat(dataSource.numberOfItems(in: self)) - options.additionView.padding.horizontal + } + + additionView.frame.origin.x = adjustCellWidth * CGFloat(index) - options.additionView.padding.left + additionView.frame.size.width = adjustCellWidth + } + + fileprivate func animateAdditionView(index: Int, animated: Bool, completion: ((Bool) -> Swift.Void)? = nil) { + + update(index) + + if animated { + UIView.animate(withDuration: options.additionView.animationDuration, animations: { + self.updateAdditionViewPosition(index: index) + }, completion: completion) + } else { + updateAdditionViewPosition(index: index) + } + } + + func moveAdditionView(index: Int, ratio: CGFloat, direction: Direction) { + + update(index) + + guard let currentItem = currentItem else { return } + + if options.additionView.isAnimationOnSwipeEnable { + switch direction { + case .forward: + additionView.frame.origin.x = currentItem.frame.origin.x + (nextItem.frame.origin.x - currentItem.frame.origin.x) * ratio + options.additionView.padding.left + additionView.frame.size.width = currentItem.frame.size.width + (nextItem.frame.size.width - currentItem.frame.size.width) * ratio - options.additionView.padding.horizontal + if options.needsConvertTextColorRatio { + nextItem.titleLabel.textColor = options.itemView.textColor.convert(to: options.itemView.selectedTextColor, multiplier: ratio) + currentItem.titleLabel.textColor = options.itemView.selectedTextColor.convert(to: options.itemView.textColor, multiplier: ratio) + } + case .reverse: + additionView.frame.origin.x = previousItem.frame.origin.x + (currentItem.frame.origin.x - previousItem.frame.origin.x) * ratio + options.additionView.padding.left + additionView.frame.size.width = previousItem.frame.size.width + (currentItem.frame.size.width - previousItem.frame.size.width) * ratio - options.additionView.padding.horizontal + if options.needsConvertTextColorRatio { + previousItem.titleLabel.textColor = options.itemView.selectedTextColor.convert(to: options.itemView.textColor, multiplier: ratio) + currentItem.titleLabel.textColor = options.itemView.textColor.convert(to: options.itemView.selectedTextColor, multiplier: ratio) + } + } + } else { + moveTabItem(index: index, animated: true) + } + + if options.itemView.selectedTextColor.convert(to: options.itemView.textColor, multiplier: ratio) == nil { + updateSelectedItem(by: currentIndex) + } + + focus(on: additionView, animated: false) + } +} + +extension TabView { + var currentItem: TabItemView? { + return currentIndex < itemViews.count ? itemViews[currentIndex] : nil + } + + var nextItem: TabItemView { + if currentIndex < itemViews.count - 1 { + return itemViews[currentIndex + 1] + } + return itemViews[currentIndex] + } + + var previousItem: TabItemView { + if currentIndex > 0 { + return itemViews[currentIndex - 1] + } + return itemViews[currentIndex] + } + + func jump(to index: Int) { + update(index) + + guard let currentItem = currentItem else { return } + + if options.addition == .underline { + additionView.frame.origin.x = currentItem.frame.origin.x + options.additionView.padding.left + additionView.frame.size.width = currentItem.frame.size.width - options.additionView.padding.horizontal + } + + focus(on: currentItem, animated: false) + } +} + +// MARK: - GestureRecognizer + +extension TabView { + + fileprivate var tapGestureRecognizer: UITapGestureRecognizer { + let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapItemView(_:))) + gestureRecognizer.numberOfTapsRequired = 1 + gestureRecognizer.cancelsTouchesInView = false + return gestureRecognizer + } + + fileprivate func addTabItemGestures() { + itemViews.forEach { + $0.addGestureRecognizer(tapGestureRecognizer) + } + } + + @objc func tapItemView(_ recognizer: UITapGestureRecognizer) { + guard let itemView = recognizer.view as? TabItemView, + let index: Int = itemViews.firstIndex(of: itemView), + currentIndex != index else { return } + tabViewDelegate?.tabView(self, willSelectTabAt: index) + moveTabItem(index: index, animated: true) + update(index) + tabViewDelegate?.tabView(self, didSelectTabAt: index) + } + + private func moveTabItem(index: Int, animated: Bool) { + + switch options.addition { + case .underline, .circle: + animateAdditionView(index: index, animated: animated, completion: nil) + case .none: + update(index) + } + } +} + diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIColorExtension.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIColorExtension.swift new file mode 100644 index 0000000..cb8bb52 --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIColorExtension.swift @@ -0,0 +1,24 @@ +import UIKit + +extension UIColor { + + func convert(to color: UIColor, multiplier _multiplier: CGFloat) -> UIColor? { + let multiplier = min(max(_multiplier, 0), 1) + + let components = cgColor.components ?? [] + let toComponents = color.cgColor.components ?? [] + + if components.isEmpty || components.count < 3 || toComponents.isEmpty || toComponents.count < 3 { + return nil + } + + var results: [CGFloat] = [] + + for index in 0...3 { + let result = (toComponents[index] - components[index]) * abs(multiplier) + components[index] + results.append(result) + } + + return UIColor(red: results[0], green: results[1], blue: results[2], alpha: results[3]) + } +} diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIEdgeInsetsExtension.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIEdgeInsetsExtension.swift new file mode 100644 index 0000000..f4852a0 --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIEdgeInsetsExtension.swift @@ -0,0 +1,16 @@ +import UIKit + +extension UIEdgeInsets { + + init(horizontal: CGFloat, vertical: CGFloat) { + self.init(top: vertical, left: horizontal, bottom: vertical, right: horizontal) + } + + var horizontal: CGFloat { + return left + right + } + + var vertical: CGFloat { + return top + bottom + } +} diff --git a/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIViewExtension.swift b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIViewExtension.swift new file mode 100644 index 0000000..7a5f789 --- /dev/null +++ b/frontend/mobile/Pods/SwipeMenuViewController/Sources/Classes/UIViewExtension.swift @@ -0,0 +1,9 @@ +import UIKit + +extension UIView { + + var hasSafeAreaInsets: Bool { + guard #available (iOS 11, *) else { return false } + return safeAreaInsets != .zero + } +} diff --git a/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-Info.plist b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-Info.plist new file mode 100644 index 0000000..e92eb78 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 6.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-dummy.m b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-dummy.m new file mode 100644 index 0000000..dfbce32 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_BonsaiController : NSObject +@end +@implementation PodsDummy_BonsaiController +@end diff --git a/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-prefix.pch b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-umbrella.h b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-umbrella.h new file mode 100644 index 0000000..5e4ac03 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double BonsaiControllerVersionNumber; +FOUNDATION_EXPORT const unsigned char BonsaiControllerVersionString[]; + diff --git a/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.debug.xcconfig b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.debug.xcconfig new file mode 100644 index 0000000..d055999 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.debug.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/BonsaiController +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.modulemap b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.modulemap new file mode 100644 index 0000000..5e746ef --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.modulemap @@ -0,0 +1,6 @@ +framework module BonsaiController { + umbrella header "BonsaiController-umbrella.h" + + export * + module * { export * } +} diff --git a/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.release.xcconfig b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.release.xcconfig new file mode 100644 index 0000000..d055999 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/BonsaiController/BonsaiController.release.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/BonsaiController +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-Info.plist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.markdown b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.markdown new file mode 100644 index 0000000..c284111 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.markdown @@ -0,0 +1,50 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## BonsaiController + +Copyright (c) 2018 rishi420 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## SwipeMenuViewController + +The MIT License (MIT) + +Copyright 2017 Yusuke Morishita + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.plist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.plist new file mode 100644 index 0000000..5265651 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-acknowledgements.plist @@ -0,0 +1,88 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2018 rishi420 <rishi420@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + BonsaiController + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright 2017 Yusuke Morishita + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + License + MIT + Title + SwipeMenuViewController + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-dummy.m b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-dummy.m new file mode 100644 index 0000000..4b63bb5 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_CommunityMC3_CommunityMC3UITests : NSObject +@end +@implementation PodsDummy_Pods_CommunityMC3_CommunityMC3UITests +@end diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Debug-input-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..7bfbd24 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh +${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework +${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Debug-output-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..aa027e1 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BonsaiController.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Release-input-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..7bfbd24 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh +${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework +${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Release-output-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..aa027e1 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BonsaiController.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh new file mode 100755 index 0000000..0a068ba --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-frameworks.sh @@ -0,0 +1,209 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + +install_artifact() { + artifact="$1" + base="$(basename "$artifact")" + case $base in + *.framework) + install_framework "$artifact" + ;; + *.dSYM) + # Suppress arch warnings since XCFrameworks will include many dSYM files + install_dsym "$artifact" "false" + ;; + *.bcsymbolmap) + install_bcsymbolmap "$artifact" + ;; + *) + echo "error: Unrecognized artifact "$artifact"" + ;; + esac +} + +copy_artifacts() { + file_list="$1" + while read artifact; do + install_artifact "$artifact" + done <$file_list +} + +ARTIFACT_LIST_FILE="${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt" +if [ -r "${ARTIFACT_LIST_FILE}" ]; then + copy_artifacts "${ARTIFACT_LIST_FILE}" +fi + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-umbrella.h b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-umbrella.h new file mode 100644 index 0000000..e83c429 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_CommunityMC3_CommunityMC3UITestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_CommunityMC3_CommunityMC3UITestsVersionString[]; + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig new file mode 100644 index 0000000..8eec38a --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.debug.xcconfig @@ -0,0 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" -framework "SwipeMenuViewController" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.modulemap b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.modulemap new file mode 100644 index 0000000..761afb7 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_CommunityMC3_CommunityMC3UITests { + umbrella header "Pods-CommunityMC3-CommunityMC3UITests-umbrella.h" + + export * + module * { export * } +} diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig new file mode 100644 index 0000000..8eec38a --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3-CommunityMC3UITests/Pods-CommunityMC3-CommunityMC3UITests.release.xcconfig @@ -0,0 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" -framework "SwipeMenuViewController" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-Info.plist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-acknowledgements.markdown b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-acknowledgements.markdown new file mode 100644 index 0000000..c284111 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-acknowledgements.markdown @@ -0,0 +1,50 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## BonsaiController + +Copyright (c) 2018 rishi420 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## SwipeMenuViewController + +The MIT License (MIT) + +Copyright 2017 Yusuke Morishita + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-acknowledgements.plist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-acknowledgements.plist new file mode 100644 index 0000000..5265651 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-acknowledgements.plist @@ -0,0 +1,88 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2018 rishi420 <rishi420@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + BonsaiController + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright 2017 Yusuke Morishita + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + License + MIT + Title + SwipeMenuViewController + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-dummy.m b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-dummy.m new file mode 100644 index 0000000..a519737 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_CommunityMC3 : NSObject +@end +@implementation PodsDummy_Pods_CommunityMC3 +@end diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Debug-input-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..fb46261 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks.sh +${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework +${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Debug-output-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..aa027e1 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BonsaiController.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Release-input-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..fb46261 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks.sh +${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework +${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Release-output-files.xcfilelist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..aa027e1 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BonsaiController.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwipeMenuViewController.framework \ No newline at end of file diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks.sh b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks.sh new file mode 100755 index 0000000..0a068ba --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-frameworks.sh @@ -0,0 +1,209 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + +install_artifact() { + artifact="$1" + base="$(basename "$artifact")" + case $base in + *.framework) + install_framework "$artifact" + ;; + *.dSYM) + # Suppress arch warnings since XCFrameworks will include many dSYM files + install_dsym "$artifact" "false" + ;; + *.bcsymbolmap) + install_bcsymbolmap "$artifact" + ;; + *) + echo "error: Unrecognized artifact "$artifact"" + ;; + esac +} + +copy_artifacts() { + file_list="$1" + while read artifact; do + install_artifact "$artifact" + done <$file_list +} + +ARTIFACT_LIST_FILE="${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt" +if [ -r "${ARTIFACT_LIST_FILE}" ]; then + copy_artifacts "${ARTIFACT_LIST_FILE}" +fi + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-umbrella.h b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-umbrella.h new file mode 100644 index 0000000..404110f --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_CommunityMC3VersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_CommunityMC3VersionString[]; + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.debug.xcconfig b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.debug.xcconfig new file mode 100644 index 0000000..8eec38a --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.debug.xcconfig @@ -0,0 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" -framework "SwipeMenuViewController" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.modulemap b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.modulemap new file mode 100644 index 0000000..280f897 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.modulemap @@ -0,0 +1,6 @@ +framework module Pods_CommunityMC3 { + umbrella header "Pods-CommunityMC3-umbrella.h" + + export * + module * { export * } +} diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.release.xcconfig b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.release.xcconfig new file mode 100644 index 0000000..8eec38a --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3/Pods-CommunityMC3.release.xcconfig @@ -0,0 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" -framework "SwipeMenuViewController" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-Info.plist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-acknowledgements.markdown b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-acknowledgements.markdown new file mode 100644 index 0000000..102af75 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-acknowledgements.markdown @@ -0,0 +1,3 @@ +# Acknowledgements +This application makes use of the following third party libraries: +Generated by CocoaPods - https://cocoapods.org diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-acknowledgements.plist b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-acknowledgements.plist new file mode 100644 index 0000000..7acbad1 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-acknowledgements.plist @@ -0,0 +1,29 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-dummy.m b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-dummy.m new file mode 100644 index 0000000..903385e --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_CommunityMC3Tests : NSObject +@end +@implementation PodsDummy_Pods_CommunityMC3Tests +@end diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-umbrella.h b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-umbrella.h new file mode 100644 index 0000000..f3965ae --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_CommunityMC3TestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_CommunityMC3TestsVersionString[]; + diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.debug.xcconfig b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.debug.xcconfig new file mode 100644 index 0000000..d1ca990 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.debug.xcconfig @@ -0,0 +1,9 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" -framework "SwipeMenuViewController" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.modulemap b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.modulemap new file mode 100644 index 0000000..ab47662 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_CommunityMC3Tests { + umbrella header "Pods-CommunityMC3Tests-umbrella.h" + + export * + module * { export * } +} diff --git a/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.release.xcconfig b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.release.xcconfig new file mode 100644 index 0000000..d1ca990 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/Pods-CommunityMC3Tests/Pods-CommunityMC3Tests.release.xcconfig @@ -0,0 +1,9 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController/SwipeMenuViewController.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" -framework "SwipeMenuViewController" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-Info.plist b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-Info.plist new file mode 100644 index 0000000..c26f36f --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 4.1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-dummy.m b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-dummy.m new file mode 100644 index 0000000..4e4f5bb --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwipeMenuViewController : NSObject +@end +@implementation PodsDummy_SwipeMenuViewController +@end diff --git a/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-prefix.pch b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-umbrella.h b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-umbrella.h new file mode 100644 index 0000000..8c5da9d --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double SwipeMenuViewControllerVersionNumber; +FOUNDATION_EXPORT const unsigned char SwipeMenuViewControllerVersionString[]; + diff --git a/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.debug.xcconfig b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.debug.xcconfig new file mode 100644 index 0000000..ed84cfc --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.debug.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwipeMenuViewController +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.modulemap b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.modulemap new file mode 100644 index 0000000..66c8d9c --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.modulemap @@ -0,0 +1,6 @@ +framework module SwipeMenuViewController { + umbrella header "SwipeMenuViewController-umbrella.h" + + export * + module * { export * } +} diff --git a/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.release.xcconfig b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.release.xcconfig new file mode 100644 index 0000000..ed84cfc --- /dev/null +++ b/frontend/mobile/Pods/Target Support Files/SwipeMenuViewController/SwipeMenuViewController.release.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwipeMenuViewController +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwipeMenuViewController +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES