Просмотр исходного кода

Merge branch 'BaseProject' into Location

Iñigo Valentin 9 лет назад
Родитель
Сommit
679181d986
54 измененных файлов с 3267 добавлено и 718 удалено
  1. 26 0
      MenuCollectionViewCell.swift
  2. 11 11
      README.es-ES.md
  3. 10 11
      README.es-EU.md
  4. 10 12
      README.md
  5. 30 1
      app.xcodeproj/project.pbxproj
  6. 7 32
      app/ActivitiesView.swift
  7. 3 3
      app/ActivitiesView.xib
  8. 58 12
      app/AlbumViewController.swift
  9. 41 0
      app/AppDelegate.swift
  10. 463 4
      app/Base.lproj/Main.storyboard
  11. 8 32
      app/BlogView.swift
  12. 0 1
      app/FetchLocation.swift
  13. 309 0
      app/FutureActivityViewController.swift
  14. 1 3
      app/GalleryView.swift
  15. 3 3
      app/GalleryView.xib
  16. 271 64
      app/HomeView.swift
  17. 202 11
      app/HomeView.xib
  18. 6 2
      app/Info.plist
  19. 0 6
      app/LablancaView.swift
  20. 1 6
      app/LocationView.swift
  21. 223 0
      app/Notifications.swift
  22. 207 0
      app/PastActivityViewController.swift
  23. 289 0
      app/PhotoViewController.swift
  24. 21 24
      app/PostViewController.swift
  25. 31 8
      app/RowAlbum.swift
  26. 16 20
      app/RowBlog.swift
  27. 1 1
      app/RowBlog.xib
  28. 29 15
      app/RowFutureActivity.swift
  29. 19 18
      app/RowFutureActivity.xib
  30. 1 3
      app/RowGallery.swift
  31. 2 2
      app/RowGallery.xib
  32. 24 17
      app/RowHomeBlog.swift
  33. 109 109
      app/RowHomeBlog.xib
  34. 18 9
      app/RowHomeFutureActivities.swift
  35. 109 109
      app/RowHomeFutureActivities.xib
  36. 78 2
      app/RowHomeGallery.swift
  37. 2 2
      app/RowHomeGallery.xib
  38. 20 11
      app/RowHomePastActivities.swift
  39. 10 5
      app/RowHomePastActivities.xib
  40. 1 1
      app/RowHomeSocial.swift
  41. 168 0
      app/RowItinerary.swift
  42. 139 0
      app/RowItinerary.xib
  43. 1 1
      app/RowLabel.swift
  44. 1 1
      app/RowLablancaDay.swift
  45. 1 2
      app/RowLablancaOffer.swift
  46. 9 10
      app/RowPastActivity.swift
  47. 3 3
      app/RowPastActivity.xib
  48. 2 8
      app/RowSchedule.swift
  49. 2 3
      app/ScheduleViewController.swift
  50. 134 65
      app/Sync.swift
  51. 72 5
      app/SyncController.swift
  52. 2 6
      app/UIImageView.swift
  53. 0 1
      app/UIView.swift
  54. 63 43
      app/ViewController.swift

+ 26 - 0
MenuCollectionViewCell.swift

@@ -28,4 +28,30 @@ class MenuCollectionViewCell: UICollectionViewCell {
 	@IBOutlet weak var label: UILabel!
  
 	@IBOutlet weak var bar: UIView!
+	
+	
+	override var isHighlighted: Bool {
+		willSet {
+			onSelected(newValue)
+		}
+	}
+	override var isSelected: Bool {
+		willSet {
+			onSelected(newValue)
+		}
+	}
+	func onSelected(_ newValue: Bool) {
+
+		guard selectedBackgroundView == nil else { return }
+		if newValue == true {
+			self.bar.backgroundColor = UIColor(red: 148/255, green: 209/255, blue: 255/255, alpha: 1)
+			self.label.font = UIFont.boldSystemFont(ofSize: self.label.font.pointSize)
+			self.label.textColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1)
+		}
+		else{
+			self.bar.backgroundColor = UIColor(red: 90/255, green: 180/255, blue: 255/255, alpha: 1)
+			self.label.font = UIFont.systemFont(ofSize: self.label.font.pointSize)
+			self.label.textColor = UIColor(red: 200/255, green: 200/255, blue: 200/255, alpha: 1)
+		}
+	}
 }

+ 11 - 11
README.es-ES.md

@@ -1,6 +1,5 @@
 ---
-[Informazioa euskaraz](README.es-EU.md) 
-[Information in english](README.md)
+[Informazioa euskaraz](README.es-EU.md) - [Information in english](README.md)
 ---
 
 
@@ -12,16 +11,16 @@ Una aplicacion para iOS para miembros de [Gasteizko Margolariak](https://margola
 
 Hay funciones diseñadas especificamente para las Fiestas de La Blanca, y solo estarán disponibles en esas fechas.
 
-* [NO IMPLEMENTADO] Consulta en tu teléfono el Programa de Fiestas, encuentra actos alrededor tuyo ydescubre como llegar hasta ellos.
-* [NO IMPLEMENTADO] Consulta el Programa de Fiestas de Gasteizko Margolariak, detallado y con la ubicación de cada actividad...
-* [NO IMPLEMENTADO] ... pero, como no somos famosos por nuestra puntualidad, comprueba nuestra ubicación en tiempo real.
+* Consulta en tu teléfono el Programa de Fiestas, encuentra actos alrededor tuyo ydescubre como llegar hasta ellos.
+* Consulta el Programa de Fiestas de Gasteizko Margolariak, detallado y con la ubicación de cada actividad...
+* ... pero, como no somos famosos por nuestra puntualidad, comprueba nuestra ubicación en tiempo real.
 
 
 ### Durante el resto del año ###
 
-* [PARCIALMENTE IMPLEMENTADO] Mantente informado de las actividades que organizamos durante el resto del año.
-* [PARCIALMENTE IMPLEMENTADO] Recibe las ultimas noticias sobre la Cuadrilla en nuestro Blog
-* [PARCIALMENTE IMPLEMENTADO] Galería de fotos de todas nuestras actividades.
+* Mantente informado de las actividades que organizamos durante el resto del año.
+* Recibe las ultimas noticias sobre la Cuadrilla en nuestro Blog
+* Galería de fotos de todas nuestras actividades.
 
 
 ### Compatibilidad ###
@@ -31,9 +30,9 @@ iOS 9.1 o superior.
 
 ### Idiomas ###
 
-* [IMPLEMENTADO] Castellano
-* [NO IMPLEMENTADO] Inglés
-* [NO IMPLEMENTADO] Euskera 
+* Castellano
+* [PARCIALMENTE] Inglés
+* [PARCIALMENTE] Euskera 
 
 
 ### Otros dispositivos ###
@@ -41,3 +40,4 @@ iOS 9.1 o superior.
 * ¿Android? [Lo tenemos!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakApp) 
 * ¿Prefieres el sitio web? [No problem!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakWeb)
 
+

+ 10 - 11
README.es-EU.md

@@ -1,6 +1,5 @@
 ---
-[Informacion en castellano](README.es-ES.md) 
-[Information in english](README.md)
+[Informacion en castellano](README.es-ES.md) - [Information in english](README.md)
 ---
 
 
@@ -12,16 +11,16 @@ Una aplicacion para iOS para miembros de [Gasteizko Margolariak](https://margola
 
 Hay funciones diseñadas especificamente para las Fiestas de La Blanca, y solo estarán disponibles en esas fechas.
 
-* [NO IMPLEMENTADO] Consulta en tu teléfono el Programa de Fiestas, encuentra actos alrededor tuyo ydescubre como llegar hasta ellos.
-* [NO IMPLEMENTADO] Consulta el Programa de Fiestas de Gasteizko Margolariak, detallado y con la ubicación de cada actividad...
-* [NO IMPLEMENTADO] ... pero, como no somos famosos por nuestra puntualidad, comprueba nuestra ubicación en tiempo real.
+* Consulta en tu teléfono el Programa de Fiestas, encuentra actos alrededor tuyo ydescubre como llegar hasta ellos.
+* Consulta el Programa de Fiestas de Gasteizko Margolariak, detallado y con la ubicación de cada actividad...
+* ... pero, como no somos famosos por nuestra puntualidad, comprueba nuestra ubicación en tiempo real.
 
 
 ### Durante el resto del año ###
 
-* [PARCIALMENTE IMPLEMENTADO] Mantente informado de las actividades que organizamos durante el resto del año.
-* [PARCIALMENTE IMPLEMENTADO] Recibe las ultimas noticias sobre la Cuadrilla en nuestro Blog
-* [PARCIALMENTE IMPLEMENTADO] Galería de fotos de todas nuestras actividades.
+* Mantente informado de las actividades que organizamos durante el resto del año.
+* Recibe las ultimas noticias sobre la Cuadrilla en nuestro Blog
+* Galería de fotos de todas nuestras actividades.
 
 
 ### Compatibilidad ###
@@ -31,9 +30,9 @@ iOS 9.1 o superior.
 
 ### Idiomas ###
 
-* [IMPLEMENTADO] Castellano
-* [NO IMPLEMENTADO] Inglés
-* [NO IMPLEMENTADO] Euskera 
+* Castellano
+* [PARCIALMENTE] Inglés
+* [PARCIALMENTE] Euskera 
 
 
 ### Otros dispositivos ###

+ 10 - 12
README.md

@@ -1,6 +1,5 @@
 ---
-[Información en castellano](README.es-ES.md) 
-[Informazioa euskaraz](README.es-EU.md)
+[Información en castellano](README.es-ES.md) - [Informazioa euskaraz](README.es-EU.md)
 ---
 
 
@@ -12,17 +11,16 @@ An iOS app intended for members of [Gasteizko Margolariak](https://margolariak.c
 
 This features will be only available during the city festivals.
 
-* [TODO] Check out the festival schedule, discover events all around the city, and get their location.
-* [TODO] Check out the schedule for the members of Gasteizko Margolariak, indicating the location of every event and activity...
-* [TODO] ... but, since we are not known for our puntuality, check out the location of Gasteizko Margolariak in real time.
-* [TODO] Approximate distance to important event around the city.
+* Check out the festival schedule, discover events all around the city, and get their location.
+* Check out the schedule for the members of Gasteizko Margolariak, indicating the location of every event and activity...
+* ... but, since we are not known for our puntuality, check out the location of Gasteizko Margolariak in real time.
 
 
 ### Features for the rest of the year ###
 
-* [PARTIALLY IMPLEMENTED] Check out and be notified of all activities organized by Gasteizko Margolariak.
-* [MOSTLY IMPLEMENTED] Stay updated witho our blog.
-* [MOSTLY IMPLEMENTED] Check out our photo gallery.
+* Check out and be notified of all activities organized by Gasteizko Margolariak.
+* Stay updated witho our blog.
+* Check out our photo gallery.
 
 
 ### Compatibility ###
@@ -32,9 +30,9 @@ iOS 9.1 or higher.
 
 ### Languages ###
 
-* [AVAILABLE] Spanish
-* [TODO] English
-* [TODO] Basque
+* Spanish
+* [PARTIALLY] English
+* [PARTIALLY] Basque
 
 
 ### On other devices ###

+ 30 - 1
app.xcodeproj/project.pbxproj

@@ -68,6 +68,10 @@
 		93BAD2F61E586310009DF853 /* RowHomeSocial.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93BAD2F51E586310009DF853 /* RowHomeSocial.xib */; };
 		93BAD2F81E586741009DF853 /* RowHomeSocial.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93BAD2F71E586741009DF853 /* RowHomeSocial.swift */; };
 		93BEB6D21E7E878300C68DE5 /* PostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93BEB6D11E7E878300C68DE5 /* PostViewController.swift */; };
+		93D8B0941EF1A64C008BD946 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D8B0931EF1A64C008BD946 /* Notifications.swift */; };
+		93D8B0961EF1B98E008BD946 /* FutureActivityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D8B0951EF1B98E008BD946 /* FutureActivityViewController.swift */; };
+		93D8B0981EF1B99A008BD946 /* RowItinerary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D8B0971EF1B99A008BD946 /* RowItinerary.swift */; };
+		93D8B09A1EF1BA03008BD946 /* RowItinerary.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93D8B0991EF1BA03008BD946 /* RowItinerary.xib */; };
 		93D9EA601DE271E700089002 /* Section.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93D9EA5F1DE271E700089002 /* Section.xib */; };
 		93D9EA641DE273FD00089002 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D9EA631DE273FD00089002 /* Section.swift */; };
 		93D9EA681DE342AC00089002 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D9EA671DE342AC00089002 /* UIView.swift */; };
@@ -84,8 +88,10 @@
 		93E0C5EE1EBE25BD00905811 /* RowLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E0C5ED1EBE25BC00905811 /* RowLabel.swift */; };
 		93E0C5F21EBE264F00905811 /* RowLabel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93E0C5F11EBE264F00905811 /* RowLabel.xib */; };
 		93E0C5F41EBE306900905811 /* ScheduleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E0C5F31EBE306900905811 /* ScheduleViewController.swift */; };
+		93E5058F1EEB0DCC00560B4A /* PhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E5058E1EEB0DCC00560B4A /* PhotoViewController.swift */; };
 		93EB2F0C1EBF5AEB00F64186 /* RowSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93EB2F0B1EBF5AEB00F64186 /* RowSchedule.swift */; };
 		93EB2F0E1EBF5BF500F64186 /* RowSchedule.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93EB2F0D1EBF5BF500F64186 /* RowSchedule.xib */; };
+		93EE9ECB1EE9B87100288F6E /* PastActivityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93EE9ECA1EE9B87100288F6E /* PastActivityViewController.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -153,6 +159,10 @@
 		93BAD2F51E586310009DF853 /* RowHomeSocial.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowHomeSocial.xib; sourceTree = "<group>"; };
 		93BAD2F71E586741009DF853 /* RowHomeSocial.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowHomeSocial.swift; sourceTree = "<group>"; };
 		93BEB6D11E7E878300C68DE5 /* PostViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostViewController.swift; sourceTree = "<group>"; };
+		93D8B0931EF1A64C008BD946 /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
+		93D8B0951EF1B98E008BD946 /* FutureActivityViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FutureActivityViewController.swift; sourceTree = "<group>"; };
+		93D8B0971EF1B99A008BD946 /* RowItinerary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowItinerary.swift; sourceTree = "<group>"; };
+		93D8B0991EF1BA03008BD946 /* RowItinerary.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowItinerary.xib; sourceTree = "<group>"; };
 		93D9EA5F1DE271E700089002 /* Section.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = Section.xib; path = ../Section.xib; sourceTree = "<group>"; };
 		93D9EA631DE273FD00089002 /* Section.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = "<group>"; };
 		93D9EA671DE342AC00089002 /* UIView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
@@ -169,8 +179,10 @@
 		93E0C5ED1EBE25BC00905811 /* RowLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowLabel.swift; sourceTree = "<group>"; };
 		93E0C5F11EBE264F00905811 /* RowLabel.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowLabel.xib; sourceTree = "<group>"; };
 		93E0C5F31EBE306900905811 /* ScheduleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduleViewController.swift; sourceTree = "<group>"; };
+		93E5058E1EEB0DCC00560B4A /* PhotoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoViewController.swift; sourceTree = "<group>"; };
 		93EB2F0B1EBF5AEB00F64186 /* RowSchedule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowSchedule.swift; sourceTree = "<group>"; };
 		93EB2F0D1EBF5BF500F64186 /* RowSchedule.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowSchedule.xib; sourceTree = "<group>"; };
+		93EE9ECA1EE9B87100288F6E /* PastActivityViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PastActivityViewController.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -221,6 +233,7 @@
 		93B84B981D9C31AB006C0F67 /* app */ = {
 			isa = PBXGroup;
 			children = (
+				93D8B0931EF1A64C008BD946 /* Notifications.swift */,
 				93B84BA81D9C31AB006C0F67 /* Info.plist */,
 				93B84BA31D9C31AB006C0F67 /* Assets.xcassets */,
 				93B84BA01D9C31AB006C0F67 /* app.xcdatamodeld */,
@@ -228,8 +241,8 @@
 				93B84B991D9C31AB006C0F67 /* AppDelegate.swift */,
 				93B84B9D1D9C31AB006C0F67 /* Main.storyboard */,
 				93B84B9B1D9C31AB006C0F67 /* ViewController.swift */,
-				93B408021D9ED44C000FBC99 /* MenuCollectionViewCell.swift */,
 				93BEB6D11E7E878300C68DE5 /* PostViewController.swift */,
+				93B408021D9ED44C000FBC99 /* MenuCollectionViewCell.swift */,
 				93D9EA5F1DE271E700089002 /* Section.xib */,
 				93D9EA631DE273FD00089002 /* Section.swift */,
 				931AA5AD1E218D0D003A2290 /* Entry.xib */,
@@ -284,6 +297,11 @@
 				93B9113C1ED7567B0061BA71 /* LocationView.xib */,
 				93B9113E1ED7582B0061BA71 /* LocationView.swift */,
 				93B9115E1ED765510061BA71 /* app-Bridging-Header.h */,
+				93EE9ECA1EE9B87100288F6E /* PastActivityViewController.swift */,
+				93D8B0971EF1B99A008BD946 /* RowItinerary.swift */,
+				93D8B0991EF1BA03008BD946 /* RowItinerary.xib */,
+				93D8B0951EF1B98E008BD946 /* FutureActivityViewController.swift */,
+				93E5058E1EEB0DCC00560B4A /* PhotoViewController.swift */,
 			);
 			path = app;
 			sourceTree = "<group>";
@@ -348,6 +366,11 @@
 						DevelopmentTeam = 9F9ER4X7TG;
 						LastSwiftMigration = 0830;
 						ProvisioningStyle = Automatic;
+						SystemCapabilities = {
+							com.apple.BackgroundModes = {
+								enabled = 1;
+							};
+						};
 					};
 				};
 			};
@@ -376,6 +399,7 @@
 			files = (
 				93E0C5E21EB7E7F000905811 /* ActivitiesView.xib in Resources */,
 				931AA5AE1E218D0E003A2290 /* Entry.xib in Resources */,
+				93D8B09A1EF1BA03008BD946 /* RowItinerary.xib in Resources */,
 				93E0C5E81EBDF0E700905811 /* RowFutureActivity.xib in Resources */,
 				938D211D1EA2275300C47EC3 /* LablancaView.xib in Resources */,
 				93075C721E59D06900396389 /* RowBlog.xib in Resources */,
@@ -424,17 +448,22 @@
 				93294FFA1E337D0D00FDAF50 /* RowHomePastActivities.swift in Sources */,
 				93B5C01A1E872B4B0069BFF8 /* RowHomeGallery.swift in Sources */,
 				935892D01E493C2300E1CD5F /* UIImageView.swift in Sources */,
+				93D8B0981EF1B99A008BD946 /* RowItinerary.swift in Sources */,
 				93D9EA761DE3ACBB00089002 /* Sync.swift in Sources */,
 				93E0C5EA1EBDFFB400905811 /* RowPastActivity.swift in Sources */,
 				93BAD2F41E585EE6009DF853 /* RowHomeFutureActivities.swift in Sources */,
+				93E5058F1EEB0DCC00560B4A /* PhotoViewController.swift in Sources */,
+				93D8B0941EF1A64C008BD946 /* Notifications.swift in Sources */,
 				931AA5891E1AFF8C003A2290 /* String.swift in Sources */,
 				935AE18A1EC6138D0055E71F /* SyncController.swift in Sources */,
 				93B84B9C1D9C31AB006C0F67 /* ViewController.swift in Sources */,
 				93075C6C1E59CB6B00396389 /* BlogView.swift in Sources */,
 				93B84B9A1D9C31AB006C0F67 /* AppDelegate.swift in Sources */,
+				93D8B0961EF1B98E008BD946 /* FutureActivityViewController.swift in Sources */,
 				93B84BA21D9C31AB006C0F67 /* app.xcdatamodeld in Sources */,
 				935D6E331E867C7E00CED3A1 /* RowGallery.swift in Sources */,
 				93EB2F0C1EBF5AEB00F64186 /* RowSchedule.swift in Sources */,
+				93EE9ECB1EE9B87100288F6E /* PastActivityViewController.swift in Sources */,
 				936966ED1E98445200A11055 /* AlbumViewController.swift in Sources */,
 				93D9EA681DE342AC00089002 /* UIView.swift in Sources */,
 				938D211F1EA2306300C47EC3 /* LablancaView.swift in Sources */,

+ 7 - 32
app/ActivitiesView.swift

@@ -21,11 +21,13 @@
 import Foundation
 import CoreData
 import UIKit
+
 /**
 Class to handle the home view.
 */
 class ActivitiesView: UIView {
 	
+	// Outlets.
 	@IBOutlet var container: ActivitiesView!
 	@IBOutlet weak var futureSection: Section!
 	@IBOutlet weak var pastSection: Section!
@@ -38,6 +40,7 @@ class ActivitiesView: UIView {
 	var pastList: UIStackView? = nil
 	var context: NSManagedObjectContext? = nil
 	
+	
 	override init(frame: CGRect){
 		super.init(frame: frame)
 	}
@@ -86,7 +89,6 @@ class ActivitiesView: UIView {
 		do {
 			let searchResults = try self.context?.fetch(fetchRequest)
 			if searchResults?.count == 0{
-				NSLog(":ACTIVITIES:DEBUG: No future activities: \(String(describing: searchResults?.count))")
 				let row: RowLabel = RowLabel.init(s: "rowFutureActivity0", i: 0)
 				row.setText(text: "No hay actividades planeadas proximamente. Pronto organizaremos algo!")
 				self.futureList?.addArrangedSubview(row)
@@ -119,6 +121,7 @@ class ActivitiesView: UIView {
 					row.setPrice(price: price)
 					row.setCity(text: city)
 					row.setDate(date: date, lang: lang!)
+					row.id = id
 				
 					// Get main image
 					image = ""
@@ -139,15 +142,10 @@ class ActivitiesView: UIView {
 					}
 				
 					self.futureList?.addArrangedSubview(row)
-					
-					// TODO: Do this on the row didLoad method
-					// Set tap recognizer
-					//let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(openActivity(_:)))
-					//row.isUserInteractionEnabled = true
-					//row.addGestureRecognizer(tapRecognizer)
 				}
 				self.futureList?.setNeedsLayout()
 				self.futureList?.layoutIfNeeded()
+				
 			}
 		}
 		catch {
@@ -155,7 +153,6 @@ class ActivitiesView: UIView {
 		}
 		
 		
-		
 		// Show past activities
 		fetchRequest = Activity.fetchRequest()
 		sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
@@ -183,6 +180,7 @@ class ActivitiesView: UIView {
 				text = r.value(forKey: "text_\(lang!)")! as! String
 				row.setTitle(text: title)
 				row.setText(text: text)
+				row.id = id
 				
 				// Get main image
 				image = ""
@@ -205,38 +203,15 @@ class ActivitiesView: UIView {
 				
 				
 				self.pastList?.addArrangedSubview(row)
-				
-				// TODO: Do this on the row didLoad method
-				// Set tap recognizer
-				//let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(openActivity(_:)))
-				//row.isUserInteractionEnabled = true
-				//row.addGestureRecognizer(tapRecognizer)
 			}
 			self.pastList?.setNeedsLayout()
 			self.pastList?.layoutIfNeeded()
+			
 		} catch {
 			NSLog(":ACTIVITIES:ERROR: Error with request: \(error)")
 		}
-		NSLog(":ACTIVITIES:DEBUG: Finished loading ActivitiesView")
 	}
 	
-	
-	/*func openActivity(){//(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ACTIVITIES:DEBUG: getting delegate and showing activity.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showActivity(id: 4)
-		NSLog(":ACTIVITIES:DEBUG: Activity should be shown.")
-	}
-	
-	
-	func openActivity(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ACTIVITIES:DEBUG: getting delegate and showing activity.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showActivity(id: 4)
-		NSLog(":ACTIVITIES:DEBUG: Activity should be shown.")
-	}*/
-	
-	
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	If the device has another language, Spanish will be selected by default.

+ 3 - 3
app/ActivitiesView.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -24,7 +24,7 @@
                 <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xyM-cc-W1r">
                     <rect key="frame" x="0.0" y="0.0" width="375" height="666"/>
                     <subviews>
-                        <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" misplaced="YES" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="gvi-ij-s5Q">
+                        <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="gvi-ij-s5Q">
                             <rect key="frame" x="0.0" y="0.0" width="375" height="306"/>
                             <subviews>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jdf-74-tJS" customClass="Section" customModule="app">

+ 58 - 12
app/AlbumViewController.swift

@@ -40,6 +40,7 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 	
 	// Id received from segue.
 	var passId: Int = -1
+	var passAlbum: Int = -1
 	
 	
 	/**
@@ -61,6 +62,27 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 		
 		// Set button action
 		barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
+		
+		// Set this controller in the delegate
+		self.delegate = UIApplication.shared.delegate as? AppDelegate
+		self.delegate?.albumController = self
+		
+		// Get album title
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Album> = Album.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
+		do {
+			let results = try context.fetch(fetchRequest)
+			let r = results[0]
+			let title: String = r.value(forKey: "title_\(lang)")! as! String
+			self.albumTitle.text = " \(title.decode().stripHtml())"
+		}
+		catch {
+			NSLog(":GALLERYCONTROLLER:ERROR: Error getting album info: \(error)")
+		}
 	}
 	
 	
@@ -102,14 +124,15 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 			let searchResults = try context.fetch(fetchRequest)
 			var image: String
 			
-			NSLog(":GALLERYCONTROLLER:DEBUG: Total photos: \(searchResults.count)")
-			
 			for i in (0..<searchResults.count) where i % 2 == 0 {
 				
 				var r = searchResults[i]
 				var photoId = r.value(forKey: "photo")! as! Int
+				var leftId: Int = -1
+				var rightId: Int = -1
 				
 				row = RowAlbum.init(s: "rowAlbum\(i)", i: i)
+				row.id = id
 				
 				// Get photo info from Photo entity
 				let imgFetchRequest: NSFetchRequest<Photo> = Photo.fetchRequest()
@@ -122,40 +145,52 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 					var imgSearchResults = try context.fetch(imgFetchRequest)
 					var imgR = imgSearchResults[0]
 					image = imgR.value(forKey: "file")! as! String
-					NSLog(":GALLERYCONTROLLER:LOG: Image Row \(i) left: \(image)")
+					leftId = imgR.value(forKey: "id")! as! Int
 					row.setImage(idx: 0, filename: image)
 					if i + 1 < searchResults.count {
 						r = searchResults[i + 1]
 						photoId = r.value(forKey: "photo")! as! Int
+						
 						imgFetchRequest.predicate = NSPredicate(format: "id == %i", photoId)
 						imgSearchResults = try context.fetch(imgFetchRequest)
 						
 						
 						imgR = imgSearchResults[0]
 						image = imgR.value(forKey: "file")! as! String
-						NSLog(":GALLERYCONTROLLER:LOG: Image Row \(i) right: \(image)")
+						rightId = imgR.value(forKey: "id")! as! Int
 						row.setImage(idx: 1, filename: image)
 					}
-					else{
-						NSLog(":GALLERYCONTROLLER:LOG: Image Row \(i) right: none")
-					}
-					//TODO create row, add images (L+R), add row to container.
-					//row.setImage(filename: image)
-				} catch {
+				}
+				catch {
 					NSLog(":GALLERYCONTROLLER:ERROR: Error getting image for post \(id): \(error)")
 				}
 				
-				NSLog(":GALLERYCONTROLLER:DEBUG: Adding row: height: \(row.frame.height)")
+				row.setIds(left: leftId, right: rightId)
 				albumContainer.addArrangedSubview(row)
 				
 				rowcount = rowcount + 1
 			}
-		} catch {
+		}
+		catch {
 			NSLog(":GALLERYCONTROLLER:ERROR: Error with request: \(error)")
 		}
 	}
 	
 	
+	/**
+	Run before performing a segue.
+	Assigns id if neccessary.
+	:param: segue The segue to perform.
+	:sender: The calling view.
+	*/
+	override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
+		if segue.identifier == "SeguePhotoAlbum"{
+			(segue.destination as! PhotoViewController).albumId = passAlbum
+			(segue.destination as! PhotoViewController).photoId = passId
+		}
+	}
+	
+	
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	If the device has another language, Spanish will be selected by default.
@@ -171,5 +206,16 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 		}
 	}
 	
+	
+	/**
+	Shows a photo.
+	:param: id The album id.
+	*/
+	func showPhoto(album: Int, photo: Int){
+		self.passAlbum = album
+		self.passId = photo
+		performSegue(withIdentifier: "SeguePhotoAlbum", sender: nil)
+	}
+	
 }
 

+ 41 - 0
app/AppDelegate.swift

@@ -21,23 +21,64 @@
 import UIKit
 import CoreData
 import GoogleMaps
+import UserNotifications
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {
 
 	var window: UIWindow?
 	var controller: ViewController?
+	var albumController: AlbumViewController?
+	var syncController: SyncController?
 
 	
 	func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
 		// Override point for customization after application launch.
 		
+		// Google Mapas API KEY
 		GMSServices.provideAPIKey("AIzaSyBfIiBM_YSBlxybmI_Uz_fGoUFN4wacR80")
 		
+		// Background mode.
+		UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
+		
+		if #available(iOS 10.0, *) {
+			let center = UNUserNotificationCenter.current()
+			center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
+				// Enable or disable features based on authorization.
+			}
+		} else {
+			// Fallback on earlier versions
+		}
+		
+		
 		return true
 	}
 	
 
+	func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
+		NSLog(":BACKGROUND:LOG: Start bg sync...")
+		Notifications()
+		Sync()
+		
+		let when = DispatchTime.now() + 120 // 2 minutes to perform the sync.
+		DispatchQueue.main.asyncAfter(deadline: when) {
+			NSLog(":BACKGROUND:LOG: Calling completion handler.")
+			completionHandler(UIBackgroundFetchResult.newData)
+		}
+		
+		/*if let tabBarController = window?.rootViewController as? UITabBarController, let viewControllers = tabBarController.viewControllers {
+			for viewController in viewControllers {
+				if let fetchViewController = viewController as? FetchViewController {
+					fetchViewController.fetch {
+						fetchViewController.updateUI()
+						completionHandler(.newData)
+					}
+				}
+			}
+		}*/
+	}
+
+
 	/**
 	Sent when the application is about to move from active to inactive state.
 	This can occur for certain types of temporary interruptions

+ 463 - 4
app/Base.lproj/Main.storyboard

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="3o1-ab-AT4">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
@@ -85,12 +85,12 @@
                                                         <constraint firstAttribute="width" constant="100" id="eKL-ga-53F"/>
                                                     </constraints>
                                                     <fontDescription key="fontDescription" type="system" pointSize="17"/>
-                                                    <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                    <color key="textColor" red="0.78431372549019607" green="0.78431372549019607" blue="0.78431372549019607" alpha="1" colorSpace="calibratedRGB"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
                                                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZNu-9N-o6K">
                                                     <rect key="frame" x="4" y="38" width="92" height="4"/>
-                                                    <color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                    <color key="backgroundColor" red="0.3529411764705882" green="0.70588235294117641" blue="1" alpha="1" colorSpace="calibratedRGB"/>
                                                     <constraints>
                                                         <constraint firstAttribute="height" constant="4" id="Si5-HX-bjR"/>
                                                     </constraints>
@@ -198,7 +198,8 @@
                         <segue destination="UkS-wI-Yhx" kind="show" identifier="SeguePost" id="gs2-jd-cPW"/>
                         <segue destination="k0M-Sk-DZM" kind="show" identifier="SegueAlbum" id="Puc-tv-vaD"/>
                         <segue destination="zJF-Mh-CNb" kind="show" identifier="SegueSchedule" id="A70-jo-yAP"/>
-                        <segue destination="3o1-ab-AT4" kind="show" identifier="SegueSync" id="E96-mK-gE9"/>
+                        <segue destination="jfx-Q2-RtY" kind="show" identifier="SeguePastActivity" id="MmG-k2-wHn"/>
+                        <segue destination="DDO-dI-c0J" kind="show" identifier="SegueFutureActivity" id="ec7-aO-4Ac"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
@@ -1027,11 +1028,469 @@
                     <connections>
                         <outlet property="lb" destination="pgU-dx-MvQ" id="ATL-SS-rxd"/>
                         <outlet property="pb" destination="VkR-DT-y3S" id="NMd-7R-Rlc"/>
+                        <segue destination="BYZ-38-t0r" kind="showDetail" identifier="SegueInit" action="showViewController:sender:" id="kSh-cP-och"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="fRm-1Y-Xmm" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
         </scene>
+        <!--Past Activity View Controller-->
+        <scene sceneID="0of-i7-sd6">
+            <objects>
+                <viewController id="jfx-Q2-RtY" customClass="PastActivityViewController" customModule="app" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="u2P-so-lU7"/>
+                        <viewControllerLayoutGuide type="bottom" id="Lav-1c-S51"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="SdM-pu-zm3">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BxO-VS-eP5" userLabel="Toolbar">
+                                <rect key="frame" x="0.0" y="20" width="375" height="30"/>
+                                <subviews>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Loj-Ff-gNj">
+                                        <rect key="frame" x="0.0" y="0.0" width="56.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                        <state key="normal" title="&lt;">
+                                            <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                    </button>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gasteizko Margolariak" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xf1-tl-98b">
+                                        <rect key="frame" x="56.5" y="0.0" width="262.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="height" secondItem="BxO-VS-eP5" secondAttribute="height" id="A9Y-Fw-3wT"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="width" secondItem="BxO-VS-eP5" secondAttribute="width" multiplier="0.15" id="JAK-Wn-RB0"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="leading" secondItem="BxO-VS-eP5" secondAttribute="leading" id="KWZ-5M-JBT"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="height" secondItem="BxO-VS-eP5" secondAttribute="height" id="PRz-QI-LGC"/>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="width" secondItem="BxO-VS-eP5" secondAttribute="width" multiplier="0.7" id="cAg-nR-WRl"/>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="centerY" secondItem="BxO-VS-eP5" secondAttribute="centerY" id="cCD-R8-57d"/>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="centerX" secondItem="BxO-VS-eP5" secondAttribute="centerX" id="ltM-gK-avh"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="centerY" secondItem="BxO-VS-eP5" secondAttribute="centerY" id="rUy-8N-1cq"/>
+                                </constraints>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JgN-DW-xUZ">
+                                <rect key="frame" x="0.0" y="50" width="375" height="617"/>
+                                <subviews>
+                                    <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3SZ-u2-ZIb">
+                                        <rect key="frame" x="0.0" y="0.0" width="375" height="617"/>
+                                        <subviews>
+                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xi6-iq-IpA" userLabel="Section">
+                                                <rect key="frame" x="10" y="10" width="355" height="995"/>
+                                                <subviews>
+                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" restorationIdentifier="Title" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cWR-TU-0Za" userLabel="Title">
+                                                        <rect key="frame" x="0.0" y="0.0" width="355" height="30"/>
+                                                        <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                        <constraints>
+                                                            <constraint firstAttribute="height" constant="30" id="s4L-e0-U96"/>
+                                                        </constraints>
+                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                        <nil key="highlightedColor"/>
+                                                    </label>
+                                                    <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="riK-xb-Vls" userLabel="Content">
+                                                        <rect key="frame" x="0.0" y="30" width="355" height="965"/>
+                                                        <subviews>
+                                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Omg-cP-uvF" userLabel="Activity">
+                                                                <rect key="frame" x="8" y="8" width="339" height="949"/>
+                                                                <subviews>
+                                                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="8Jn-h7-TSJ" userLabel="Image">
+                                                                        <rect key="frame" x="0.0" y="10" width="339" height="71"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="71" id="lZg-2O-4LP"/>
+                                                                        </constraints>
+                                                                    </imageView>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Text" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Usd-Rm-Tq2" userLabel="Text">
+                                                                        <rect key="frame" x="17" y="91" width="305.5" height="826"/>
+                                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                                                        <nil key="textColor"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LmH-0o-Hku" userLabel="Separator">
+                                                                        <rect key="frame" x="17" y="917" width="305.5" height="2"/>
+                                                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="2" id="X7n-cL-6Hk"/>
+                                                                        </constraints>
+                                                                    </view>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="254" text="Date" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dvg-B2-xmI" userLabel="Date">
+                                                                        <rect key="frame" x="17" y="929" width="305.5" height="20"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="20" id="8LF-YM-5Cn"/>
+                                                                        </constraints>
+                                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                                                        <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                </subviews>
+                                                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                                <constraints>
+                                                                    <constraint firstItem="Usd-Rm-Tq2" firstAttribute="top" secondItem="8Jn-h7-TSJ" secondAttribute="bottom" constant="10" id="1oO-Iq-tff"/>
+                                                                    <constraint firstItem="LmH-0o-Hku" firstAttribute="top" secondItem="Usd-Rm-Tq2" secondAttribute="bottom" id="7Du-au-fft"/>
+                                                                    <constraint firstItem="8Jn-h7-TSJ" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="H9k-8U-X4o"/>
+                                                                    <constraint firstItem="dvg-B2-xmI" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" multiplier="0.9" id="LcU-3f-pz6"/>
+                                                                    <constraint firstItem="Usd-Rm-Tq2" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" multiplier="0.9" id="MQd-UV-3Ee"/>
+                                                                    <constraint firstItem="dvg-B2-xmI" firstAttribute="top" secondItem="LmH-0o-Hku" secondAttribute="bottom" constant="10" id="QrH-eq-mXV"/>
+                                                                    <constraint firstItem="Usd-Rm-Tq2" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="SHM-nk-s9u"/>
+                                                                    <constraint firstItem="dvg-B2-xmI" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="XBR-sR-Yqg"/>
+                                                                    <constraint firstItem="LmH-0o-Hku" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="a8v-br-EaA"/>
+                                                                    <constraint firstItem="8Jn-h7-TSJ" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" id="gm5-CU-FKw"/>
+                                                                    <constraint firstItem="8Jn-h7-TSJ" firstAttribute="top" secondItem="Omg-cP-uvF" secondAttribute="top" constant="10" id="js6-Fg-pg1"/>
+                                                                    <constraint firstAttribute="bottom" secondItem="dvg-B2-xmI" secondAttribute="bottom" id="lta-H9-CYI"/>
+                                                                    <constraint firstItem="LmH-0o-Hku" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" multiplier="0.9" id="xmH-tU-ZFp"/>
+                                                                </constraints>
+                                                                <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                                <userDefinedRuntimeAttributes>
+                                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                                        <color key="value" red="0.42745098040000001" green="0.41176470590000003" blue="0.56470588239999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                                        <real key="value" value="1"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                                        <real key="value" value="3"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                </userDefinedRuntimeAttributes>
+                                                            </view>
+                                                        </subviews>
+                                                        <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                        <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                    </stackView>
+                                                </subviews>
+                                                <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="bottom" secondItem="riK-xb-Vls" secondAttribute="bottom" id="Cx5-Kf-8OE"/>
+                                                    <constraint firstItem="cWR-TU-0Za" firstAttribute="width" secondItem="xi6-iq-IpA" secondAttribute="width" id="FVH-in-wHT"/>
+                                                    <constraint firstItem="riK-xb-Vls" firstAttribute="top" secondItem="cWR-TU-0Za" secondAttribute="bottom" id="Hn5-9l-iCk"/>
+                                                    <constraint firstItem="riK-xb-Vls" firstAttribute="centerX" secondItem="xi6-iq-IpA" secondAttribute="centerX" id="KR9-e1-CPc"/>
+                                                    <constraint firstItem="cWR-TU-0Za" firstAttribute="centerX" secondItem="xi6-iq-IpA" secondAttribute="centerX" id="eMS-XG-Mee"/>
+                                                    <constraint firstItem="riK-xb-Vls" firstAttribute="width" secondItem="xi6-iq-IpA" secondAttribute="width" id="g6A-Nh-o8X"/>
+                                                    <constraint firstItem="cWR-TU-0Za" firstAttribute="top" secondItem="xi6-iq-IpA" secondAttribute="top" id="yuP-2e-AdF"/>
+                                                </constraints>
+                                                <edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
+                                                <userDefinedRuntimeAttributes>
+                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                        <color key="value" red="0.0" green="0.0" blue="0.066666666669999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                        <real key="value" value="1"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                        <real key="value" value="8"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                </userDefinedRuntimeAttributes>
+                                            </view>
+                                        </subviews>
+                                        <color key="backgroundColor" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <constraints>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="top" secondItem="3SZ-u2-ZIb" secondAttribute="top" constant="10" id="DOt-pc-3eb"/>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="centerX" secondItem="3SZ-u2-ZIb" secondAttribute="centerX" id="IFM-jn-576"/>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="trailing" secondItem="3SZ-u2-ZIb" secondAttribute="trailing" constant="10" id="SAk-SF-xVS"/>
+                                            <constraint firstAttribute="bottom" secondItem="xi6-iq-IpA" secondAttribute="bottom" constant="10" id="Xdk-K7-KDJ"/>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="leading" secondItem="3SZ-u2-ZIb" secondAttribute="leading" constant="10" id="wud-Ff-5hQ"/>
+                                        </constraints>
+                                        <edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
+                                        <userDefinedRuntimeAttributes>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                <real key="value" value="0.0"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </scrollView>
+                                </subviews>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstItem="3SZ-u2-ZIb" firstAttribute="width" secondItem="JgN-DW-xUZ" secondAttribute="width" id="31P-4U-Pt1"/>
+                                    <constraint firstAttribute="bottom" secondItem="3SZ-u2-ZIb" secondAttribute="bottom" id="Eou-gG-0WN"/>
+                                    <constraint firstItem="3SZ-u2-ZIb" firstAttribute="centerX" secondItem="JgN-DW-xUZ" secondAttribute="centerX" id="JzA-TZ-T6w"/>
+                                    <constraint firstItem="3SZ-u2-ZIb" firstAttribute="top" secondItem="JgN-DW-xUZ" secondAttribute="top" id="T5M-NN-rUZ"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                        <color key="value" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="BxO-VS-eP5" firstAttribute="centerX" secondItem="SdM-pu-zm3" secondAttribute="centerX" id="0eo-Jq-yKG"/>
+                            <constraint firstItem="JgN-DW-xUZ" firstAttribute="centerX" secondItem="SdM-pu-zm3" secondAttribute="centerX" id="XMm-11-4Bs"/>
+                            <constraint firstItem="Lav-1c-S51" firstAttribute="top" secondItem="JgN-DW-xUZ" secondAttribute="bottom" id="ai7-fu-CPH"/>
+                            <constraint firstItem="BxO-VS-eP5" firstAttribute="width" secondItem="SdM-pu-zm3" secondAttribute="width" id="d1M-W0-fTO"/>
+                            <constraint firstItem="JgN-DW-xUZ" firstAttribute="width" secondItem="SdM-pu-zm3" secondAttribute="width" id="jJF-ok-Gxw"/>
+                            <constraint firstItem="JgN-DW-xUZ" firstAttribute="top" secondItem="BxO-VS-eP5" secondAttribute="bottom" id="pqm-X9-1Pa"/>
+                            <constraint firstItem="BxO-VS-eP5" firstAttribute="top" secondItem="u2P-so-lU7" secondAttribute="bottom" id="qdC-D0-ERu"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="activityDate" destination="dvg-B2-xmI" id="hyQ-Wm-9J7"/>
+                        <outlet property="activityImage" destination="8Jn-h7-TSJ" id="OtM-Zu-0Qf"/>
+                        <outlet property="activityText" destination="Usd-Rm-Tq2" id="ySl-QS-kOh"/>
+                        <outlet property="activityTitle" destination="cWR-TU-0Za" id="oRe-G1-MMU"/>
+                        <outlet property="barButton" destination="Loj-Ff-gNj" id="0tW-a0-rNG"/>
+                        <outlet property="barTitle" destination="xf1-tl-98b" id="dO8-P5-V8C"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="YKC-ZH-aSz" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+        <!--Future Activity View Controller-->
+        <scene sceneID="thm-MM-5qk">
+            <objects>
+                <viewController id="DDO-dI-c0J" customClass="FutureActivityViewController" customModule="app" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="yac-Xq-lM3"/>
+                        <viewControllerLayoutGuide type="bottom" id="94e-TO-KhL"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="Tll-v9-w0T">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wso-as-8H4" userLabel="Toolbar">
+                                <rect key="frame" x="0.0" y="20" width="375" height="30"/>
+                                <subviews>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FiC-sd-IGL">
+                                        <rect key="frame" x="0.0" y="0.0" width="56.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                        <state key="normal" title="&lt;">
+                                            <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                    </button>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gasteizko Margolariak" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="v7W-BZ-qle">
+                                        <rect key="frame" x="56.5" y="0.0" width="262.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="FiC-sd-IGL" firstAttribute="centerY" secondItem="Wso-as-8H4" secondAttribute="centerY" id="Bwe-wN-Ciz"/>
+                                    <constraint firstItem="v7W-BZ-qle" firstAttribute="height" secondItem="Wso-as-8H4" secondAttribute="height" id="De6-CZ-soc"/>
+                                    <constraint firstItem="v7W-BZ-qle" firstAttribute="width" secondItem="Wso-as-8H4" secondAttribute="width" multiplier="0.7" id="HFz-HT-150"/>
+                                    <constraint firstItem="v7W-BZ-qle" firstAttribute="centerX" secondItem="Wso-as-8H4" secondAttribute="centerX" id="SH6-iN-gma"/>
+                                    <constraint firstItem="FiC-sd-IGL" firstAttribute="height" secondItem="Wso-as-8H4" secondAttribute="height" id="aAa-nP-JRw"/>
+                                    <constraint firstItem="FiC-sd-IGL" firstAttribute="width" secondItem="Wso-as-8H4" secondAttribute="width" multiplier="0.15" id="fvu-CA-aIr"/>
+                                    <constraint firstItem="FiC-sd-IGL" firstAttribute="leading" secondItem="Wso-as-8H4" secondAttribute="leading" id="pXi-AQ-w7N"/>
+                                    <constraint firstItem="v7W-BZ-qle" firstAttribute="centerY" secondItem="Wso-as-8H4" secondAttribute="centerY" id="rhp-eA-2va"/>
+                                </constraints>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Sqd-hf-hGI" userLabel="Cont">
+                                <rect key="frame" x="0.0" y="50" width="375" height="617"/>
+                                <subviews>
+                                    <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" bounces="NO" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Gqf-Sj-1VO">
+                                        <rect key="frame" x="0.0" y="0.0" width="375" height="617"/>
+                                        <subviews>
+                                            <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kyg-VN-Jc1" userLabel="Section">
+                                                <rect key="frame" x="10" y="10" width="355" height="1954"/>
+                                                <subviews>
+                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" restorationIdentifier="Title" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pz6-97-sPy" userLabel="Title">
+                                                        <rect key="frame" x="0.0" y="0.0" width="355" height="30"/>
+                                                        <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                        <constraints>
+                                                            <constraint firstAttribute="height" constant="30" id="den-z0-VST"/>
+                                                        </constraints>
+                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                        <nil key="highlightedColor"/>
+                                                    </label>
+                                                    <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="2yK-fO-giD" userLabel="Content">
+                                                        <rect key="frame" x="0.0" y="30" width="355" height="1175"/>
+                                                        <subviews>
+                                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Qj9-S3-bY4" userLabel="Activity">
+                                                                <rect key="frame" x="8" y="8" width="339" height="200"/>
+                                                                <subviews>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="254" text="Date" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6gj-f6-Ggb" userLabel="Date">
+                                                                        <rect key="frame" x="10" y="10" width="319" height="20"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="20" id="9ED-Vw-Zue"/>
+                                                                        </constraints>
+                                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                                                        <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="Ztx-jl-MsD" userLabel="Image">
+                                                                        <rect key="frame" x="0.0" y="40" width="339" height="71"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="71" id="s96-BJ-tG9"/>
+                                                                        </constraints>
+                                                                    </imageView>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Text" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s4H-vW-9W1" userLabel="Text">
+                                                                        <rect key="frame" x="17" y="121" width="305.5" height="39"/>
+                                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                                                        <nil key="textColor"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="254" text="Precio: 0E" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2JU-8j-g42" userLabel="Price">
+                                                                        <rect key="frame" x="10" y="170" width="319" height="20"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="20" id="RZA-yo-WR6"/>
+                                                                        </constraints>
+                                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                                                        <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                </subviews>
+                                                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                                <constraints>
+                                                                    <constraint firstItem="s4H-vW-9W1" firstAttribute="width" secondItem="Qj9-S3-bY4" secondAttribute="width" multiplier="0.9" id="4WU-oP-oyH"/>
+                                                                    <constraint firstItem="Ztx-jl-MsD" firstAttribute="centerX" secondItem="Qj9-S3-bY4" secondAttribute="centerX" id="GVu-8M-yPh"/>
+                                                                    <constraint firstItem="6gj-f6-Ggb" firstAttribute="top" secondItem="Qj9-S3-bY4" secondAttribute="top" constant="10" id="Icg-y4-cOc"/>
+                                                                    <constraint firstItem="2JU-8j-g42" firstAttribute="top" secondItem="s4H-vW-9W1" secondAttribute="bottom" constant="10" id="SjA-hc-Hei"/>
+                                                                    <constraint firstAttribute="bottom" secondItem="2JU-8j-g42" secondAttribute="bottom" constant="10" id="Vlo-eb-rs8"/>
+                                                                    <constraint firstItem="s4H-vW-9W1" firstAttribute="centerX" secondItem="Qj9-S3-bY4" secondAttribute="centerX" id="Vqv-6j-le8"/>
+                                                                    <constraint firstItem="2JU-8j-g42" firstAttribute="width" secondItem="Qj9-S3-bY4" secondAttribute="width" constant="-20" id="ZOe-dR-B4s"/>
+                                                                    <constraint firstItem="s4H-vW-9W1" firstAttribute="top" secondItem="Ztx-jl-MsD" secondAttribute="bottom" constant="10" id="be6-mK-3Ki"/>
+                                                                    <constraint firstItem="2JU-8j-g42" firstAttribute="centerX" secondItem="Qj9-S3-bY4" secondAttribute="centerX" id="gdn-GS-gAm"/>
+                                                                    <constraint firstItem="Ztx-jl-MsD" firstAttribute="top" secondItem="6gj-f6-Ggb" secondAttribute="bottom" constant="10" id="ihO-Xt-zic"/>
+                                                                    <constraint firstItem="6gj-f6-Ggb" firstAttribute="width" secondItem="Qj9-S3-bY4" secondAttribute="width" constant="-20" id="jmb-0t-Hfc"/>
+                                                                    <constraint firstItem="6gj-f6-Ggb" firstAttribute="centerX" secondItem="Qj9-S3-bY4" secondAttribute="centerX" id="me4-rt-RAG"/>
+                                                                    <constraint firstItem="Ztx-jl-MsD" firstAttribute="width" secondItem="Qj9-S3-bY4" secondAttribute="width" id="tZQ-7w-fhB"/>
+                                                                </constraints>
+                                                                <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                                <userDefinedRuntimeAttributes>
+                                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                                        <color key="value" red="0.42745098040000001" green="0.41176470590000003" blue="0.56470588239999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                                        <real key="value" value="1"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                                        <real key="value" value="3"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                </userDefinedRuntimeAttributes>
+                                                            </view>
+                                                            <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HZX-gN-1YI" userLabel="Itinerary">
+                                                                <rect key="frame" x="8" y="218" width="339" height="949"/>
+                                                                <subviews>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Itinerario" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cjj-sd-Gou" userLabel="Title">
+                                                                        <rect key="frame" x="10" y="10" width="319" height="21.5"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="21.5" id="2zz-qZ-PEW"/>
+                                                                        </constraints>
+                                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
+                                                                        <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                    <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="3lO-kN-Y0S">
+                                                                        <rect key="frame" x="9.5" y="374" width="319" height="200"/>
+                                                                    </stackView>
+                                                                </subviews>
+                                                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                                <constraints>
+                                                                    <constraint firstItem="3lO-kN-Y0S" firstAttribute="width" secondItem="HZX-gN-1YI" secondAttribute="width" constant="-20" id="Hz4-jl-pQ1"/>
+                                                                    <constraint firstItem="3lO-kN-Y0S" firstAttribute="top" secondItem="cjj-sd-Gou" secondAttribute="bottom" constant="10" id="Okn-6j-Z72"/>
+                                                                    <constraint firstItem="cjj-sd-Gou" firstAttribute="width" secondItem="HZX-gN-1YI" secondAttribute="width" constant="-20" id="Vpb-9J-POY"/>
+                                                                    <constraint firstAttribute="bottom" secondItem="3lO-kN-Y0S" secondAttribute="bottom" constant="10" id="hpN-tm-PLc"/>
+                                                                    <constraint firstItem="cjj-sd-Gou" firstAttribute="centerX" secondItem="HZX-gN-1YI" secondAttribute="centerX" id="qlD-cC-2hf"/>
+                                                                    <constraint firstItem="cjj-sd-Gou" firstAttribute="top" secondItem="HZX-gN-1YI" secondAttribute="top" constant="10" id="sUG-Wx-Qba"/>
+                                                                    <constraint firstItem="3lO-kN-Y0S" firstAttribute="centerX" secondItem="HZX-gN-1YI" secondAttribute="centerX" id="tpQ-ml-ORh"/>
+                                                                </constraints>
+                                                                <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                                <userDefinedRuntimeAttributes>
+                                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                                        <color key="value" red="0.42745098040000001" green="0.41176470590000003" blue="0.56470588239999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                                        <real key="value" value="1"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                                        <real key="value" value="3"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                </userDefinedRuntimeAttributes>
+                                                            </view>
+                                                        </subviews>
+                                                        <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                        <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                    </stackView>
+                                                </subviews>
+                                                <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                <constraints>
+                                                    <constraint firstItem="pz6-97-sPy" firstAttribute="centerX" secondItem="kyg-VN-Jc1" secondAttribute="centerX" id="Fdn-EI-QGl"/>
+                                                    <constraint firstItem="2yK-fO-giD" firstAttribute="centerX" secondItem="kyg-VN-Jc1" secondAttribute="centerX" id="kDg-sI-VYI"/>
+                                                    <constraint firstAttribute="bottom" secondItem="2yK-fO-giD" secondAttribute="bottom" id="ogx-5T-Dfd"/>
+                                                    <constraint firstItem="2yK-fO-giD" firstAttribute="top" secondItem="pz6-97-sPy" secondAttribute="bottom" id="qPT-dv-eVg"/>
+                                                    <constraint firstItem="pz6-97-sPy" firstAttribute="width" secondItem="kyg-VN-Jc1" secondAttribute="width" id="qWi-1Z-VWQ"/>
+                                                    <constraint firstItem="2yK-fO-giD" firstAttribute="width" secondItem="kyg-VN-Jc1" secondAttribute="width" id="rY6-hl-afc"/>
+                                                    <constraint firstItem="pz6-97-sPy" firstAttribute="top" secondItem="kyg-VN-Jc1" secondAttribute="top" id="sw5-Qt-DUd"/>
+                                                </constraints>
+                                                <edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
+                                                <userDefinedRuntimeAttributes>
+                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                        <color key="value" red="0.0" green="0.0" blue="0.066666666669999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                        <real key="value" value="1"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                        <real key="value" value="8"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                </userDefinedRuntimeAttributes>
+                                            </view>
+                                        </subviews>
+                                        <color key="backgroundColor" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <constraints>
+                                            <constraint firstItem="kyg-VN-Jc1" firstAttribute="trailing" secondItem="Gqf-Sj-1VO" secondAttribute="trailing" constant="10" id="4CW-W7-4ND"/>
+                                            <constraint firstItem="kyg-VN-Jc1" firstAttribute="top" secondItem="Gqf-Sj-1VO" secondAttribute="top" constant="10" id="fyr-qO-Cdl"/>
+                                            <constraint firstItem="kyg-VN-Jc1" firstAttribute="centerX" secondItem="Gqf-Sj-1VO" secondAttribute="centerX" id="hjI-3k-lKK"/>
+                                            <constraint firstItem="kyg-VN-Jc1" firstAttribute="leading" secondItem="Gqf-Sj-1VO" secondAttribute="leading" constant="10" id="hmA-Z3-r1z"/>
+                                            <constraint firstAttribute="bottom" secondItem="kyg-VN-Jc1" secondAttribute="bottom" constant="10" id="nGV-76-wZo"/>
+                                        </constraints>
+                                        <edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
+                                        <userDefinedRuntimeAttributes>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                <real key="value" value="0.0"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </scrollView>
+                                </subviews>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstItem="Gqf-Sj-1VO" firstAttribute="width" secondItem="Sqd-hf-hGI" secondAttribute="width" id="RkS-ku-LcK"/>
+                                    <constraint firstItem="Gqf-Sj-1VO" firstAttribute="centerX" secondItem="Sqd-hf-hGI" secondAttribute="centerX" id="bTt-jg-jEg"/>
+                                    <constraint firstItem="Gqf-Sj-1VO" firstAttribute="top" secondItem="Sqd-hf-hGI" secondAttribute="top" id="wgm-EO-9Fw"/>
+                                    <constraint firstAttribute="bottom" secondItem="Gqf-Sj-1VO" secondAttribute="bottom" id="zBV-o0-Ah0"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                        <color key="value" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="Sqd-hf-hGI" firstAttribute="width" secondItem="Tll-v9-w0T" secondAttribute="width" id="4Oi-mE-zRB"/>
+                            <constraint firstItem="Sqd-hf-hGI" firstAttribute="top" secondItem="Wso-as-8H4" secondAttribute="bottom" id="5pc-Qo-6wP"/>
+                            <constraint firstItem="Sqd-hf-hGI" firstAttribute="centerX" secondItem="Tll-v9-w0T" secondAttribute="centerX" id="D9r-lY-5aj"/>
+                            <constraint firstItem="94e-TO-KhL" firstAttribute="top" secondItem="Sqd-hf-hGI" secondAttribute="bottom" id="F8t-mE-en5"/>
+                            <constraint firstItem="Wso-as-8H4" firstAttribute="top" secondItem="yac-Xq-lM3" secondAttribute="bottom" id="Ip2-eX-rdk"/>
+                            <constraint firstItem="Wso-as-8H4" firstAttribute="centerX" secondItem="Tll-v9-w0T" secondAttribute="centerX" id="Mxx-Zd-rFC"/>
+                            <constraint firstItem="Wso-as-8H4" firstAttribute="width" secondItem="Tll-v9-w0T" secondAttribute="width" id="gSn-Ue-Gl1"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="activityDate" destination="6gj-f6-Ggb" id="eBH-rF-6p2"/>
+                        <outlet property="activityImage" destination="Ztx-jl-MsD" id="kAh-WI-jsg"/>
+                        <outlet property="activityPrice" destination="2JU-8j-g42" id="0na-jU-hcv"/>
+                        <outlet property="activityText" destination="s4H-vW-9W1" id="edz-vu-9kL"/>
+                        <outlet property="activityTitle" destination="pz6-97-sPy" id="QFy-g3-k0u"/>
+                        <outlet property="barButton" destination="FiC-sd-IGL" id="cbn-gb-Nj5"/>
+                        <outlet property="barTitle" destination="v7W-BZ-qle" id="aQB-IA-P19"/>
+                        <outlet property="itineraryContainer" destination="HZX-gN-1YI" id="1lZ-0m-TwZ"/>
+                        <outlet property="itineraryList" destination="3lO-kN-Y0S" id="Vf3-t6-l0Y"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="IHt-fO-2Q0" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="1302" y="-403"/>
+        </scene>
     </scenes>
     <resources>
         <image name="GM" width="120" height="120"/>

+ 8 - 32
app/BlogView.swift

@@ -60,19 +60,18 @@ class BlogView: UIView {
 		
 		// Get viewController from StoryBoard
 		self.storyboard = UIStoryboard(name: "Main", bundle: nil)
-		self.controller = storyboard?.instantiateViewController(withIdentifier: "GMViewController") as? ViewController
+		self.controller = storyboard?.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
 		self.context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
 		self.lang = getLanguage()
 		self.context?.persistentStoreCoordinator = delegate?.persistentStoreCoordinator
 		
 		populate()
-		
 	}
 	
 	
 	/**
-	Populates the section.
+	Actually populates the section.
 	*/
 	func populate(){
 		let fetchRequest: NSFetchRequest<Post> = Post.fetchRequest()
@@ -87,18 +86,17 @@ class BlogView: UIView {
 			}
 			
 			// Get the results
-			let searchResults = try self.context?.fetch(fetchRequest)			
+			let searchResults = try self.context?.fetch(fetchRequest)
 			
+			var count: Int = 0
 			var row : RowBlog
-			var count = 0
 			var id: Int
 			var title: String
 			var text: String
 			var image: String
 			
 			for r in searchResults! {
-				count = count + 1
-				
+								
 				//Create a new row
 				row = RowBlog.init(s: "rowBlog\(count)", i: count)
 				id = r.value(forKey: "id")! as! Int
@@ -106,6 +104,7 @@ class BlogView: UIView {
 				text = r.value(forKey: "text_\(lang!)")! as! String
 				row.setTitle(text: title)
 				row.setText(text: text)
+				row.id = id
 				
 				// Get main image
 				image = ""
@@ -127,13 +126,7 @@ class BlogView: UIView {
 				
 				
 				self.postList?.addArrangedSubview(row)
-				
-				// TODO: Do this on the row didLoad method
-				// Set tap recognizer
-				//let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(openPost(_:)))
-				//row.isUserInteractionEnabled = true
-				//row.addGestureRecognizer(tapRecognizer)
-				
+				count = count + 1
 			}
 
 			// Trigger a layout update
@@ -143,25 +136,8 @@ class BlogView: UIView {
 		} catch {
 			NSLog(":BLOG:ERROR: Error with request: \(error)")
 		}
-		NSLog(":BLOG:DEBUG: Finished populating BlogView")
 	}
-	
-	
-	/*func openPost(){//(_ sender:UITapGestureRecognizer? = nil){
-		print("BLOG:DEBUG: getting delegate and showing post.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showPost(id: 4)
-		
-	print("BLOG:DEBUG: Post should be shown.")
-	}
-	
-	func openPost(_ sender:UITapGestureRecognizer? = nil){
-		print("BLOG:DEBUG: getting delegate and showing post.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showPost(id: 4)
-		print("BLOG:DEBUG: Post should be shown.")
-	}*/
-	
+
 	
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.

+ 0 - 1
app/FetchLocation.swift

@@ -50,7 +50,6 @@ class FetchLocation{
 			if status == 200{
 			
 				guard let data = data else {
-					NSLog(":LOCATION:DEBUG: No data received.")
 					return
 				}
 

+ 309 - 0
app/FutureActivityViewController.swift

@@ -0,0 +1,309 @@
+// Copyright (C) 2016 Inigo Valentin
+//
+// This file is part of the Gasteizko Margolariak IOS app.
+//
+// The Gasteizko Margolariak IOS app is free software: you can
+// redistribute it and/or modify it under the terms of the
+// GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// The Gasteizko Margolariak IOS app is distributed in the
+// hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with the Gasteizko Margolariak IOS app.
+// If not, see <http://www.gnu.org/licenses/>.
+
+import UIKit
+import CoreData
+
+/**
+Controller to show a future activity.
+*/
+class FutureActivityViewController: UIViewController, UIGestureRecognizerDelegate {
+	
+	@IBOutlet weak var barButton: UIButton!
+	@IBOutlet weak var barTitle: UILabel!
+	@IBOutlet weak var activityTitle: UILabel!
+	@IBOutlet weak var activityImage: UIImageView!
+	@IBOutlet weak var activityText: UILabel!
+	@IBOutlet weak var activityDate: UILabel!
+	@IBOutlet weak var itineraryContainer: UIView!
+	@IBOutlet weak var itineraryList: UIStackView!
+	@IBOutlet weak var activityPrice: UILabel!
+	
+	// Activity id
+	var id: Int = -1
+	
+	var delegate: AppDelegate?
+	
+	var passId: Int = -1
+	
+	
+	/**
+	Get the app context.
+	:return: The app context.
+	*/
+	func getContext () -> NSManagedObjectContext {
+		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
+	}
+	
+	
+	/**
+	Run when the app loads.
+	*/
+	override func viewDidLoad() {
+		super.viewDidLoad()
+		self.loadActivity(id: id)
+		// Set button action
+		barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
+	}
+	
+	
+	/**
+	Dismisses the controller.
+	*/
+	func back() {
+		self.dismiss(animated: true, completion: nil)
+	}
+	
+	
+	/**
+	Dispose of any resources that can be recreated.
+	*/
+	override func didReceiveMemoryWarning() {
+		super.didReceiveMemoryWarning()
+	}
+	
+	
+	/**
+	Loads the selected post.
+	:param: id Post id.
+	*/
+	public func loadActivity(id: Int){
+		
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Activity> = Activity.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
+		
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			var count = 0
+			var sTitle: String
+			var sText: String
+			var image: String
+			var date: NSDate
+			var price: Int
+			
+			for r in searchResults as [NSManagedObject] {
+				count = count + 1
+				sTitle = r.value(forKey: "title_\(lang)")! as! String
+				sText = r.value(forKey: "text_\(lang)")! as! String
+				date = r.value(forKey: "date")! as! NSDate
+				price = r.value(forKey: "price")! as! Int
+				activityTitle.text = "  \(sTitle.decode().stripHtml())"
+				activityText.text = sText.decode().stripHtml()
+				activityDate.text = formatDate(date: date, lang: lang)
+				activityPrice.text = "Precio: \(price) €"
+				
+				// Get main image
+				image = ""
+				let imgFetchRequest: NSFetchRequest<Activity_image> = Activity_image.fetchRequest()
+				let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
+				let imgSortDescriptors = [imgSortDescriptor]
+				imgFetchRequest.sortDescriptors = imgSortDescriptors
+				imgFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
+				imgFetchRequest.fetchLimit = 1
+				do{
+					let imgSearchResults = try context.fetch(imgFetchRequest)
+					for imgR in imgSearchResults as [NSManagedObject]{
+						image = imgR.value(forKey: "image")! as! String
+						let path = "img/actividades/preview/\(image)"
+						self.activityImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+					}
+				}
+				catch {
+					NSLog(":FUTUREACTIVITYCONTROLLER:ERROR: Error getting image for past activity \(id): \(error)")
+				}
+				
+				// Get itinerary
+				let itiFetchRequest: NSFetchRequest<Activity_itinerary> = Activity_itinerary.fetchRequest()
+				let itiSortDescriptor = NSSortDescriptor(key: "start", ascending: true)
+				let itiSortDescriptors = [itiSortDescriptor]
+				itiFetchRequest.sortDescriptors = itiSortDescriptors
+				itiFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
+				do {
+					let itiSearchResults = try context.fetch(itiFetchRequest)
+					if itiSearchResults.count == 0{
+						NSLog(":FUTUREACTIVITY:DEBUG: No itinerary for activity \(id)")
+						self.itineraryContainer.isHidden = true
+					}
+					else{
+					
+						var row: RowItinerary
+						var count = 0
+						var itiId: Int
+						var itiTitle: String
+						var itiText: String
+						var itiPlace: Int
+						var itiStart: NSDate
+						var place: [String]
+					
+						for r in itiSearchResults {
+							count = count + 1
+						
+							// Create a new row
+							row = RowItinerary.init(s: "rowItinerary\(count)", i: count)
+							itiId = r.value(forKey: "id")! as! Int
+							itiTitle = r.value(forKey: "name_\(lang)")! as! String
+							itiText = r.value(forKey: "description_\(lang)")! as! String
+							itiStart = r.value(forKey: "start")! as! NSDate
+							itiPlace = r.value(forKey: "place")! as! Int
+							place = getPlace(place: itiPlace, lang: lang, context: context)
+														
+							row.setTitle(text: itiTitle)
+							row.setText(text: itiText)
+							row.setStart(str: formatTime(date: itiStart))
+							row.setPlace(place: place[0], address: place[1])
+							row.id = id
+						
+							self.itineraryList?.addArrangedSubview(row)
+						}
+						self.itineraryList?.setNeedsLayout()
+						self.itineraryList?.layoutIfNeeded()
+						
+					}
+				}
+				catch {
+					NSLog(":FUTUREACTIVITY:ERROR: Error getting itinerary: \(error)")
+				}
+			}
+		} catch {
+			NSLog(":FUTUREACTIVITYCONTROLLER:ERROR: Error loading past activity: \(error)")
+		}
+	}
+	
+	
+	/**
+	Formats a date to the desired language.
+	:param: text The date.
+	:param: lang Device language (only 'es', 'en', or 'eu').
+	*/
+	func formatDate(date: NSDate, lang: String) -> String{
+		
+		let months_es = ["0index", "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]
+		let months_en = ["0index", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
+		let months_eu = ["0index", "urtarrilaren", "otsailaren", "martxoaren", "abrilaren", "maiatzaren", "ekainaren", "ustailaren", "abustuaren", "irailaren", "urriaren", "azaroaren", "abenduaren"]
+		let days_es = ["0index", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sábado", "Domingo"]
+		let days_en = ["0index", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+		let days_eu = ["0index", "Astelehena", "Asteartea", "Asteazkena", "Osteguna", "Ostirala", "Larumbata", "Igandea"]
+		
+		let calendar = Calendar.current
+		let day = calendar.component(.day, from: date as Date)
+		let month = calendar.component(.month, from: date as Date)
+		let weekday = calendar.component(.weekday, from: date as Date)
+		var strDate = ""
+		
+		switch lang{
+		case "en":
+			
+			var dayNum = ""
+			switch day{
+			case 1:
+				dayNum = "1th"
+				break
+			case 2:
+				dayNum = "2nd"
+				break;
+			case 3:
+				dayNum = "3rd"
+				break;
+			default:
+				dayNum = "\(weekday)th"
+			}
+			
+			strDate = "\(days_en[weekday]), \(months_en[month]) \(dayNum)"
+			break
+		case "eu":
+			strDate = "\(days_eu[weekday]) \(months_eu[month]) \(day)an"
+			break
+		default:
+			strDate = "\(days_es[weekday]) \(day) de \(months_es[month])"
+		}
+		
+		return strDate
+	}
+	
+	
+	/**
+	Extracts the time from a date to a string.
+	:param: text The date.
+	:return: Time, in string format.
+	*/
+	func formatTime(date: NSDate) -> String{
+
+		let calendar = Calendar.current
+		let hour: Int = calendar.component(.hour, from: date as Date)
+		let minute: Int = calendar.component(.minute, from: date as Date)
+		
+		var strTime = ""
+		if minute <= 9{
+			strTime = "\(hour):0\(minute)"
+		}
+		else{
+			strTime = "\(hour):\(minute)"
+		}
+		
+		return strTime
+	}
+	
+	
+	/**
+	Gets info about a place in the device language.
+	:param: place Place id.
+	:param: lang Device language (only 'es', 'en', or 'eu').
+	:param: context Application context.
+	:return: String array. 0-index item contains the place name. The 1-index one contains the address.
+	*/
+	func getPlace(place: Int, lang: String, context: NSManagedObjectContext) -> [String]{
+		var placeName = ""
+		var placeAddress = ""
+		let fetchRequest: NSFetchRequest<Place> = Place.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", place)
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			let r: NSManagedObject = searchResults[0]
+			placeName = r.value(forKey: "name_\(lang)")! as! String
+			placeAddress = r.value(forKey: "address_\(lang)")! as! String
+		}
+		catch{
+			NSLog(":FUTUREACTIVITY:ERROR: Error getting infor about place \(place): \(error)")
+		}
+		return [placeName, placeAddress]
+	}
+	
+	
+	/**
+	Gets the device language. The only recognized languages are Spanish, English and Basque.
+	If the device has another language, Spanish will be selected by default.
+	:return: Two-letter language code.
+	*/
+	func getLanguage() -> String{
+		let pre = NSLocale.preferredLanguages[0].subStr(start: 0, end: 1)
+		if(pre == "es" || pre == "en" || pre == "eu"){
+			return pre
+		}
+		else{
+			return "es"
+		}
+	}
+	
+}
+

+ 1 - 3
app/GalleryView.swift

@@ -73,7 +73,7 @@ class GalleryView: UIView {
 		let lang : String = getLanguage()
 		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
 		let fetchRequest: NSFetchRequest<Album> = Album.fetchRequest()
-		let sortDescriptor = NSSortDescriptor(key: "time", ascending: false)
+		let sortDescriptor = NSSortDescriptor(key: "id", ascending: false)
 		let sortDescriptors = [sortDescriptor]
 		fetchRequest.sortDescriptors = sortDescriptors
 		
@@ -164,7 +164,6 @@ class GalleryView: UIView {
 	*/
 	func openAlbum(_ sender:UITapGestureRecognizer? = nil){
 		let id = (sender?.view as! RowGallery).id
-		NSLog(":GALLERY:DEBUG: getting delegate and showing album \(id).")
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		delegate.controller?.showAlbum(id: id)
 	}
@@ -190,7 +189,6 @@ class GalleryView: UIView {
 	Handles the click events to open albums.
 	*/
 	func setUpRowsTapRecognizers(){
-		NSLog(":GALLERY:DEBUG: Setting up tap recognizers")
 		for row in self.rows{
 			let tapRecognizer = UITapGestureRecognizer(target: row, action: #selector(openAlbum(_:)))
 			row.isUserInteractionEnabled = true

+ 3 - 3
app/GalleryView.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -24,7 +24,7 @@
                 <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aoy-Mh-gpR">
                     <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                     <subviews>
-                        <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" misplaced="YES" axis="vertical" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="ULw-PH-L95">
+                        <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="ULw-PH-L95">
                             <rect key="frame" x="0.0" y="0.0" width="375" height="3000"/>
                             <subviews>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3TY-0K-6q1" customClass="Section" customModule="app">

+ 271 - 64
app/HomeView.swift

@@ -26,14 +26,15 @@ import UIKit
  */
 class HomeView: UIView {
 	
-	//The main scroll view.
+	// Outlets
 	@IBOutlet weak var scrollView: UIScrollView!
-	
-	//The container of the view.
 	@IBOutlet weak var container: UIView!
+	@IBOutlet weak var locationMessage: UILabel!
+	@IBOutlet weak var lablancaImage: UIImageView!
+	@IBOutlet weak var lablancaText: UILabel!
 	
 	//Each of the sections of the view.
-	@IBOutlet weak var locationSection: Section!
+	@IBOutlet weak var locationSection: UIView!
 	@IBOutlet weak var lablancaSection: Section!
 	@IBOutlet weak var futureActivitiesSection: Section!
 	@IBOutlet weak var blogSection: Section!
@@ -41,15 +42,33 @@ class HomeView: UIView {
 	@IBOutlet weak var pastActivitiesSection: Section!
 	@IBOutlet weak var socialSection: Section!
 	
+	var moc: NSManagedObjectContext? = nil
+	var delegate: AppDelegate? = nil
+	var lang: String? = nil
+	var locationTimer: Timer? = nil
+	var controller: ViewController
+	var storyboard: UIStoryboard
+	
+	
+	/**
+	Default constructor for the storyboard.
+	:param: frame View frame.
+	*/
 	override init(frame: CGRect){
+		self.storyboard = UIStoryboard(name: "Main", bundle: nil)
+		self.controller = storyboard.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
 		super.init(frame: frame)
+		
 	}
 	
+	
 	/**
 	 Run when the view is started.
 	*/
 	required init?(coder aDecoder: NSCoder) {
 		
+		self.storyboard = UIStoryboard(name: "Main", bundle: nil)
+		self.controller = storyboard.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
 		super.init(coder: aDecoder)
 		
 		//Load the contents of the HomeView.xib file.
@@ -57,45 +76,47 @@ class HomeView: UIView {
 		self.addSubview(container)
 		container.frame = self.bounds
 		
-
-		
 		//Set titles for each section
-		locationSection.setTitle(text: "Encuentranos")
-		lablancaSection.setTitle(text: "La Blanca")
-		futureActivitiesSection.setTitle(text: "Proximas actividades")
-		blogSection.setTitle(text: "Ultimos posts")
-		gallerySection.setTitle(text: "Ultimas fotos")
-		pastActivitiesSection.setTitle(text: "Ultimas actividades")
-		socialSection.setTitle(text: "Siguenos")
+		futureActivitiesSection.setTitle(text: "Próximas actividades")
+		blogSection.setTitle(text: "Últimos posts")
+		gallerySection.setTitle(text: "Últimas fotos")
+		pastActivitiesSection.setTitle(text: "Últimas actividades")
+		socialSection.setTitle(text: "Síguenos")
 		
 		//Get info to populate sections
-		let moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
-		
-		let appDelegate = UIApplication.shared.delegate as! AppDelegate
-		moc.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
-		let lang : String = getLanguage()
+		self.moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		
-		//Populate sections
-		setUpPastActivities(context: moc, delegate: appDelegate, lang: lang, parent: pastActivitiesSection.getContentStack())
-		setUpBlog(context: moc, delegate: appDelegate, lang: lang, parent: blogSection.getContentStack())
-		setUpFutureActivities(context: moc, delegate: appDelegate, lang: lang, parent: futureActivitiesSection.getContentStack())
-		setUpSocial(parent: socialSection.getContentStack())
-		setUpGallery(context: moc, delegate: appDelegate, parent: gallerySection.getContentStack())
+		self.delegate = UIApplication.shared.delegate as! AppDelegate
+		self.moc?.persistentStoreCoordinator = self.delegate?.persistentStoreCoordinator
+		self.lang = getLanguage()
 		
 		
-		pastActivitiesSection.expandSection()
+		// Populate section.
+		populate()
 		
 		
-		//Always at the end: update scrollview
-		var h: Int = 0
-		for view in scrollView.subviews {
-			//contentRect = contentRect.union(view.frame);
-			h = h + Int(view.frame.height) + 30 //Why 30?
-		}
-		// TODO: Calculate at the end
-		self.scrollView.contentSize.height = 1300// CGFloat(h);
+		// Special case: Location
+		// Set up once and start and periodically witha  timer.
+		setUpLocation()
+		Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(setUpLocation), userInfo: nil, repeats: true)
+	}
+	
+	
+	/**
+	Sets all the sections up
+	*/
+	func populate(){
+	
+		//Populate sections
+		setUpPastActivities(context: self.moc!, delegate: self.delegate!, lang: self.lang!, parent: self.pastActivitiesSection.getContentStack())
+		setUpBlog(context: self.moc!, delegate: self.delegate!, lang: self.lang!, parent: self.blogSection.getContentStack())
+		setUpFutureActivities(context: self.moc!, delegate: self.delegate!, lang: self.lang!, parent: self.futureActivitiesSection.getContentStack())
+		setUpSocial(parent: self.socialSection.getContentStack())
+		setUpGallery(context: self.moc!, delegate: self.delegate!, parent: self.gallerySection.getContentStack())
+		setUpLablanca(context: self.moc!, delegate: self.delegate!, lang: self.lang!)
 	}
 	
+	
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	If the device has another language, Spanish will be selected by default.
@@ -112,8 +133,115 @@ class HomeView: UIView {
 	}
 	
 	
+	/**
+	Sets up the location section.
+	If no location is reported, it hiddes the section.
+	*/
+	func setUpLocation(){
+		// TODO: Also set up tap recognizer.
+		let defaults = UserDefaults.standard
+		if (defaults.value(forKey: "GMLocLat") != nil && defaults.value(forKey: "GMLocLon") != nil){
+			let lat = defaults.value(forKey: "GMLocLat") as! Double
+			let lon = defaults.value(forKey: "GMLocLon") as! Double
+			let time = defaults.value(forKey: "GMLocTime") as! Date
+			let cTime = Date()
+			let minutes = Calendar.current.dateComponents([.minute], from: time, to: cTime).minute
+			if (minutes! < 30){
+				self.locationSection.isHidden = false
+				
+				// Set tap recognizer.
+				let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (HomeView.openLocation (_:)))
+				tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+				self.locationSection.addGestureRecognizer(tapRecognizer)
+				
+				let location = self.controller.getLocation()
+				if location != nil {
+					let d: Int = calculateDistance(lat1: location.latitude, lon1: location.longitude, lat2: lat, lon2: lon)
+					
+					if d <= 1000 {
+						self.locationMessage.text = "¡Gasteizko Margolariak está por ahí! A \(d) metros de ti."
+					}
+					else{
+						self.locationMessage.text = "¡Gasteizko Margolariak está por ahí! A \(Int(d/1000)) kilómetros de ti."
+					}
+				}
+				else{
+					self.locationMessage.text = "¡Gasteizko Margolariak está por ahí!"
+				}
+			}
+			else{
+				self.locationSection.isHidden = true
+			}
+		}
+		else{
+			self.locationSection.isHidden = true
+		}
+	}
+	
+	
+	/**
+	Sets up the La Blanca secction.
+	Hiddes it if no current festivals.
+	:param: context App context.
+	:param: delegate App delegate.
+	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
+	*/
+	func setUpLablanca(context : NSManagedObjectContext, delegate: AppDelegate, lang: String){
+		
+		let defaults = UserDefaults.standard
+		if (defaults.value(forKey: "festivals") != nil){
+			let festivals = defaults.value(forKey: "festivals") as! Int
+			if festivals == 1{
+				
+				// Set tap recognizer
+				let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (HomeView.openLablanca (_:)))
+				tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+				self.lablancaSection.addGestureRecognizer(tapRecognizer)
+				
+				// TODO: Get current year
+				let year = 2017
+				
+				// Get info about festivals
+				let fetchRequest: NSFetchRequest<Festival> = Festival.fetchRequest()
+				fetchRequest.predicate = NSPredicate(format: "year = %i", year)
+				
+				do {
+					
+					// Get info from festivals
+					let searchResults = try context.fetch(fetchRequest)
+					
+					if searchResults.count > 0 {
+						let r = searchResults[0]
+						
+						// Set image and text
+						self.lablancaText.text = (r.value(forKey: "text_\(lang)") as! String?)?.decode().stripHtml()
+						let filename: String = r.value(forKey: "img") as! String
+						if (filename == ""){
+							// Hide the imageview
+							self.lablancaImage.isHidden = true;
+						}
+						else{
+							let path = "img/blog/thumb/\(filename)"
+							self.lablancaImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+						}
+					}
+					
+				}
+				catch {
+					NSLog(":LABLANCA:ERROR: Error getting festivals info: \(error)")
+				}
+			}
+			else{
+				self.lablancaSection.isHidden = true
+			}
+		}
+	}
+	
+	
 	/**
 	Sets up the future activities section.
+	If none, it hiddes the section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: parent Stack view to load the rows in.
@@ -136,40 +264,46 @@ class HomeView: UIView {
 			var text: String
 			var image: String
 			
-			for r in searchResults as [NSManagedObject] {
-				count = count + 1
+			if searchResults.count == 0{
+				self.futureActivitiesSection.isHidden = true
+			}
+			else{
+				for r in searchResults as [NSManagedObject] {
+					count = count + 1
 				
-				//Create a new row
-				row = RowHomeFutureActivities.init(s: "rowHomeFutureActivities\(count)", i: count)
-				id = r.value(forKey: "id")! as! Int
-				title = r.value(forKey: "title_\(lang)")! as! String
-				text = r.value(forKey: "text_\(lang)")! as! String
-				row.setTitle(text: title)
-				row.setText(text: text.decode())
+					//Create a new row
+					row = RowHomeFutureActivities.init(s: "rowHomeFutureActivities\(count)", i: count)
+					id = r.value(forKey: "id")! as! Int
+					title = r.value(forKey: "title_\(lang)")! as! String
+					text = r.value(forKey: "text_\(lang)")! as! String
+					row.setTitle(text: title)
+					row.setText(text: text)
+					row.id = id
 				
-				// Get main image
-				image = ""
-				let imgFetchRequest: NSFetchRequest<Activity_image> = Activity_image.fetchRequest()
-				let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
-				let imgSortDescriptors = [imgSortDescriptor]
-				imgFetchRequest.sortDescriptors = imgSortDescriptors
-				imgFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
-				imgFetchRequest.fetchLimit = 1
-				do{
-					let imgSearchResults = try context.fetch(imgFetchRequest)
-					for imgR in imgSearchResults as [NSManagedObject]{
-						image = imgR.value(forKey: "image")! as! String
-						row.setImage(filename: image)
+					// Get main image
+					image = ""
+					let imgFetchRequest: NSFetchRequest<Activity_image> = Activity_image.fetchRequest()
+					let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
+					let imgSortDescriptors = [imgSortDescriptor]
+					imgFetchRequest.sortDescriptors = imgSortDescriptors
+					imgFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
+					imgFetchRequest.fetchLimit = 1
+					do{
+						let imgSearchResults = try context.fetch(imgFetchRequest)
+						for imgR in imgSearchResults as [NSManagedObject]{
+							image = imgR.value(forKey: "image")! as! String
+							row.setImage(filename: image)
+						}
+					}
+					catch {
+						NSLog(":HOME:ERROR: Error getting image for activity \(id): \(error)")
 					}
-				}
-				catch {
-					NSLog(":HOME:ERROR: Error getting image for activity \(id): \(error)")
-				}
-				
-				parent.addArrangedSubview(row)
 				
+					parent.addArrangedSubview(row)
+				}
 			}
-		} catch {
+		}
+		catch {
 			NSLog(":HOME:ERROR: Error loading future activities: \(error)")
 		}
 	}
@@ -177,6 +311,7 @@ class HomeView: UIView {
 	
 	/**
 	Sets up the blog section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: parent Stack view to load the rows in.
@@ -245,6 +380,7 @@ class HomeView: UIView {
 	
 	/**
 	Sets up the past activities section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: parent Stack view to load the rows in.
@@ -279,6 +415,7 @@ class HomeView: UIView {
 				
 				row.setTitle(text: title)
 				row.setText(text: text)
+				row.id = id
 				
 				// Get main image
 				image = ""
@@ -306,8 +443,10 @@ class HomeView: UIView {
 		}
 	}
 	
+	
 	/**
 	Sets up the future activities section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: parent Stack view to load the rows in.
 	*/
@@ -330,13 +469,30 @@ class HomeView: UIView {
 	
 			var id: Int
 			var image: String
+			var albumId: Int
 			var i = 0
 			for r in searchResults as [NSManagedObject] {
 				
 				image = r.value(forKey: "file")! as! String
+				id = r.value(forKey: "id")! as! Int
+				
+				// TODO Get album id
+				// Get album title
+				let albumFetchRequest: NSFetchRequest<Photo_album> = Photo_album.fetchRequest()
+				albumFetchRequest.predicate = NSPredicate(format: "photo = %i", id)
+				do {
+					let results = try context.fetch(albumFetchRequest)
+					let r = results[0]
+					albumId = r.value(forKey: "album")! as! Int
+					row.albumIds[i] = albumId
+				}
+				catch {
+					NSLog(":GALLERYCONTROLLER:ERROR: Error getting album info: \(error)")
+				}
+				
 				row.setImage(idx: i, filename: image)
+				row.photoIds[i] = id
 				
-				//TODO Set click listener
 				i = i + 1
 			}
 		}
@@ -358,12 +514,63 @@ class HomeView: UIView {
 	}
 	
 	
+	/**
+	Converts degrees to radians.
+	:params: degrees Angle in degrees.
+	:return: Angle in radians.
+	*/
+	func degreesToRadians(degrees: Double) -> Double {
+		return degrees * Double.pi / 180;
+	}
+	
+	
+	/**
+	Calculates the distance between two coordinates.
+	:param: lat1 Latitude of the first coordinate.
+	:param: lon1 Longitude of the first coordinate.
+	:param: lat2 Latitude of the second coordinate.
+	:param: lon2 Longitude of the second coordinate.
+	:return: Distance between the points, in meters.
+	*/
+	func calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Int {
+		let eRadius: Double = 6371
+		
+		let dLat: Double = degreesToRadians(degrees: lat2-lat1)
+		let dLon: Double = degreesToRadians(degrees: lon2-lon1)
+		
+		let l1: Double = degreesToRadians(degrees: lat1)
+		let l2: Double = degreesToRadians(degrees: lat2)
+		
+		let a: Double = sin(dLat/2) * sin(dLat/2) + sin(dLon/2) * sin(dLon/2) * cos(l1) * cos(l2)
+		let c: Double = 2 * atan2(sqrt(a), sqrt(1-a))
+		let m: Double = eRadius * c * 1000
+		return Int(m)
+	}
+	
+	
 	/**
 	Opens a post.
 	*/
 	func openPost(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":HOME:DEBUG: Getting delegate and showing post.")
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		delegate.controller?.showPost(id: (sender?.view as! RowHomeBlog).id)
 	}
+	
+	
+	/**
+	Opens the La Blanca section when tapping the section.
+	*/
+	func openLablanca(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showComponent(selected: 2)
+	}
+	
+	
+	/**
+	Opens the Location section when tapping the section.
+	*/
+	func openLocation(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showComponent(selected: 1)
+	}
 }

+ 202 - 11
app/HomeView.xib

@@ -15,7 +15,10 @@
                 <outlet property="container" destination="iN0-l3-epB" id="cfT-rm-jA0"/>
                 <outlet property="futureActivitiesSection" destination="FQo-nm-4Mo" id="TAU-5k-Sc5"/>
                 <outlet property="gallerySection" destination="v6A-Ya-esA" id="TPS-Ut-DK1"/>
+                <outlet property="lablancaImage" destination="gkF-He-baV" id="pCZ-g7-TMf"/>
                 <outlet property="lablancaSection" destination="9nu-j1-wGI" id="3eu-wW-jM4"/>
+                <outlet property="lablancaText" destination="YsW-Bq-7gd" id="Oce-9m-0Io"/>
+                <outlet property="locationMessage" destination="JXP-eW-H8r" id="fic-KB-N90"/>
                 <outlet property="locationSection" destination="Ljm-NP-c4e" id="bCD-0M-vqb"/>
                 <outlet property="pastActivitiesSection" destination="fZk-r1-Tca" id="U8D-Sh-TpR"/>
                 <outlet property="scrollView" destination="Poy-ba-9jX" id="PyU-Nb-kOS"/>
@@ -31,25 +34,203 @@
                     <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                     <subviews>
                         <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="gOz-rr-CeQ">
-                            <rect key="frame" x="0.0" y="0.0" width="320" height="780"/>
+                            <rect key="frame" x="0.0" y="0.0" width="320" height="1144"/>
                             <subviews>
-                                <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ljm-NP-c4e" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="0.0" width="320" height="50"/>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ljm-NP-c4e">
+                                    <rect key="frame" x="0.0" y="0.0" width="320" height="157"/>
+                                    <subviews>
+                                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZvF-yV-TQm" userLabel="LocationContainer">
+                                            <rect key="frame" x="10" y="9.5" width="300" height="137"/>
+                                            <subviews>
+                                                <textView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Encuéntranos" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="xcx-xq-doc">
+                                                    <rect key="frame" x="0.0" y="0.0" width="300" height="27"/>
+                                                    <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                    <constraints>
+                                                        <constraint firstAttribute="height" constant="27" id="GLS-4B-sku"/>
+                                                    </constraints>
+                                                    <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                                                    <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
+                                                </textView>
+                                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qqh-sw-MbH" userLabel="Entry">
+                                                    <rect key="frame" x="10" y="37" width="280" height="90"/>
+                                                    <subviews>
+                                                        <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PinpointGM" translatesAutoresizingMaskIntoConstraints="NO" id="HgA-hw-nFb">
+                                                            <rect key="frame" x="10" y="19.5" width="40" height="50"/>
+                                                            <constraints>
+                                                                <constraint firstAttribute="width" constant="40" id="LL7-qW-58P"/>
+                                                                <constraint firstAttribute="height" constant="50" id="Ye3-b8-p9O"/>
+                                                            </constraints>
+                                                        </imageView>
+                                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="¡Gasteizko Margolariak está por ahí!" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JXP-eW-H8r" userLabel="Text">
+                                                            <rect key="frame" x="65" y="10" width="205" height="70"/>
+                                                            <constraints>
+                                                                <constraint firstAttribute="height" constant="70" id="EF3-nL-xJE"/>
+                                                            </constraints>
+                                                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                                            <nil key="textColor"/>
+                                                            <nil key="highlightedColor"/>
+                                                        </label>
+                                                    </subviews>
+                                                    <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                    <constraints>
+                                                        <constraint firstItem="HgA-hw-nFb" firstAttribute="leading" secondItem="qqh-sw-MbH" secondAttribute="leading" constant="10" id="K2O-i3-xXX"/>
+                                                        <constraint firstItem="HgA-hw-nFb" firstAttribute="centerY" secondItem="qqh-sw-MbH" secondAttribute="centerY" id="KM1-Yd-1CZ"/>
+                                                        <constraint firstItem="JXP-eW-H8r" firstAttribute="height" secondItem="qqh-sw-MbH" secondAttribute="height" constant="-20" id="KPu-k0-bCe"/>
+                                                        <constraint firstItem="JXP-eW-H8r" firstAttribute="leading" secondItem="HgA-hw-nFb" secondAttribute="trailing" constant="15" id="aTU-Xn-urr"/>
+                                                        <constraint firstAttribute="trailing" secondItem="JXP-eW-H8r" secondAttribute="trailing" constant="10" id="gOz-7L-IQ6"/>
+                                                        <constraint firstItem="JXP-eW-H8r" firstAttribute="centerY" secondItem="qqh-sw-MbH" secondAttribute="centerY" id="yEV-Vl-cMY"/>
+                                                    </constraints>
+                                                    <userDefinedRuntimeAttributes>
+                                                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                            <color key="value" red="0.42745098040000001" green="0.41176470590000003" blue="0.56470588239999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                        </userDefinedRuntimeAttribute>
+                                                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                            <real key="value" value="1"/>
+                                                        </userDefinedRuntimeAttribute>
+                                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                            <real key="value" value="3"/>
+                                                        </userDefinedRuntimeAttribute>
+                                                    </userDefinedRuntimeAttributes>
+                                                </view>
+                                            </subviews>
+                                            <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                            <constraints>
+                                                <constraint firstItem="xcx-xq-doc" firstAttribute="top" secondItem="ZvF-yV-TQm" secondAttribute="top" id="1Hp-p6-gXS"/>
+                                                <constraint firstItem="qqh-sw-MbH" firstAttribute="width" secondItem="ZvF-yV-TQm" secondAttribute="width" constant="-20" id="FS5-DP-F6y"/>
+                                                <constraint firstItem="xcx-xq-doc" firstAttribute="centerX" secondItem="ZvF-yV-TQm" secondAttribute="centerX" id="Xq6-tK-aZf"/>
+                                                <constraint firstAttribute="bottom" secondItem="qqh-sw-MbH" secondAttribute="bottom" constant="10" id="gAr-Ar-e57"/>
+                                                <constraint firstItem="qqh-sw-MbH" firstAttribute="top" secondItem="xcx-xq-doc" secondAttribute="bottom" constant="10" id="kOJ-wR-oGj"/>
+                                                <constraint firstItem="xcx-xq-doc" firstAttribute="width" secondItem="ZvF-yV-TQm" secondAttribute="width" id="ldg-HY-G9g"/>
+                                                <constraint firstItem="qqh-sw-MbH" firstAttribute="centerX" secondItem="ZvF-yV-TQm" secondAttribute="centerX" id="llP-Al-gqL"/>
+                                            </constraints>
+                                            <userDefinedRuntimeAttributes>
+                                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                    <color key="value" red="0.0" green="0.0" blue="0.066666666669999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                </userDefinedRuntimeAttribute>
+                                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                    <real key="value" value="1"/>
+                                                </userDefinedRuntimeAttribute>
+                                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                    <real key="value" value="8"/>
+                                                </userDefinedRuntimeAttribute>
+                                            </userDefinedRuntimeAttributes>
+                                        </view>
+                                    </subviews>
+                                    <constraints>
+                                        <constraint firstItem="ZvF-yV-TQm" firstAttribute="width" secondItem="Ljm-NP-c4e" secondAttribute="width" constant="-20" id="A3M-1s-2gK"/>
+                                        <constraint firstItem="ZvF-yV-TQm" firstAttribute="centerY" secondItem="Ljm-NP-c4e" secondAttribute="centerY" id="ZQZ-8v-OrW"/>
+                                        <constraint firstItem="ZvF-yV-TQm" firstAttribute="centerX" secondItem="Ljm-NP-c4e" secondAttribute="centerX" id="jhS-6W-MWI"/>
+                                        <constraint firstItem="ZvF-yV-TQm" firstAttribute="height" secondItem="Ljm-NP-c4e" secondAttribute="height" constant="-20" id="nie-wn-NTt"/>
+                                    </constraints>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                            <real key="value" value="0.0"/>
+                                        </userDefinedRuntimeAttribute>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                            <real key="value" value="0.0"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
                                 </view>
-                                <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9nu-j1-wGI" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="60" width="320" height="50"/>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9nu-j1-wGI">
+                                    <rect key="frame" x="0.0" y="167" width="320" height="157"/>
+                                    <subviews>
+                                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RyS-ln-grn" userLabel="LablancaContainer">
+                                            <rect key="frame" x="9.5" y="10" width="300" height="137"/>
+                                            <subviews>
+                                                <textView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="La Blanca" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="ftX-qb-57S">
+                                                    <rect key="frame" x="0.0" y="0.0" width="300" height="27"/>
+                                                    <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                    <constraints>
+                                                        <constraint firstAttribute="height" constant="27" id="oV8-jh-6e5"/>
+                                                    </constraints>
+                                                    <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                                                    <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
+                                                </textView>
+                                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fBq-qg-fz9" userLabel="Entry">
+                                                    <rect key="frame" x="10" y="37" width="280" height="90"/>
+                                                    <subviews>
+                                                        <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="gkF-He-baV">
+                                                            <rect key="frame" x="10" y="9.5" width="70" height="70"/>
+                                                            <constraints>
+                                                                <constraint firstAttribute="width" constant="70" id="ChM-hX-OnO"/>
+                                                                <constraint firstAttribute="height" constant="70" id="hNg-Je-ufU"/>
+                                                            </constraints>
+                                                        </imageView>
+                                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="¡Gasteizko Margolariak está por ahí!" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YsW-Bq-7gd" userLabel="Text">
+                                                            <rect key="frame" x="95" y="10" width="175" height="70"/>
+                                                            <constraints>
+                                                                <constraint firstAttribute="height" constant="70" id="Txi-or-Pra"/>
+                                                            </constraints>
+                                                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                                            <nil key="textColor"/>
+                                                            <nil key="highlightedColor"/>
+                                                        </label>
+                                                    </subviews>
+                                                    <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                    <constraints>
+                                                        <constraint firstItem="gkF-He-baV" firstAttribute="centerY" secondItem="fBq-qg-fz9" secondAttribute="centerY" id="Pi9-t0-oOa"/>
+                                                        <constraint firstAttribute="trailing" secondItem="YsW-Bq-7gd" secondAttribute="trailing" constant="10" id="VAj-dj-MLd"/>
+                                                        <constraint firstItem="YsW-Bq-7gd" firstAttribute="centerY" secondItem="fBq-qg-fz9" secondAttribute="centerY" id="jjq-4v-b9d"/>
+                                                        <constraint firstItem="gkF-He-baV" firstAttribute="leading" secondItem="fBq-qg-fz9" secondAttribute="leading" constant="10" id="jtF-UZ-btH"/>
+                                                        <constraint firstItem="YsW-Bq-7gd" firstAttribute="height" secondItem="fBq-qg-fz9" secondAttribute="height" constant="-20" id="uVT-PP-R5k"/>
+                                                        <constraint firstItem="YsW-Bq-7gd" firstAttribute="leading" secondItem="gkF-He-baV" secondAttribute="trailing" constant="15" id="zdn-rO-ngp"/>
+                                                    </constraints>
+                                                    <userDefinedRuntimeAttributes>
+                                                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                            <color key="value" red="0.42745098040000001" green="0.41176470590000003" blue="0.56470588239999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                        </userDefinedRuntimeAttribute>
+                                                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                            <real key="value" value="1"/>
+                                                        </userDefinedRuntimeAttribute>
+                                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                            <real key="value" value="3"/>
+                                                        </userDefinedRuntimeAttribute>
+                                                    </userDefinedRuntimeAttributes>
+                                                </view>
+                                            </subviews>
+                                            <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                            <constraints>
+                                                <constraint firstItem="fBq-qg-fz9" firstAttribute="centerX" secondItem="RyS-ln-grn" secondAttribute="centerX" id="AqL-EH-Tjq"/>
+                                                <constraint firstItem="ftX-qb-57S" firstAttribute="centerX" secondItem="RyS-ln-grn" secondAttribute="centerX" id="FJ5-wt-uIa"/>
+                                                <constraint firstItem="fBq-qg-fz9" firstAttribute="top" secondItem="ftX-qb-57S" secondAttribute="bottom" constant="10" id="G4N-Ok-LJL"/>
+                                                <constraint firstItem="ftX-qb-57S" firstAttribute="top" secondItem="RyS-ln-grn" secondAttribute="top" id="SEd-7H-WX5"/>
+                                                <constraint firstItem="fBq-qg-fz9" firstAttribute="width" secondItem="RyS-ln-grn" secondAttribute="width" constant="-20" id="ay3-po-Etb"/>
+                                                <constraint firstItem="ftX-qb-57S" firstAttribute="width" secondItem="RyS-ln-grn" secondAttribute="width" id="kFI-rY-JTv"/>
+                                                <constraint firstAttribute="bottom" secondItem="fBq-qg-fz9" secondAttribute="bottom" constant="10" id="vka-uG-rAI"/>
+                                            </constraints>
+                                            <userDefinedRuntimeAttributes>
+                                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                    <color key="value" red="0.0" green="0.0" blue="0.066666666669999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                </userDefinedRuntimeAttribute>
+                                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                    <real key="value" value="1"/>
+                                                </userDefinedRuntimeAttribute>
+                                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                    <real key="value" value="8"/>
+                                                </userDefinedRuntimeAttribute>
+                                            </userDefinedRuntimeAttributes>
+                                        </view>
+                                    </subviews>
+                                    <constraints>
+                                        <constraint firstItem="RyS-ln-grn" firstAttribute="height" secondItem="9nu-j1-wGI" secondAttribute="height" constant="-20" id="IVY-CC-5KF"/>
+                                        <constraint firstItem="RyS-ln-grn" firstAttribute="width" secondItem="9nu-j1-wGI" secondAttribute="width" constant="-20" id="Qen-Pe-Hql"/>
+                                        <constraint firstItem="RyS-ln-grn" firstAttribute="centerY" secondItem="9nu-j1-wGI" secondAttribute="centerY" id="TnC-Qy-tMy"/>
+                                        <constraint firstItem="RyS-ln-grn" firstAttribute="centerX" secondItem="9nu-j1-wGI" secondAttribute="centerX" id="wGj-v9-Ljw"/>
+                                    </constraints>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FQo-nm-4Mo" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="120" width="320" height="50"/>
+                                    <rect key="frame" x="0.0" y="334" width="320" height="50"/>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uHa-Mu-U68" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="180" width="320" height="50"/>
+                                    <rect key="frame" x="0.0" y="394" width="320" height="50"/>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="v6A-Ya-esA" customClass="Section" customModule="app" customModuleProvider="target">
-                                    <rect key="frame" x="0.0" y="240" width="320" height="50"/>
+                                    <rect key="frame" x="0.0" y="454" width="320" height="200"/>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fZk-r1-Tca" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="300" width="320" height="350"/>
+                                    <rect key="frame" x="0.0" y="664" width="320" height="350"/>
                                     <userDefinedRuntimeAttributes>
                                         <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
                                             <real key="value" value="0.0"/>
@@ -57,7 +238,7 @@
                                     </userDefinedRuntimeAttributes>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dgk-s8-xje" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="660" width="320" height="120"/>
+                                    <rect key="frame" x="0.0" y="1024" width="320" height="120"/>
                                 </view>
                             </subviews>
                             <color key="backgroundColor" red="1" green="1" blue="0.42787000868055558" alpha="1" colorSpace="calibratedRGB"/>
@@ -73,6 +254,7 @@
                                 <constraint firstItem="FQo-nm-4Mo" firstAttribute="centerX" secondItem="gOz-rr-CeQ" secondAttribute="centerX" id="aWZ-5w-1ke"/>
                                 <constraint firstItem="FQo-nm-4Mo" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="azo-MK-F5R"/>
                                 <constraint firstItem="uHa-Mu-U68" firstAttribute="centerX" secondItem="gOz-rr-CeQ" secondAttribute="centerX" id="i5O-1b-eCi"/>
+                                <constraint firstAttribute="bottom" secondItem="dgk-s8-xje" secondAttribute="bottom" id="lUo-Rq-bAi"/>
                                 <constraint firstItem="uHa-Mu-U68" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="ljo-DJ-9M1"/>
                                 <constraint firstItem="Ljm-NP-c4e" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="s8R-dV-4ju"/>
                                 <constraint firstItem="9nu-j1-wGI" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="v1C-hQ-R98"/>
@@ -80,6 +262,8 @@
                         </stackView>
                     </subviews>
                     <constraints>
+                        <constraint firstAttribute="bottom" secondItem="gOz-rr-CeQ" secondAttribute="bottom" id="1aX-69-rIr"/>
+                        <constraint firstAttribute="trailing" secondItem="gOz-rr-CeQ" secondAttribute="trailing" id="53K-6k-eT3"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="width" secondItem="Poy-ba-9jX" secondAttribute="width" id="Gw0-jw-ldE"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="top" secondItem="Poy-ba-9jX" secondAttribute="top" id="Hmx-ri-LqQ"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="leading" secondItem="Poy-ba-9jX" secondAttribute="leading" id="k5u-hr-4th"/>
@@ -89,9 +273,16 @@
             <color key="backgroundColor" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
             <constraints>
                 <constraint firstItem="Poy-ba-9jX" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="9SN-Tf-raC"/>
-                <constraint firstItem="Poy-ba-9jX" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="TFG-sf-YY4"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Gar-uI-abW"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="gDS-mJ-c25"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="k8Z-RL-IVb"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="xvC-vv-ebb"/>
             </constraints>
             <point key="canvasLocation" x="26" y="52"/>
         </view>
     </objects>
+    <resources>
+        <image name="PhotoPlaceholder" width="170" height="108"/>
+        <image name="PinpointGM" width="15" height="20"/>
+    </resources>
 </document>

+ 6 - 2
app/Info.plist

@@ -17,13 +17,17 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>0.0.5</string>
+	<string>0.1.1</string>
 	<key>CFBundleVersion</key>
-	<string>6</string>
+	<string>11</string>
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
 	<key>NSLocationWhenInUseUsageDescription</key>
 	<string>Permitiendo acceso a tu ubicación, podrás conocer la distancia a la cuadrilla y a determinados eventos.</string>
+	<key>UIBackgroundModes</key>
+	<array>
+		<string>fetch</string>
+	</array>
 	<key>UILaunchStoryboardName</key>
 	<string>LaunchScreen</string>
 	<key>UIMainStoryboardFile</key>

+ 0 - 6
app/LablancaView.swift

@@ -146,8 +146,6 @@ class LablancaView: UIView {
 			// Get info from festivals
 			let offerSearchResults = try context.fetch(offerFetchRequest)
 			
-			NSLog(":LABLANCA:DEBUG: \(offerSearchResults.count) offes found.")
-
 			var row: RowLablancaOffer
 			var count: Int = 0
 
@@ -245,10 +243,8 @@ class LablancaView: UIView {
 	:param: sender The view that triggered the event.
 	*/
 	func openSchedule(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":LABLANCA:DEBUG: Getting delegate and showing schedule.")
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		delegate.controller?.showSchedule(margolari: false)
-		NSLog(":LABLANCA:DEBUG: Schedule should be shown.")
 	}
 
 
@@ -257,10 +253,8 @@ class LablancaView: UIView {
 	:param: sender The view that triggered the event.
 	*/
 	func openGMSchedule(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":LABLANCA:DEBUG: Getting delegate and showing GM schedule.")
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		delegate.controller?.showSchedule(margolari: true)
-		NSLog(":LABLANCA:DEBUG: GM schedule should be shown.")
 	}
 
 	

+ 1 - 6
app/LocationView.swift

@@ -92,7 +92,7 @@ class LocationView: UIView {
 	Get new location
 	*/
 	func getNewLocation(){
-		NSLog(":LOCATION:DEBUG: Setting marker.")
+		NSLog(":LOCATION:LOG: Recalculating location.")
 		let defaults = UserDefaults.standard
 		if (defaults.value(forKey: "GMLocLat") != nil && defaults.value(forKey: "GMLocLon") != nil){
 			let lat = defaults.value(forKey: "GMLocLat") as! Double
@@ -110,12 +110,10 @@ class LocationView: UIView {
 				marker.title = "Gasteizko Margolariak"
 				//marker.snippet = "Australia"
 				marker.map = self.map
-				NSLog(":LOCATION:DEBUG: Marker set.")
 			
 				let location = self.controller.getLocation()
 				if location != nil {
 					let d: Int = calculateDistance(lat1: location.latitude, lon1: location.longitude, lat2: lat, lon2: lon)
-					NSLog(":LOCATION:LOG: Distance (m): \(d)")
 				
 					if d <= 1000 {
 						self.lbDistance.text = "A \(d) metros de ti."
@@ -132,9 +130,6 @@ class LocationView: UIView {
 				self.lbNo.isHidden = false
 			}
 		}
-		else{
-			NSLog(":LOCATION:DEBUG: No location saved yet.")
-		}
 	}
 
 

+ 223 - 0
app/Notifications.swift

@@ -0,0 +1,223 @@
+// Copyright (C) 2016 Inigo Valentin
+//
+// This file is part of the Gasteizko Margolariak IOS app.
+//
+// The Gasteizko Margolariak IOS app is free software: you can
+// redistribute it and/or modify it under the terms of the
+// GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// The Gasteizko Margolariak IOS app is distributed in the
+// hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with the Gasteizko Margolariak IOS app.
+// If not, see <http://www.gnu.org/licenses/>.
+
+import Foundation
+import CoreData
+import UIKit
+import UserNotifications
+
+/**
+Class to handle server sync.
+*/
+class Notifications{
+	
+	/**
+	Starts the sync process.
+	Always asynchronously.
+	*/
+	init(){
+		let url = buildUrl();
+		notification(url: url)
+	}
+	
+	
+	/**
+	Builds the URL to perform the sync against.
+	:returns: The URL.
+	*/
+	func buildUrl() -> URL{
+		
+		let url = URL(string: "https://margolariak.com/API/v1/notifications.php")
+		
+		return url!
+	}
+	
+	
+	/**
+	Performs an asynchronous sync.
+	It fetches the info from the server and stores as Core Data
+	:param: url The url to sync.
+	*/
+	func notification(url: URL){
+		
+		NSLog(":NOTIFICATION:LOG: Notification fetch started.")
+		
+		//Synchronously get data
+		let task = URLSession.shared.dataTask(with: url) { data, response, error in
+			guard error == nil else {
+				NSLog(":NOTIFICATION:ERROR: Unknown error.")
+				return
+			}
+			guard let data = data else {
+				NSLog(":NOTIFICATION:ERROR: Data is empty.")
+				return
+			}
+			
+			let strData: String = String(data:data, encoding: String.Encoding.utf8)!
+			NSLog(":NOTIFICATION:LOG: Data received: \(strData)")
+			if strData.length > 0{
+				let dataNotification: [String] = self.getData(data: strData)
+				self.saveNotifications(entries: dataNotification)
+			}
+			
+		}
+		
+		task.resume()
+	}
+	
+	
+	/**
+	Extracts notifications from the raw data received.
+	:param: param Received data in JSON format.
+	:return: Array of strings containing the notifications.
+	*/
+	func getData(data: String) -> [String]{
+		
+		//Separate the entries
+		var entries : [String] = data.components(separatedBy: "},{")
+		
+		//Modify the first and the last one to remove bracers
+		entries[0] = entries[0].subStr(start: 1, end: entries[0].length - 1)
+		entries[entries.count - 1] = entries[entries.count - 1].subStr(start: 0, end: entries[entries.count - 1].length - 2)
+		
+		
+		//Return the array
+		return entries
+	}
+	
+	
+	/**
+	Saves the data in the table.
+	:param: entries Array of strings containing the rows of the table, in JSON format.
+	*/
+	func saveNotifications(entries : [String]){
+		
+		let dateFormatter = DateFormatter()
+		dateFormatter.timeZone = TimeZone.ReferenceType.local
+		
+		//Set up context
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		
+		let entity =  NSEntityDescription.entity(forEntityName: "Notification", in: context)
+		
+		var row: NSManagedObject
+		
+		//Loop new entries
+		for entry in entries{
+			
+			//Get id
+			var str = entry
+			let id: Int = Int(str.subStr(start : str.indexOf(target : "\"id\":")! + 6, end : str.indexOf(target : ",\"")! - 2))!
+			
+			//Get title_es
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			let title_es: String = str.subStr(start : str.indexOf(target : "\"title_es\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
+			
+			//Get title_en
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			let title_en: String = str.subStr(start : str.indexOf(target : "\"title_en\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
+			
+			//Get title_eu
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			let title_eu: String = str.subStr(start : str.indexOf(target : "\"title_eu\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
+			
+			//Get text_es
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			let text_es: String = str.subStr(start : str.indexOf(target : "\"text_es\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
+			
+			//Get text_en
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			let text_en: String = str.subStr(start : str.indexOf(target : "\"text_en\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
+			
+			//Get text_eu
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			let text_eu: String = str.subStr(start : str.indexOf(target : "\"text_eu\":")! + 11, end: str.indexOf(target : ",\"")! - 2)
+			
+			//Get dtime
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
+			let dtime = dateFormatter.date(from : str.subStr(start : str.indexOf(target : "\"dtime\":")! + 9, end : str.indexOf(target : ",\"")! - 2))!
+			
+			//Get GM
+			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
+			let gm: Int = Int(str.subStr(start : str.indexOf(target : "\"gm\":")! + 6, end : str.indexOf(target : ",\"")! - 2))!
+			
+			// Not getting seen
+			
+			// Save & show
+			let fetchRequest: NSFetchRequest<Notification> = Notification.fetchRequest()
+			fetchRequest.predicate = NSPredicate(format: "id == %i", id)
+			fetchRequest.fetchLimit = 1
+			do{
+				let searchResults = try context.fetch(fetchRequest)
+				if (searchResults.count == 0){
+					row = NSManagedObject(entity: entity!, insertInto: context)
+					row.setValue(id, forKey: "id")
+					row.setValue(title_es, forKey: "title_es")
+					row.setValue(title_en, forKey: "title_en")
+					row.setValue(title_eu, forKey: "title_eu")
+					row.setValue(text_es, forKey: "text_es")
+					row.setValue(text_en, forKey: "text_en")
+					row.setValue(text_eu, forKey: "text_eu")
+					row.setValue(dtime, forKey: "dtime")
+					row.setValue(gm, forKey: "gm")
+					do {
+						try context.save()
+						
+						if #available(iOS 10.0, *) {
+							let content = UNMutableNotificationContent()
+							
+							// TODO Select language.
+							content.title = title_es
+							content.body = text_es
+							content.sound = UNNotificationSound.default()
+							let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 1, repeats: false)
+							let request = UNNotificationRequest.init(identifier: "Not", content: content, trigger: trigger)
+							
+							// Schedule the notification.
+							let center = UNUserNotificationCenter.current()
+							center.add(request) {
+								(error) in
+								NSLog(":NOTIFICATION:ERROR: Error showing notification \(String(describing: error))")
+							}
+						} else {
+							// Fallback on earlier versions
+						}
+						// TODO Get language
+						
+					}
+					catch let error as NSError  {
+						NSLog(":NOTIFICATION:ERROR: Could not save notification with id \(id): \(error), \(error.userInfo).")
+					}
+					catch {
+						NSLog(":NOTIFICATION:ERROR: Could not save notification with id \(id).")
+					}
+				}
+			}
+			catch {
+				NSLog(":NOTIFICATION:ERROR: Error getting notifications: \(error)")
+			}
+		}
+	}
+	
+	
+}

+ 207 - 0
app/PastActivityViewController.swift

@@ -0,0 +1,207 @@
+// Copyright (C) 2016 Inigo Valentin
+//
+// This file is part of the Gasteizko Margolariak IOS app.
+//
+// The Gasteizko Margolariak IOS app is free software: you can
+// redistribute it and/or modify it under the terms of the
+// GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// The Gasteizko Margolariak IOS app is distributed in the
+// hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with the Gasteizko Margolariak IOS app.
+// If not, see <http://www.gnu.org/licenses/>.
+
+import UIKit
+import CoreData
+
+/**
+Controller to show a past activity.
+*/
+class PastActivityViewController: UIViewController, UIGestureRecognizerDelegate {
+	
+	@IBOutlet weak var barButton: UIButton!
+	@IBOutlet weak var barTitle: UILabel!
+	@IBOutlet weak var activityTitle: UILabel!
+	@IBOutlet weak var activityImage: UIImageView!
+	@IBOutlet weak var activityText: UILabel!
+	@IBOutlet weak var activityDate: UILabel!
+
+	
+	// Activity id
+	var id: Int = -1
+	
+	var delegate: AppDelegate?
+	
+	var passId: Int = -1
+	
+	/**
+	Get the app context.
+	:return: The app context.
+	*/
+	func getContext () -> NSManagedObjectContext {
+		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
+	}
+	
+	
+	/**
+	Run when the app loads.
+	*/
+	override func viewDidLoad() {
+		super.viewDidLoad()
+		self.loadActivity(id: id)
+		// Set button action
+		barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
+	}
+	
+	
+	/**
+	Dismisses the controller.
+	*/
+	func back() {
+		self.dismiss(animated: true, completion: nil)
+	}
+	
+	
+	/**
+	Dispose of any resources that can be recreated.
+	*/
+	override func didReceiveMemoryWarning() {
+		super.didReceiveMemoryWarning()
+	}
+	
+	
+	/**
+	Loads the selected post.
+	:param: id Post id.
+	*/
+	public func loadActivity(id: Int){
+		
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Activity> = Activity.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
+		
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			var count = 0
+			var sTitle: String
+			var sText: String
+			var image: String
+			var date: NSDate
+			
+			for r in searchResults as [NSManagedObject] {
+				count = count + 1
+				sTitle = r.value(forKey: "title_\(lang)")! as! String
+				if (r.value(forKey: "after_\(lang)")! as! String).length != 0{
+					sText = r.value(forKey: "after_\(lang)")! as! String
+				}
+				else{
+					sText = r.value(forKey: "text_\(lang)")! as! String
+				}
+				date = r.value(forKey: "date")! as! NSDate
+				activityTitle.text = "  \(sTitle.decode().stripHtml())"
+				activityText.text = sText.decode().stripHtml()
+				activityDate.text = formatDate(date: date, lang: lang)
+				
+				// Get main image
+				image = ""
+				let imgFetchRequest: NSFetchRequest<Activity_image> = Activity_image.fetchRequest()
+				let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
+				let imgSortDescriptors = [imgSortDescriptor]
+				imgFetchRequest.sortDescriptors = imgSortDescriptors
+				imgFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
+				imgFetchRequest.fetchLimit = 1
+				do{
+					let imgSearchResults = try context.fetch(imgFetchRequest)
+					for imgR in imgSearchResults as [NSManagedObject]{
+						image = imgR.value(forKey: "image")! as! String
+						let path = "img/actividades/preview/\(image)"
+						self.activityImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+					}
+				} catch {
+					NSLog(":PASTACTIVITYCONTROLLER:ERROR: Error getting image for past activity \(id): \(error)")
+				}
+				
+			}
+		} catch {
+			NSLog(":PASTACTIVITYCONTROLLER:ERROR: Error loading past activity: \(error)")
+		}
+	}
+	
+	
+	/**
+	Formats a date to the desired language.
+	:param: text The date.
+	:param: lang Device language (only 'es', 'en', or 'eu').
+	*/
+	func formatDate(date: NSDate, lang: String) -> String{
+		
+		let months_es = ["0index", "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]
+		let months_en = ["0index", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
+		let months_eu = ["0index", "urtarrilaren", "otsailaren", "martxoaren", "abrilaren", "maiatzaren", "ekainaren", "ustailaren", "abustuaren", "irailaren", "urriaren", "azaroaren", "abenduaren"]
+		let days_es = ["0index", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sábado", "Domingo"]
+		let days_en = ["0index", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+		let days_eu = ["0index", "Astelehena", "Asteartea", "Asteazkena", "Osteguna", "Ostirala", "Larumbata", "Igandea"]
+		
+		let calendar = Calendar.current
+		let day = calendar.component(.day, from: date as Date)
+		let month = calendar.component(.month, from: date as Date)
+		let weekday = calendar.component(.weekday, from: date as Date)
+		var strDate = ""
+		
+		switch lang{
+		case "en":
+			
+			var dayNum = ""
+			switch day{
+			case 1:
+				dayNum = "1th"
+				break
+			case 2:
+				dayNum = "2nd"
+				break;
+			case 3:
+				dayNum = "3rd"
+				break;
+			default:
+				dayNum = "\(weekday)th"
+			}
+			
+			strDate = "\(days_en[weekday]), \(months_en[month]) \(dayNum)"
+			break
+		case "eu":
+			strDate = "\(days_eu[weekday]) \(months_eu[month]) \(day)an"
+			break
+		default:
+			strDate = "\(days_es[weekday]) \(day) de \(months_es[month])"
+		}
+		
+		return strDate
+	}
+	
+	/**
+	Gets the device language. The only recognized languages are Spanish, English and Basque.
+	If the device has another language, Spanish will be selected by default.
+	:return: Two-letter language code.
+	*/
+	func getLanguage() -> String{
+		let pre = NSLocale.preferredLanguages[0].subStr(start: 0, end: 1)
+		if(pre == "es" || pre == "en" || pre == "eu"){
+			return pre
+		}
+		else{
+			return "es"
+		}
+	}
+	
+}
+

+ 289 - 0
app/PhotoViewController.swift

@@ -0,0 +1,289 @@
+// Copyright (C) 2016 Inigo Valentin
+//
+// This file is part of the Gasteizko Margolariak IOS app.
+//
+// The Gasteizko Margolariak IOS app is free software: you can
+// redistribute it and/or modify it under the terms of the
+// GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// The Gasteizko Margolariak IOS app is distributed in the
+// hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with the Gasteizko Margolariak IOS app.
+// If not, see <http://www.gnu.org/licenses/>.
+
+import UIKit
+import CoreData
+
+/**
+The view controller of the app.
+*/
+class PhotoViewController: UIViewController, UIGestureRecognizerDelegate {
+
+	@IBOutlet weak var barButton: UIButton!
+	@IBOutlet weak var barTitle: UILabel!
+	@IBOutlet weak var photoTitle: UILabel!
+	@IBOutlet weak var photoImage: UIImageView!
+	@IBOutlet weak var photoDate: UILabel!
+	@IBOutlet weak var btPrev: UIButton!
+	@IBOutlet weak var btNext: UIButton!
+	
+	var albumId: Int = -1
+	var photoId: Int = -1
+	var photoIds: [Int] = []
+	var photoIdx: Int = 0
+	var passPhotoId: Int = -1
+	var passAlbumId: Int = -1
+	var albumTitle: String = ""
+	var delegate: AppDelegate?
+	
+	
+	/**
+	Gets the application context.
+	:return: The application context.
+	*/
+	func getContext () -> NSManagedObjectContext {
+		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
+	}
+	
+	
+	/**
+	Run when the app loads.
+	*/
+	override func viewDidLoad() {
+		
+		// Populate photo array.
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Photo_album> = Photo_album.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "album = %i", albumId)
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			
+			var id: Int
+			var i = 0
+			
+			for r in searchResults as [NSManagedObject] {
+				
+				id = r.value(forKey: "photo")! as! Int
+				photoIds.append(id)
+				if id == photoId{
+					photoIdx = i
+				}
+				i = i + 1
+			}
+			
+			// Get album title
+			let albumFetchRequest: NSFetchRequest<Album> = Album.fetchRequest()
+			albumFetchRequest.predicate = NSPredicate(format: "id = %i", albumId)
+			do {
+				let results = try context.fetch(albumFetchRequest)
+				let r = results[0]
+				self.albumTitle = r.value(forKey: "title_\(lang)")! as! String
+			}
+			catch {
+				NSLog(":GALLERYCONTROLLER:ERROR: Error getting album info: \(error)")
+			}
+			
+		} catch {
+			NSLog(":PHOTO:ERROR: Error getting infor from album \(albumId): \(error)")
+		}
+		
+		// Set up buttons
+		let tapRecognizerNext = UITapGestureRecognizer(target: self, action: #selector(nextPhoto(_:)))
+		btNext.isUserInteractionEnabled = true
+		btNext.addGestureRecognizer(tapRecognizerNext)
+		let tapRecognizerPrev = UITapGestureRecognizer(target: self, action: #selector(prevPhoto(_:)))
+		btPrev.isUserInteractionEnabled = true
+		btPrev.addGestureRecognizer(tapRecognizerPrev)
+		
+		super.viewDidLoad()
+		self.loadPhoto(id: photoId)
+		
+		// Set button action
+		self.barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
+	}
+	
+	
+	/**
+	Dismisses the controller.
+	*/
+	func back() {
+		self.dismiss(animated: true, completion: nil)
+	}
+	
+	
+	/**
+	Dispose of any resources that can be recreated.
+	*/
+	override func didReceiveMemoryWarning() {
+		super.didReceiveMemoryWarning()
+	}
+	
+	
+	/**
+	Opens the next photo.
+	*/
+	func nextPhoto(_ sender:UITapGestureRecognizer? = nil){
+		photoIdx = photoIdx + 1
+		loadPhoto(id: photoIds[photoIdx])
+	}
+	
+	
+	/**
+	Opens the previous photo.
+	*/
+	func prevPhoto(_ sender:UITapGestureRecognizer? = nil){
+		photoIdx = photoIdx - 1
+		loadPhoto(id: photoIds[photoIdx])
+	}
+	
+	
+	/**
+	Loads a photo in the viewer.
+	:param: id
+	*/
+	public func loadPhoto(id: Int){
+		
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Photo> = Photo.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
+		
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			
+			var sTitle: String
+			var image: String
+			var date: NSDate
+			
+			for r in searchResults as [NSManagedObject] {
+				
+				sTitle = r.value(forKey: "title_\(lang)")! as! String
+				if sTitle == "" || sTitle == "ul" {
+					sTitle = self.albumTitle
+				}
+				self.photoTitle.text = "  \(sTitle.decode().stripHtml())"
+				
+				// Enable or disable buttons
+				if photoIdx == 0{
+					self.btPrev.isEnabled = false
+					self.btPrev.alpha = 0.5
+				}
+				else{
+					self.btPrev.isEnabled = true
+					self.btPrev.alpha = 1
+				}
+				if photoIdx == photoIds.count - 1{
+					self.btNext.isEnabled = false
+					self.btNext.alpha = 0.5
+				}
+				else{
+					self.btNext.isEnabled = true
+					self.btNext.alpha = 1
+				}
+				
+				// Get image
+				image = ""
+				let imgFetchRequest: NSFetchRequest<Photo> = Photo.fetchRequest()
+				imgFetchRequest.predicate = NSPredicate(format: "id == %i", id)
+				do{
+					let imgSearchResults = try context.fetch(imgFetchRequest)
+					let r: NSManagedObject = imgSearchResults[0]
+					image = r.value(forKey: "file")! as! String
+					date = r.value(forKey: "uploaded")! as! NSDate
+					let path = "img/galeria/preview/\(image)"
+					// TODO: Every time, set placeholder image
+					self.photoImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+					self.photoDate.text = formatDate(date: date, lang: lang)
+				}
+				catch {
+					NSLog(":PHOTO:ERROR: Error getting image for post \(id): \(error)")
+				}
+				
+			}
+		} catch {
+			NSLog(":PHOTO:ERROR: Error setting up photo \(id): \(error)")
+		}
+	}
+	
+
+	
+	/**
+	Formats a date to the desired language.
+	:param: text The date.
+	:param: lang Device language (only 'es', 'en', or 'eu').
+	*/
+	func formatDate(date: NSDate, lang: String) -> String{
+		
+		let months_es = ["0index", "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]
+		let months_en = ["0index", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
+		let months_eu = ["0index", "urtarrilaren", "otsailaren", "martxoaren", "abrilaren", "maiatzaren", "ekainaren", "ustailaren", "abustuaren", "irailaren", "urriaren", "azaroaren", "abenduaren"]
+		let days_es = ["0index", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sábado", "Domingo"]
+		let days_en = ["0index", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+		let days_eu = ["0index", "Astelehena", "Asteartea", "Asteazkena", "Osteguna", "Ostirala", "Larumbata", "Igandea"]
+		
+		let calendar = Calendar.current
+		let year = calendar.component(.year, from: date as Date)
+		let day = calendar.component(.day, from: date as Date)
+		let month = calendar.component(.month, from: date as Date)
+		let weekday = calendar.component(.weekday, from: date as Date)
+		var strDate = ""
+		
+		switch lang{
+		case "en":
+			
+			var dayNum = ""
+			switch day{
+			case 1:
+				dayNum = "1th"
+				break
+			case 2:
+				dayNum = "2nd"
+				break;
+			case 3:
+				dayNum = "3rd"
+				break;
+			default:
+				dayNum = "\(weekday)th"
+			}
+			
+			strDate = "\(days_en[weekday]), \(months_en[month]) \(dayNum), \(year)"
+			break
+		case "eu":
+			strDate = "\(year)ko \(days_eu[weekday]) \(months_eu[month]) \(day)an"
+			break
+		default:
+			strDate = "\(days_es[weekday]) \(day) de \(months_es[month]) de \(year)"
+		}
+		
+		return strDate
+	}
+	
+	
+	/**
+	Gets the device language. The only recognized languages are Spanish, English and Basque.
+	If the device has another language, Spanish will be selected by default.
+	:return: Two-letter language code.
+	*/
+	func getLanguage() -> String{
+		let pre = NSLocale.preferredLanguages[0].subStr(start: 0, end: 1)
+		if(pre == "es" || pre == "en" || pre == "eu"){
+			return pre
+		}
+		else{
+			return "es"
+		}
+	}
+}
+

+ 21 - 24
app/PostViewController.swift

@@ -26,20 +26,17 @@ The view controller of the app.
 */
 class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 	
+	
 	@IBOutlet weak var barTitle: UILabel!
 	@IBOutlet weak var barButton: UIButton!
 	@IBOutlet weak var postText: UILabel!
 	@IBOutlet weak var postTitle: UILabel!
 	@IBOutlet weak var postImage: UIImageView!
-	var id: Int = -1
-	var delegate: AppDelegate?
 	
+	var id: Int = -1
 	var passId: Int = -1
+	var delegate: AppDelegate?
 	
-	/**
-	Get the app context.
-	:return: The app context.
-	*/
 	func getContext () -> NSManagedObjectContext {
 		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
 	}
@@ -49,18 +46,16 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 	Run when the app loads.
 	*/
 	override func viewDidLoad() {
+		
 		super.viewDidLoad()
 		self.loadPost(id: id)
+		
 		// Set button action
 		barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
 	}
+		
 	
-	
-	/**
-	Dismisses the controller.
-	*/
 	func back() {
-		print("POSTCONTROLLER:DEBUG: Back")
 		self.dismiss(animated: true, completion: nil)
 	}
 	
@@ -72,15 +67,8 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 		super.didReceiveMemoryWarning()
 	}
 	
-	
-	/**
-	Loads the selected post.
-	:param: id Post id.
-	*/
 	public func loadPost(id: Int){
 		
-		NSLog(":POSTCONTROLLER:DEBUG: Loading post \(id)")
-		
 		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		let appDelegate = UIApplication.shared.delegate as! AppDelegate
 		let lang : String = getLanguage()
@@ -89,18 +77,20 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
 		
 		do {
+			//go get the results
 			let searchResults = try context.fetch(fetchRequest)
-			var count = 0
+			
 			var sTitle: String
 			var sText: String
 			var image: String
 			
+			//You need to convert to NSManagedObject to use 'for' loops
 			for r in searchResults as [NSManagedObject] {
-				count = count + 1
+				
 				sTitle = r.value(forKey: "title_\(lang)")! as! String
 				sText = r.value(forKey: "text_\(lang)")! as! String
-				postTitle.text = "  \(sTitle)"
-				postText.text = sText.stripHtml()
+				postTitle.text = "  \(sTitle.decode().stripHtml())"
+				postText.text = sText.decode().stripHtml()
 				
 				// Get main image
 				image = ""
@@ -110,12 +100,18 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 				imgFetchRequest.sortDescriptors = imgSortDescriptors
 				imgFetchRequest.predicate = NSPredicate(format: "post == %i", id)
 				imgFetchRequest.fetchLimit = 1
+				//TODO get more images
 				do{
 					let imgSearchResults = try context.fetch(imgFetchRequest)
 					for imgR in imgSearchResults as [NSManagedObject]{
 						image = imgR.value(forKey: "image")! as! String
-						let path = "img/blog/preview/\(image)"
-						self.postImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+						if image == ""{
+							self.postImage.isHidden = true
+						}
+						else{
+							let path = "img/blog/thumb/\(image)"
+							self.postImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+						}
 					}
 				} catch {
 					NSLog(":POST:ERROR: Error getting image for post \(id): \(error)")
@@ -127,6 +123,7 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 		}
 	}
 	
+	
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	If the device has another language, Spanish will be selected by default.

+ 31 - 8
app/RowAlbum.swift

@@ -34,6 +34,9 @@ Extension of UIView to be formatted as sections.
 	// Album ID
 	var id = -1
 	
+	// Photo ids
+	var photoIds: [Int] = [-1, -1]
+	
 	// Array with the imageviews
 	var preview: [UIImageView] = []
 
@@ -50,7 +53,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 		
 		self.frame = self.bounds
 		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
@@ -70,7 +73,6 @@ Extension of UIView to be formatted as sections.
 	:param: i Custom identifier
 	*/
 	init(s: String, i: Int) {
-		NSLog(":ROWALBUM:DEBUG: Init \(s), \(i)")
 		
 		super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
 		loadViewFromNib()
@@ -95,29 +97,50 @@ Extension of UIView to be formatted as sections.
 		super.init(frame: frame)
 	}
 	
-	func openPhoto(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ROWALBUM:DEBUG: Getting delegate and showing photo.")
-		// TODO
-		//let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		//delegate.controller?.showAlbum(id: self.id)
+	func openLeftPhoto(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.albumController?.showPhoto(album: self.id, photo: self.photoIds[0])
+	}
+	
+	func openRightPhoto(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.albumController?.showPhoto(album: self.id, photo: self.photoIds[1])
 	}
 	
 	
 	/**
 	Changes the preview image of the photos.
 	If null or empty, the igage is hidden.
+	It also sets the tap listener to show the photo.
 	:param: idx Id of the image in the row. 0 for left, 1 for right.
 	:param: filename Filename of the image.
 	*/
 	func setImage(idx: Int, filename: String){
 		if (filename == ""){
 			self.preview[idx].isHidden = true
-			//TODO hide the imageview
 		}
 		else{
 			let path = "img/galeria/thumb/\(filename)"
 			self.preview[idx].setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+			// Set tap listener
+			if idx == 0 {
+				let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowAlbum.openLeftPhoto(_:)))
+				tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+				self.preview[idx].isUserInteractionEnabled = true
+				self.preview[idx].addGestureRecognizer(tapRecognizer)
+			}
+			else{
+				let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowAlbum.openRightPhoto(_:)))
+				tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+				self.preview[idx].isUserInteractionEnabled = true
+				self.preview[idx].addGestureRecognizer(tapRecognizer)
+			}
 		}
 	}
 	
+	func setIds(left: Int, right: Int){
+		self.photoIds[0] = left
+		self.photoIds[1] = right
+	}
+	
 }

+ 16 - 20
app/RowBlog.swift

@@ -22,25 +22,20 @@ import Foundation
 import UIKit
 
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as post rows.
 */
 @IBDesignable class RowBlog: UIView {
 	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
-
-	//The post title.
 	@IBOutlet weak var title: UILabel!
-	
-	//The post description.
 	@IBOutlet weak var descrip: UILabel!
-
-	//The post image.
 	@IBOutlet weak var image: UIImageView!
 	
+	// Post ID.
+	var id = -1
+	
 	
 	/**
 	Default constructor
@@ -51,14 +46,15 @@ Extension of UIView to be formatted as sections.
 	
 	
 	/**
-	Loads the view in the xib file with the same name.
+	Loads the view from the xib with the same name as the class.
 	*/
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
+	
 	/**
 	Default constructor.
 	:param: s Custom identifier
@@ -77,10 +73,9 @@ Extension of UIView to be formatted as sections.
 		self.addSubview(self.container)
 		
 		// Set tap recognizer
-		/*print("ROW_BLOG:DEBUG: set tap recognizer")
-		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (self.openPost (_:)))
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowBlog.openPost (_:)))
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		addGestureRecognizer(tapRecognizer)*/
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	
 	
@@ -97,7 +92,7 @@ Extension of UIView to be formatted as sections.
 	:param: text The new title.
 	*/
 	func setTitle(text: String){
-		self.title.text = text.decode().stripHtml()
+		title.text = text.decode().stripHtml()
 	}
 	
 	
@@ -106,10 +101,11 @@ Extension of UIView to be formatted as sections.
 	:param: text The new text.
 	*/
 	func setText(text: String){
-		self.descrip.text = text.decode()
+		descrip.text = text.decode().stripHtml()
 	}
 	
 	
+	
 	/**
 	Changes the image of the post.
 	If null or empty, the igage is hidden.
@@ -128,10 +124,10 @@ Extension of UIView to be formatted as sections.
 	
 	
 	/**
-	Opens a post.
+	Opens an activity.
 	*/
 	func openPost(_ sender:UITapGestureRecognizer? = nil){
-		// TODO implement openPost.
-		NSLog(":ROW_BLOG:DEBUG: openpost")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPost(id: self.id)
 	}
 }

+ 1 - 1
app/RowBlog.xib

@@ -36,7 +36,7 @@
                                     <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                 </label>
-                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="6hA-MD-OsD" userLabel="Image">
+                                <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="6hA-MD-OsD" userLabel="Image">
                                     <rect key="frame" x="10" y="40" width="71" height="64"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="64" id="68z-jj-fIa"/>

+ 29 - 15
app/RowFutureActivity.swift

@@ -22,11 +22,11 @@ import Foundation
 import UIKit
 
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as future activity rows.
 */
 @IBDesignable class RowFutureActivity: UIView {
 
-	// Outlets
+	// Outlets.
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var image: UIImageView!
@@ -35,6 +35,9 @@ Extension of UIView to be formatted as sections.
 	@IBOutlet weak var city: UILabel!
 	@IBOutlet weak var price: UILabel!
 	
+	// Activity ID.
+	var id = -1
+	
 	
 	/**
 	Default constructor
@@ -45,13 +48,16 @@ Extension of UIView to be formatted as sections.
 	}
 	
 	
-	
+	/**
+	Loads the view from the xib with the same name as the class.
+	*/
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
+	
 	/**
 	Default constructor.
 	:param: s Custom identifier
@@ -66,16 +72,16 @@ Extension of UIView to be formatted as sections.
 		container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
 		container.translatesAutoresizingMaskIntoConstraints = true
 		
-		container.frame = self.bounds
-		self.addSubview(container)
+		self.container.frame = self.bounds
+		self.addSubview(self.container)
 		
 		// Set tap recognizer
-		/*print("ROW_FUTURE_ACTIVITY:DEBUG: set tap recognizer")
-		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (self.openActivity (_:)))
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowPastActivity.openActivity (_:)))
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		addGestureRecognizer(tapRecognizer)*/
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	
+	
 	/**
 	Default constructor for the interface builder
 	*/
@@ -84,7 +90,6 @@ Extension of UIView to be formatted as sections.
 	}
 	
 	
-	
 	/**
 	Changes the title of the activity. Decodes HTML.
 	:param: text The new title.
@@ -93,6 +98,7 @@ Extension of UIView to be formatted as sections.
 		self.title.text = text.decode().stripHtml()
 	}
 	
+	
 	/**
 	Sets the city of the activity.
 	:param: text The city.
@@ -101,6 +107,7 @@ Extension of UIView to be formatted as sections.
 		self.city.text = text.decode().stripHtml()
 	}
 	
+	
 	/**
 	Sets the price of the activity.
 	:param: price The price, in Euros. If 0, nothing is shown.
@@ -114,6 +121,7 @@ Extension of UIView to be formatted as sections.
 		}
 	}
 	
+	
 	/**
 	Changes the description of the activity. Decodes HTML.
 	:param: text The new text.
@@ -122,6 +130,7 @@ Extension of UIView to be formatted as sections.
 		self.descript.text = text.decode().stripHtml()
 	}
 	
+	
 	/**
 	Sets the date of the activity in a human readable format.
 	:param: text The date.
@@ -172,6 +181,7 @@ Extension of UIView to be formatted as sections.
 		self.date.text = strDate
 	}
 	
+	
 	/**
 	Changes the image of the activity.
 	If null or empty, the igage is hidden.
@@ -179,17 +189,21 @@ Extension of UIView to be formatted as sections.
 	*/
 	func setImage(filename: String){
 		if (filename == ""){
-			NSLog("ROW_FUTURE_ACTIVITY:DEBUG: No image")
-			//TODO hide the imageview
+			// Hide the imageview
+			self.image.isHidden = true
 		}
 		else{
-			NSLog(":ROW_FUTURE_ACTIVITY:DEBUG: Set image \(filename)")
 			let path = "img/actividades/thumb/\(filename)"
-			image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 	}
 	
+	
+	/**
+	Opens an activity.
+	*/
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ROW_FUTURE_ACTIVITY:DEBUG: open activity")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showFutureActivity(id: self.id)
 	}
 }

+ 19 - 18
app/RowFutureActivity.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -27,10 +27,10 @@
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <subviews>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LXM-17-fy1" userLabel="Container">
-                    <rect key="frame" x="0.0" y="263.5" width="375" height="140"/>
+                    <rect key="frame" x="0.0" y="248.5" width="375" height="170"/>
                     <subviews>
                         <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Oax-mA-mEd" userLabel="Entry">
-                            <rect key="frame" x="10" y="10" width="355" height="140"/>
+                            <rect key="frame" x="10" y="10" width="355" height="170"/>
                             <subviews>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Vd3-c0-iYd" userLabel="Title">
                                     <rect key="frame" x="10" y="10" width="335" height="22"/>
@@ -39,35 +39,36 @@
                                     <nil key="highlightedColor"/>
                                 </label>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pCj-dq-5rF" userLabel="Date">
-                                    <rect key="frame" x="14.5" y="32" width="325" height="21"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                    <rect key="frame" x="9.5" y="40" width="335" height="21"/>
+                                    <fontDescription key="fontDescription" type="italicSystem" pointSize="17"/>
                                     <color key="textColor" red="0.15294117647058825" green="0.33333333333333331" blue="0.45098039215686275" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                 </label>
-                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="xIf-kY-gPW" userLabel="Image">
+                                <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="xIf-kY-gPW" userLabel="Image">
+                                    <rect key="frame" x="10" y="69" width="71" height="64"/>
                                     <rect key="frame" x="10" y="53" width="71" height="64"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="64" id="GGt-lC-syI"/>
                                     </constraints>
                                 </imageView>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m6I-vy-k36" userLabel="Text">
-                                    <rect key="frame" x="97" y="53" width="248" height="21"/>
+                                    <rect key="frame" x="97" y="61" width="248" height="21"/>
                                     <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                     <nil key="textColor"/>
                                     <nil key="highlightedColor"/>
                                 </label>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VQF-xA-wca" userLabel="City">
-                                    <rect key="frame" x="20" y="119" width="275" height="21"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                    <rect key="frame" x="10" y="144" width="275" height="21"/>
+                                    <fontDescription key="fontDescription" type="italicSystem" pointSize="17"/>
                                     <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                 </label>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U3K-kD-4pK" userLabel="Price">
-                                    <rect key="frame" x="285" y="119" width="50" height="21"/>
+                                    <rect key="frame" x="285" y="144" width="50" height="21"/>
                                     <constraints>
                                         <constraint firstAttribute="width" constant="50" id="uI7-D4-q0g"/>
                                     </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                    <fontDescription key="fontDescription" type="italicSystem" pointSize="17"/>
                                     <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                 </label>
@@ -75,7 +76,7 @@
                             <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
                             <constraints>
                                 <constraint firstItem="VQF-xA-wca" firstAttribute="width" secondItem="Oax-mA-mEd" secondAttribute="width" constant="-80" id="1bi-lD-f66"/>
-                                <constraint firstItem="pCj-dq-5rF" firstAttribute="top" secondItem="Vd3-c0-iYd" secondAttribute="bottom" id="2SS-dr-xRe"/>
+                                <constraint firstItem="pCj-dq-5rF" firstAttribute="top" secondItem="Vd3-c0-iYd" secondAttribute="bottom" constant="8" id="2SS-dr-xRe"/>
                                 <constraint firstItem="Vd3-c0-iYd" firstAttribute="top" secondItem="Oax-mA-mEd" secondAttribute="top" constant="10" id="6ON-9I-XV5"/>
                                 <constraint firstItem="xIf-kY-gPW" firstAttribute="width" secondItem="Oax-mA-mEd" secondAttribute="width" multiplier="0.2" id="7yL-vu-0hi"/>
                                 <constraint firstItem="m6I-vy-k36" firstAttribute="width" secondItem="Oax-mA-mEd" secondAttribute="width" multiplier="0.7" id="G5a-55-w2d"/>
@@ -83,14 +84,14 @@
                                 <constraint firstItem="pCj-dq-5rF" firstAttribute="centerX" secondItem="Oax-mA-mEd" secondAttribute="centerX" id="LiY-tJ-HN8"/>
                                 <constraint firstAttribute="trailing" secondItem="Vd3-c0-iYd" secondAttribute="trailing" constant="10" id="QqW-8x-l8D"/>
                                 <constraint firstAttribute="trailing" secondItem="m6I-vy-k36" secondAttribute="trailing" constant="10" id="d6m-wH-hZ4"/>
-                                <constraint firstItem="pCj-dq-5rF" firstAttribute="width" secondItem="Oax-mA-mEd" secondAttribute="width" constant="-30" id="ec5-Em-Hvc"/>
-                                <constraint firstItem="VQF-xA-wca" firstAttribute="leading" secondItem="Oax-mA-mEd" secondAttribute="leading" constant="20" id="fKa-XB-zgY"/>
+                                <constraint firstItem="pCj-dq-5rF" firstAttribute="width" secondItem="Oax-mA-mEd" secondAttribute="width" constant="-20" id="ec5-Em-Hvc"/>
+                                <constraint firstItem="VQF-xA-wca" firstAttribute="leading" secondItem="Oax-mA-mEd" secondAttribute="leading" constant="10" id="fKa-XB-zgY"/>
                                 <constraint firstAttribute="trailing" secondItem="U3K-kD-4pK" secondAttribute="trailing" constant="20" id="fib-sq-y5t"/>
                                 <constraint firstItem="U3K-kD-4pK" firstAttribute="centerY" secondItem="VQF-xA-wca" secondAttribute="centerY" id="fxM-45-fab"/>
                                 <constraint firstItem="m6I-vy-k36" firstAttribute="top" secondItem="pCj-dq-5rF" secondAttribute="bottom" id="jKd-mD-fFn"/>
-                                <constraint firstAttribute="bottom" secondItem="VQF-xA-wca" secondAttribute="bottom" id="rUq-Gl-Ma0"/>
+                                <constraint firstAttribute="bottom" secondItem="VQF-xA-wca" secondAttribute="bottom" constant="5" id="rUq-Gl-Ma0"/>
                                 <constraint firstItem="xIf-kY-gPW" firstAttribute="leading" secondItem="Oax-mA-mEd" secondAttribute="leading" constant="10" id="xRs-gP-CBO"/>
-                                <constraint firstItem="xIf-kY-gPW" firstAttribute="top" secondItem="pCj-dq-5rF" secondAttribute="bottom" id="xYq-wH-6dd"/>
+                                <constraint firstItem="xIf-kY-gPW" firstAttribute="top" secondItem="pCj-dq-5rF" secondAttribute="bottom" constant="8" id="xYq-wH-6dd"/>
                             </constraints>
                             <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
                             <userDefinedRuntimeAttributes>
@@ -111,7 +112,7 @@
                         <constraint firstItem="Oax-mA-mEd" firstAttribute="bottom" secondItem="LXM-17-fy1" secondAttribute="bottom" constant="10" id="cGe-u0-Et9"/>
                         <constraint firstAttribute="top" secondItem="Oax-mA-mEd" secondAttribute="top" constant="-10" id="dfL-CJ-4Ja"/>
                         <constraint firstAttribute="trailing" secondItem="Oax-mA-mEd" secondAttribute="trailing" constant="10" id="mgX-om-hx4"/>
-                        <constraint firstAttribute="height" constant="140" id="pnJ-Mv-tz4"/>
+                        <constraint firstAttribute="height" constant="170" id="pnJ-Mv-tz4"/>
                     </constraints>
                     <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
                     <userDefinedRuntimeAttributes>

+ 1 - 3
app/RowGallery.swift

@@ -55,7 +55,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
 	
@@ -100,7 +100,6 @@ Extension of UIView to be formatted as sections.
 	Opens an album.
 	*/
 	func openAlbum(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ROW_GALLERY:DEBUG: Getting delegate and showing album \(self.id).")
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		delegate.controller?.showAlbum(id: self.id)
 	}
@@ -122,7 +121,6 @@ Extension of UIView to be formatted as sections.
 	*/
 	func setImage(idx: Int, filename: String){
 		if (filename == ""){
-			NSLog(":ROWGALLERY:DEBUG: No image for album \(self.id) at index \(idx).")
 			self.preview[idx].isHidden = true
 		}
 		else{

+ 2 - 2
app/RowGallery.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>

+ 24 - 17
app/RowHomeBlog.swift

@@ -26,23 +26,16 @@ Extension of UIView to be formatted as sections.
 */
 @IBDesignable class RowHomeBlog: UIView {
 
-	var id: Int!
-	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
-	
-	//The post title.
 	@IBOutlet weak var title: UILabel!
-	
-	//The post text.
 	@IBOutlet weak var descrip: UILabel!
-	
-	//The image.
 	@IBOutlet weak var image: UIImageView!
 	
+	// Post ID.
+	var id: Int!
+	
 	
 	/**
 	Default constructor
@@ -58,7 +51,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil).first as! UIView
 	}
 	
 	
@@ -73,11 +66,16 @@ Extension of UIView to be formatted as sections.
 		self.frame = self.bounds
 		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
 		self.translatesAutoresizingMaskIntoConstraints = true
-		container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-		container.translatesAutoresizingMaskIntoConstraints = true
+		self.container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		self.container.translatesAutoresizingMaskIntoConstraints = true
+		
+		self.container.frame = self.bounds
+		self.addSubview(self.container)
 		
-		container.frame = self.bounds
-		self.addSubview(container)
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeBlog.openPost (_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	
 	
@@ -115,11 +113,20 @@ Extension of UIView to be formatted as sections.
 	func setImage(filename: String){
 		if (filename == ""){
 			// Hide the imageview
-			self.image.isHidden = true
+			self.image.isHidden = true;
 		}
 		else{
 			let path = "img/blog/thumb/\(filename)"
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 	}
+	
+	
+	/**
+	Opens a post.
+	*/
+	func openPost(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPost(id: self.id)
+	}
 }

+ 109 - 109
app/RowHomeBlog.xib

@@ -1,111 +1,111 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16B2657" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-<device id="retina4_7" orientation="portrait">
-<adaptation id="fullscreen"/>
-</device>
-<dependencies>
-<deployment identifier="iOS"/>
-<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
-<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
-<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-</dependencies>
-<objects>
-<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RowHomeBlog" customModule="app">
-<connections>
-<outlet property="container" destination="2hI-rc-KPm" id="rWX-Vl-kOp"/>
-<outlet property="descrip" destination="f4E-5p-Bid" id="IF5-ck-qUL"/>
-<outlet property="entry" destination="wLM-VU-VYk" id="Gkq-yE-fdN"/>
-<outlet property="image" destination="WSe-uz-Uhz" id="iU4-jm-UzQ"/>
-<outlet property="title" destination="Bkz-DV-HVr" id="1ok-yI-Npt"/>
-</connections>
-</placeholder>
-<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-<view contentMode="scaleToFill" id="iN0-l3-epB" userLabel="RowHomePastActivities" customClass="RowHomePastActivities" customModule="app">
-<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
-<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-<subviews>
-<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2hI-rc-KPm" userLabel="Container">
-<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
-<subviews>
-<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wLM-VU-VYk" userLabel="Entry">
-<rect key="frame" x="10" y="10" width="355" height="667"/>
-<subviews>
-<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bkz-DV-HVr" userLabel="Title">
-<rect key="frame" x="10" y="10" width="335" height="21.5"/>
-<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
-<color key="textColor" red="0.15294117647058825" green="0.33333333333333331" blue="0.45098039215686275" alpha="1" colorSpace="calibratedRGB"/>
-<nil key="highlightedColor"/>
-</label>
-<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="WSe-uz-Uhz" userLabel="Image">
-<rect key="frame" x="10" y="40" width="89" height="64"/>
-<constraints>
-<constraint firstAttribute="height" constant="64" id="EJ3-uo-Xp3"/>
-</constraints>
-</imageView>
-<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f4E-5p-Bid" userLabel="Text">
-<rect key="frame" x="98" y="40" width="214" height="64"/>
-<fontDescription key="fontDescription" type="system" pointSize="17"/>
-<nil key="textColor"/>
-<nil key="highlightedColor"/>
-</label>
-</subviews>
-<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
-<constraints>
-<constraint firstItem="WSe-uz-Uhz" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.2" id="9Lz-WQ-1aS"/>
-<constraint firstItem="f4E-5p-Bid" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Emi-Ob-27Q"/>
-<constraint firstItem="Bkz-DV-HVr" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="LSz-FM-x2V"/>
-<constraint firstItem="f4E-5p-Bid" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.7" id="MdM-ps-4b8"/>
-<constraint firstAttribute="trailing" secondItem="Bkz-DV-HVr" secondAttribute="trailing" constant="10" id="MdM-yF-pmK"/>
-<constraint firstItem="WSe-uz-Uhz" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Pyf-oT-PQl"/>
-<constraint firstItem="WSe-uz-Uhz" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="YG6-eX-oTj"/>
-<constraint firstItem="Bkz-DV-HVr" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="10" id="mwG-d2-HQL"/>
-<constraint firstAttribute="trailing" secondItem="f4E-5p-Bid" secondAttribute="trailing" constant="10" id="svU-xx-LsR"/>
-</constraints>
-<edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
-<userDefinedRuntimeAttributes>
-<userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-<color key="value" red="0.42745098039215684" green="0.41176470588235292" blue="0.56470588235294117" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-</userDefinedRuntimeAttribute>
-<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-<real key="value" value="1"/>
-</userDefinedRuntimeAttribute>
-<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-<real key="value" value="3"/>
-</userDefinedRuntimeAttribute>
-</userDefinedRuntimeAttributes>
-</view>
-</subviews>
-<constraints>
-<constraint firstItem="wLM-VU-VYk" firstAttribute="bottom" secondItem="2hI-rc-KPm" secondAttribute="bottom" constant="10" id="39K-W7-EIE"/>
-<constraint firstAttribute="trailing" secondItem="wLM-VU-VYk" secondAttribute="trailing" constant="10" id="HSF-55-R5c"/>
-<constraint firstAttribute="height" constant="120" id="PdT-5v-I0r"/>
-<constraint firstItem="wLM-VU-VYk" firstAttribute="top" secondItem="2hI-rc-KPm" secondAttribute="top" constant="10" id="fWN-oO-QzS"/>
-<constraint firstItem="wLM-VU-VYk" firstAttribute="leading" secondItem="2hI-rc-KPm" secondAttribute="leading" constant="10" id="teN-oh-Db9"/>
-</constraints>
-<edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
-<userDefinedRuntimeAttributes>
-<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-<real key="value" value="0.0"/>
-</userDefinedRuntimeAttribute>
-</userDefinedRuntimeAttributes>
-</view>
-</subviews>
-<constraints>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="Kwy-25-YES"/>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="clR-QU-zlD"/>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="htS-q0-otF"/>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="rig-k7-6bz"/>
-</constraints>
-<nil key="simulatedStatusBarMetrics"/>
-<userDefinedRuntimeAttributes>
-<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-<real key="value" value="0.0"/>
-</userDefinedRuntimeAttribute>
-</userDefinedRuntimeAttributes>
-<point key="canvasLocation" x="45.5" y="-43.5"/>
-</view>
-</objects>
-<resources>
-<image name="PhotoPlaceholder" width="170" height="108"/>
-</resources>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RowHomeBlog" customModule="app">
+            <connections>
+                <outlet property="container" destination="2hI-rc-KPm" id="rWX-Vl-kOp"/>
+                <outlet property="descrip" destination="f4E-5p-Bid" id="IF5-ck-qUL"/>
+                <outlet property="entry" destination="wLM-VU-VYk" id="Gkq-yE-fdN"/>
+                <outlet property="image" destination="WSe-uz-Uhz" id="iU4-jm-UzQ"/>
+                <outlet property="title" destination="Bkz-DV-HVr" id="1ok-yI-Npt"/>
+            </connections>
+        </placeholder>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" userLabel="RowHomePastActivities" customClass="RowHomePastActivities" customModule="app">
+            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2hI-rc-KPm" userLabel="Container">
+                    <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wLM-VU-VYk" userLabel="Entry">
+                            <rect key="frame" x="10" y="10" width="355" height="667"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bkz-DV-HVr" userLabel="Title">
+                                    <rect key="frame" x="10" y="10" width="335" height="21.5"/>
+                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
+                                    <color key="textColor" red="0.15294117647058825" green="0.33333333333333331" blue="0.45098039215686275" alpha="1" colorSpace="calibratedRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="WSe-uz-Uhz" userLabel="Image">
+                                    <rect key="frame" x="10" y="40" width="71" height="64"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="64" id="EJ3-uo-Xp3"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f4E-5p-Bid" userLabel="Text">
+                                    <rect key="frame" x="96.5" y="40" width="248.5" height="20.5"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                    <nil key="textColor"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                            </subviews>
+                            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstItem="WSe-uz-Uhz" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.2" id="9Lz-WQ-1aS"/>
+                                <constraint firstItem="f4E-5p-Bid" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Emi-Ob-27Q"/>
+                                <constraint firstItem="Bkz-DV-HVr" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="LSz-FM-x2V"/>
+                                <constraint firstItem="f4E-5p-Bid" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.7" id="MdM-ps-4b8"/>
+                                <constraint firstAttribute="trailing" secondItem="Bkz-DV-HVr" secondAttribute="trailing" constant="10" id="MdM-yF-pmK"/>
+                                <constraint firstItem="WSe-uz-Uhz" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Pyf-oT-PQl"/>
+                                <constraint firstItem="WSe-uz-Uhz" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="YG6-eX-oTj"/>
+                                <constraint firstItem="Bkz-DV-HVr" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="10" id="mwG-d2-HQL"/>
+                                <constraint firstAttribute="trailing" secondItem="f4E-5p-Bid" secondAttribute="trailing" constant="10" id="svU-xx-LsR"/>
+                            </constraints>
+                            <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                    <color key="value" red="0.42745098039215684" green="0.41176470588235292" blue="0.56470588235294117" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                    <real key="value" value="1"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="3"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="wLM-VU-VYk" firstAttribute="bottom" secondItem="2hI-rc-KPm" secondAttribute="bottom" constant="10" id="39K-W7-EIE"/>
+                        <constraint firstAttribute="trailing" secondItem="wLM-VU-VYk" secondAttribute="trailing" constant="10" id="HSF-55-R5c"/>
+                        <constraint firstAttribute="height" constant="120" id="PdT-5v-I0r"/>
+                        <constraint firstItem="wLM-VU-VYk" firstAttribute="top" secondItem="2hI-rc-KPm" secondAttribute="top" constant="10" id="fWN-oO-QzS"/>
+                        <constraint firstItem="wLM-VU-VYk" firstAttribute="leading" secondItem="2hI-rc-KPm" secondAttribute="leading" constant="10" id="teN-oh-Db9"/>
+                    </constraints>
+                    <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                            <real key="value" value="0.0"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <constraints>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="Kwy-25-YES"/>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="clR-QU-zlD"/>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="htS-q0-otF"/>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="rig-k7-6bz"/>
+            </constraints>
+            <nil key="simulatedStatusBarMetrics"/>
+            <userDefinedRuntimeAttributes>
+                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                    <real key="value" value="0.0"/>
+                </userDefinedRuntimeAttribute>
+            </userDefinedRuntimeAttributes>
+            <point key="canvasLocation" x="45.5" y="-43.5"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="PhotoPlaceholder" width="170" height="108"/>
+    </resources>
 </document>

+ 18 - 9
app/RowHomeFutureActivities.swift

@@ -26,21 +26,16 @@ Extension of UIView to be formatted as sections.
 */
 @IBDesignable class RowHomeFutureActivities: UIView {
 	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
-	
-	//The activity title.
 	@IBOutlet weak var title: UILabel!
-	
-	//The activity description.
 	@IBOutlet weak var descrip: UILabel!
-	
-	//The activity image.
 	@IBOutlet weak var image: UIImageView!
 	
+	// Activity ID.
+	var id: Int = -1;
+	
 	
 	/**
 	Default constructor
@@ -76,6 +71,11 @@ Extension of UIView to be formatted as sections.
 		
 		self.container.frame = self.bounds
 		self.addSubview(container)
+		
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeFutureActivities.openActivity (_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	
 	
@@ -120,4 +120,13 @@ Extension of UIView to be formatted as sections.
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 	}
+	
+	
+	/**
+	Opens an activity.
+	*/
+	func openActivity(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showFutureActivity(id: self.id)
+	}
 }

+ 109 - 109
app/RowHomeFutureActivities.xib

@@ -1,111 +1,111 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16B2657" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-<device id="retina4_7" orientation="portrait">
-<adaptation id="fullscreen"/>
-</device>
-<dependencies>
-<deployment identifier="iOS"/>
-<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
-<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
-<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-</dependencies>
-<objects>
-<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RowHomeFutureActivities" customModule="app">
-<connections>
-<outlet property="container" destination="2hI-rc-KPm" id="rWX-Vl-kOp"/>
-<outlet property="descrip" destination="f4E-5p-Bid" id="IF5-ck-qUL"/>
-<outlet property="entry" destination="wLM-VU-VYk" id="Gkq-yE-fdN"/>
-<outlet property="image" destination="WSe-uz-Uhz" id="iU4-jm-UzQ"/>
-<outlet property="title" destination="Bkz-DV-HVr" id="1ok-yI-Npt"/>
-</connections>
-</placeholder>
-<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-<view contentMode="scaleToFill" id="iN0-l3-epB" userLabel="RowHomePastActivities" customClass="RowHomePastActivities" customModule="app">
-<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
-<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-<subviews>
-<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2hI-rc-KPm" userLabel="Container">
-<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
-<subviews>
-<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wLM-VU-VYk" userLabel="Entry">
-<rect key="frame" x="10" y="10" width="355" height="667"/>
-<subviews>
-<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bkz-DV-HVr" userLabel="Title">
-<rect key="frame" x="10" y="10" width="335" height="21.5"/>
-<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
-<color key="textColor" red="0.15294117647058825" green="0.33333333333333331" blue="0.45098039215686275" alpha="1" colorSpace="calibratedRGB"/>
-<nil key="highlightedColor"/>
-</label>
-<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="WSe-uz-Uhz" userLabel="Image">
-<rect key="frame" x="10" y="40" width="89" height="64"/>
-<constraints>
-<constraint firstAttribute="height" constant="64" id="EJ3-uo-Xp3"/>
-</constraints>
-</imageView>
-<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f4E-5p-Bid" userLabel="Text">
-<rect key="frame" x="98" y="40" width="214" height="64"/>
-<fontDescription key="fontDescription" type="system" pointSize="17"/>
-<nil key="textColor"/>
-<nil key="highlightedColor"/>
-</label>
-</subviews>
-<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
-<constraints>
-<constraint firstItem="WSe-uz-Uhz" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.2" id="9Lz-WQ-1aS"/>
-<constraint firstItem="f4E-5p-Bid" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Emi-Ob-27Q"/>
-<constraint firstItem="Bkz-DV-HVr" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="LSz-FM-x2V"/>
-<constraint firstItem="f4E-5p-Bid" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.7" id="MdM-ps-4b8"/>
-<constraint firstAttribute="trailing" secondItem="Bkz-DV-HVr" secondAttribute="trailing" constant="10" id="MdM-yF-pmK"/>
-<constraint firstItem="WSe-uz-Uhz" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Pyf-oT-PQl"/>
-<constraint firstItem="WSe-uz-Uhz" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="YG6-eX-oTj"/>
-<constraint firstItem="Bkz-DV-HVr" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="10" id="mwG-d2-HQL"/>
-<constraint firstAttribute="trailing" secondItem="f4E-5p-Bid" secondAttribute="trailing" constant="10" id="svU-xx-LsR"/>
-</constraints>
-<edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
-<userDefinedRuntimeAttributes>
-<userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-<color key="value" red="0.42745098039215684" green="0.41176470588235292" blue="0.56470588235294117" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-</userDefinedRuntimeAttribute>
-<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-<real key="value" value="1"/>
-</userDefinedRuntimeAttribute>
-<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-<real key="value" value="3"/>
-</userDefinedRuntimeAttribute>
-</userDefinedRuntimeAttributes>
-</view>
-</subviews>
-<constraints>
-<constraint firstItem="wLM-VU-VYk" firstAttribute="bottom" secondItem="2hI-rc-KPm" secondAttribute="bottom" constant="10" id="39K-W7-EIE"/>
-<constraint firstAttribute="trailing" secondItem="wLM-VU-VYk" secondAttribute="trailing" constant="10" id="HSF-55-R5c"/>
-<constraint firstAttribute="height" constant="120" id="PdT-5v-I0r"/>
-<constraint firstItem="wLM-VU-VYk" firstAttribute="top" secondItem="2hI-rc-KPm" secondAttribute="top" constant="10" id="fWN-oO-QzS"/>
-<constraint firstItem="wLM-VU-VYk" firstAttribute="leading" secondItem="2hI-rc-KPm" secondAttribute="leading" constant="10" id="teN-oh-Db9"/>
-</constraints>
-<edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
-<userDefinedRuntimeAttributes>
-<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-<real key="value" value="0.0"/>
-</userDefinedRuntimeAttribute>
-</userDefinedRuntimeAttributes>
-</view>
-</subviews>
-<constraints>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="Kwy-25-YES"/>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="clR-QU-zlD"/>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="htS-q0-otF"/>
-<constraint firstItem="2hI-rc-KPm" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="rig-k7-6bz"/>
-</constraints>
-<nil key="simulatedStatusBarMetrics"/>
-<userDefinedRuntimeAttributes>
-<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-<real key="value" value="0.0"/>
-</userDefinedRuntimeAttribute>
-</userDefinedRuntimeAttributes>
-<point key="canvasLocation" x="45.5" y="-43.5"/>
-</view>
-</objects>
-<resources>
-<image name="PhotoPlaceholder" width="170" height="108"/>
-</resources>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RowHomeFutureActivities" customModule="app">
+            <connections>
+                <outlet property="container" destination="2hI-rc-KPm" id="rWX-Vl-kOp"/>
+                <outlet property="descrip" destination="f4E-5p-Bid" id="IF5-ck-qUL"/>
+                <outlet property="entry" destination="wLM-VU-VYk" id="Gkq-yE-fdN"/>
+                <outlet property="image" destination="WSe-uz-Uhz" id="iU4-jm-UzQ"/>
+                <outlet property="title" destination="Bkz-DV-HVr" id="1ok-yI-Npt"/>
+            </connections>
+        </placeholder>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" userLabel="RowHomePastActivities" customClass="RowHomePastActivities" customModule="app">
+            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2hI-rc-KPm" userLabel="Container">
+                    <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wLM-VU-VYk" userLabel="Entry">
+                            <rect key="frame" x="10" y="10" width="355" height="667"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bkz-DV-HVr" userLabel="Title">
+                                    <rect key="frame" x="10" y="10" width="335" height="21.5"/>
+                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
+                                    <color key="textColor" red="0.15294117647058825" green="0.33333333333333331" blue="0.45098039215686275" alpha="1" colorSpace="calibratedRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="WSe-uz-Uhz" userLabel="Image">
+                                    <rect key="frame" x="10" y="40" width="71" height="64"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="64" id="EJ3-uo-Xp3"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f4E-5p-Bid" userLabel="Text">
+                                    <rect key="frame" x="96.5" y="40" width="248.5" height="20.5"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                    <nil key="textColor"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                            </subviews>
+                            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstItem="WSe-uz-Uhz" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.2" id="9Lz-WQ-1aS"/>
+                                <constraint firstItem="f4E-5p-Bid" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Emi-Ob-27Q"/>
+                                <constraint firstItem="Bkz-DV-HVr" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="LSz-FM-x2V"/>
+                                <constraint firstItem="f4E-5p-Bid" firstAttribute="width" secondItem="wLM-VU-VYk" secondAttribute="width" multiplier="0.7" id="MdM-ps-4b8"/>
+                                <constraint firstAttribute="trailing" secondItem="Bkz-DV-HVr" secondAttribute="trailing" constant="10" id="MdM-yF-pmK"/>
+                                <constraint firstItem="WSe-uz-Uhz" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="40" id="Pyf-oT-PQl"/>
+                                <constraint firstItem="WSe-uz-Uhz" firstAttribute="leading" secondItem="wLM-VU-VYk" secondAttribute="leading" constant="10" id="YG6-eX-oTj"/>
+                                <constraint firstItem="Bkz-DV-HVr" firstAttribute="top" secondItem="wLM-VU-VYk" secondAttribute="top" constant="10" id="mwG-d2-HQL"/>
+                                <constraint firstAttribute="trailing" secondItem="f4E-5p-Bid" secondAttribute="trailing" constant="10" id="svU-xx-LsR"/>
+                            </constraints>
+                            <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                    <color key="value" red="0.42745098039215684" green="0.41176470588235292" blue="0.56470588235294117" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                    <real key="value" value="1"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="3"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="wLM-VU-VYk" firstAttribute="bottom" secondItem="2hI-rc-KPm" secondAttribute="bottom" constant="10" id="39K-W7-EIE"/>
+                        <constraint firstAttribute="trailing" secondItem="wLM-VU-VYk" secondAttribute="trailing" constant="10" id="HSF-55-R5c"/>
+                        <constraint firstAttribute="height" constant="120" id="PdT-5v-I0r"/>
+                        <constraint firstItem="wLM-VU-VYk" firstAttribute="top" secondItem="2hI-rc-KPm" secondAttribute="top" constant="10" id="fWN-oO-QzS"/>
+                        <constraint firstItem="wLM-VU-VYk" firstAttribute="leading" secondItem="2hI-rc-KPm" secondAttribute="leading" constant="10" id="teN-oh-Db9"/>
+                    </constraints>
+                    <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                            <real key="value" value="0.0"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <constraints>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="Kwy-25-YES"/>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="clR-QU-zlD"/>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="htS-q0-otF"/>
+                <constraint firstItem="2hI-rc-KPm" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="rig-k7-6bz"/>
+            </constraints>
+            <nil key="simulatedStatusBarMetrics"/>
+            <userDefinedRuntimeAttributes>
+                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                    <real key="value" value="0.0"/>
+                </userDefinedRuntimeAttribute>
+            </userDefinedRuntimeAttributes>
+            <point key="canvasLocation" x="45.5" y="-43.5"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="PhotoPlaceholder" width="170" height="108"/>
+    </resources>
 </document>

+ 78 - 2
app/RowHomeGallery.swift

@@ -34,6 +34,9 @@ Extension of UIView to be formatted as sections.
 	
 	var photos: [UIImageView] = []
 	
+	var photoIds: [Int] = [-1, -1, -1, -1]
+	var albumIds: [Int] = [-1, -1, -1, -1]
+	
 	
 	/**
 	Default constructor
@@ -49,7 +52,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first as! UIView
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
 	
@@ -61,7 +64,14 @@ Extension of UIView to be formatted as sections.
 	init(s: String, i: Int) {
 		super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
 		loadViewFromNib()
-		self.addSubview(self.container)
+		
+		self.frame = self.bounds
+		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		self.translatesAutoresizingMaskIntoConstraints = true
+		self.container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		self.container.translatesAutoresizingMaskIntoConstraints = true
+		self.container.frame = self.bounds
+		self.addSubview(container)
 		
 		self.photos = [photo0, photo1, photo2, photo3]
 		
@@ -70,6 +80,42 @@ Extension of UIView to be formatted as sections.
 	}
 	
 	
+	/**
+	Open the first photo in the photo viewer.
+	*/
+	func openFirstPhoto(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPhoto(album: self.albumIds[0], photo: self.photoIds[0])
+	}
+	
+	
+	/**
+	Open the second photo in the photo viewer.
+	*/
+	func openSecondPhoto(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPhoto(album: self.albumIds[1], photo: self.photoIds[1])
+	}
+	
+	
+	/**
+	Open the third photo in the photo viewer.
+	*/
+	func openThirdPhoto(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPhoto(album: self.albumIds[2], photo: self.photoIds[2])
+	}
+	
+	
+	/**
+	Open the fourth photo in the photo viewer.
+	*/
+	func openFourthPhoto(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPhoto(album: self.albumIds[3], photo: self.photoIds[3])
+	}
+	
+	
 	/**
 	Default constructor for the interface builder
 	*/
@@ -91,6 +137,36 @@ Extension of UIView to be formatted as sections.
 		else{
 			let path = "img/galeria/thumb/\(filename)"
 			photos[idx].setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+			
+			// Set tap recognizer
+			switch idx{
+				case 0:
+					let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeGallery.openFirstPhoto(_:)))
+					tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+					self.photos[idx].isUserInteractionEnabled = true
+					self.photos[idx].addGestureRecognizer(tapRecognizer)
+					break;
+				case 1:
+					let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeGallery.openSecondPhoto(_:)))
+					tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+					self.photos[idx].isUserInteractionEnabled = true
+					self.photos[idx].addGestureRecognizer(tapRecognizer)
+					break;
+				case 2:
+					let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeGallery.openThirdPhoto(_:)))
+					tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+					self.photos[idx].isUserInteractionEnabled = true
+					self.photos[idx].addGestureRecognizer(tapRecognizer)
+					break;
+				case 3:
+					let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeGallery.openFourthPhoto(_:)))
+					tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+					self.photos[idx].isUserInteractionEnabled = true
+					self.photos[idx].addGestureRecognizer(tapRecognizer)
+					break;
+				default:
+					NSLog(":ROWHOMEGALLERY:ERROR: Trying to set tap recognizer for invalid photo index \(idx).")
+			}
 		}
 	}
 	

+ 2 - 2
app/RowHomeGallery.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>

+ 20 - 11
app/RowHomePastActivities.swift

@@ -22,25 +22,20 @@ import Foundation
 import UIKit
 
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as past activity rows.
 */
 @IBDesignable class RowHomePastActivities: UIView {
 	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
-	
-	//The activity title.
 	@IBOutlet weak var title: UILabel!
-	
-	//The activity description.
 	@IBOutlet weak var descrip: UILabel!
-	
-	//The activity image.
 	@IBOutlet weak var image: UIImageView!
 	
+	// Activity ID.
+	var id: Int = -1;
+	
 	
 	/**
 	Default constructor
@@ -56,7 +51,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
 	
@@ -76,6 +71,11 @@ Extension of UIView to be formatted as sections.
 
 		self.container.frame = self.bounds
 		self.addSubview(container)
+		
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomePastActivities.openActivity (_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	
 	
@@ -120,4 +120,13 @@ Extension of UIView to be formatted as sections.
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 	}
+	
+	
+	/**
+	Opens an activity.
+	*/
+	func openActivity(_ sender:UITapGestureRecognizer? = nil){
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPastActivity(id: self.id)
+	}
 }

+ 10 - 5
app/RowHomePastActivities.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16B2657" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -36,14 +36,19 @@
                                     <color key="textColor" red="0.15294117647058825" green="0.33333333333333331" blue="0.45098039215686275" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                 </label>
-                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="WSe-uz-Uhz" userLabel="Image">
-                                    <rect key="frame" x="10" y="40" width="89" height="64"/>
+                                <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="WSe-uz-Uhz" userLabel="Image">
+                                    <rect key="frame" x="10" y="40" width="71" height="64"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="64" id="EJ3-uo-Xp3"/>
                                     </constraints>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                            <real key="value" value="0.0"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
                                 </imageView>
                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f4E-5p-Bid" userLabel="Text">
-                                    <rect key="frame" x="98" y="40" width="214" height="64"/>
+                                    <rect key="frame" x="96.5" y="40" width="248.5" height="20.5"/>
                                     <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                     <nil key="textColor"/>
                                     <nil key="highlightedColor"/>

+ 1 - 1
app/RowHomeSocial.swift

@@ -56,7 +56,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
 	/**

+ 168 - 0
app/RowItinerary.swift

@@ -0,0 +1,168 @@
+// Copyright (C) 2016 Inigo Valentin
+//
+// This file is part of the Gasteizko Margolariak IOS app.
+//
+// The Gasteizko Margolariak IOS app is free software: you can
+// redistribute it and/or modify it under the terms of the
+// GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// The Gasteizko Margolariak IOS app is distributed in the
+// hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with the Gasteizko Margolariak IOS app.
+// If not, see <http://www.gnu.org/licenses/>.
+
+import Foundation
+import UIKit
+
+/**
+Extension of UIView to be formatted an activity itinerary.
+*/
+@IBDesignable class RowItinerary: UIView {
+
+	
+	// Outlets
+	@IBOutlet weak var container: UIView!
+	@IBOutlet weak var lbTime: UILabel!
+	@IBOutlet weak var lbTitle: UILabel!
+	@IBOutlet weak var lbText: UILabel!
+	@IBOutlet weak var lbLocation: UILabel!
+	
+	var id: Int = -1
+	
+	/**
+	Default constructor
+	*/
+	required init?(coder aDecoder: NSCoder) {
+		super.init(coder: aDecoder)
+	}
+	
+	
+	/**
+	Loads the view from the xib with the same name as the class.
+	*/
+	private func loadViewFromNib() {
+		let bundle = Bundle(for: type(of: self))
+		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
+		nib.instantiate(withOwner: self, options: nil)
+	}
+	
+	
+	/**
+	Default constructor.
+	:param: s Custom identifier
+	:param: i Custom identifier
+	*/
+	init(s: String, i: Int) {
+		super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
+		loadViewFromNib()
+		self.frame = self.bounds
+		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		self.translatesAutoresizingMaskIntoConstraints = true
+		
+		container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		container.translatesAutoresizingMaskIntoConstraints = true
+		
+		container.frame = self.bounds
+		self.addSubview(container)
+	}
+	
+	
+	/**
+	Default constructor for the interface builder
+	*/
+	override init(frame: CGRect){
+		super.init(frame: frame)
+	}
+	
+	
+	/**
+	Sets the time of the event.
+	:param: str String with the time to set.
+	*/
+	func setStart(str: String){
+		self.lbTime.text = str
+	}
+	
+	
+	/**
+	Sets the time of the event.
+	:param: hours Hour of the event start.
+	:param: minutes Minutes of the event start.
+	*/
+	func setStart(hours: Int, minutes: Int){
+		var strMinutes: String = ""
+		if "\(minutes)".length == 1{
+			strMinutes = "0\(minutes)"
+		}
+		else{
+			strMinutes = "\(minutes)"
+		}
+		self.lbTime.text = "\(hours):\(strMinutes)"
+	}
+	
+	
+	/**
+	Sets the time of the event.
+	:param: dtime Datetime of the event start.
+	*/
+	func setStart(time: NSDate){
+		let calendar = Calendar.current
+		let hours = calendar.component(.hour, from: time as Date)
+		let minutes = calendar.component(.minute, from: time as Date)
+		var strMinutes: String = ""
+		if "\(minutes)".length == 1{
+			strMinutes = "0\(minutes)"
+		}
+		else{
+			strMinutes = "\(minutes)"
+		}
+		self.lbTime.text = "\(hours):\(strMinutes)"
+	}
+	
+	
+	/**
+	Sets the title of the event.
+	:param: text The title of the event.
+	*/
+	func setTitle(text: String){
+		self.lbTitle.text = text.decode().stripHtml()
+	}
+	
+	
+	/**
+	Sets the location of the event.
+	:param: text The location of the event.
+	*/
+	func setLocation(text: String){
+		self.lbLocation.text = text.decode().stripHtml()
+	}
+	
+	
+	/**
+	Sets the description of the event. Decodes HTML.
+	:param: text The new text.
+	*/
+	func setText(text: String){
+		self.lbText.text = text.decode().stripHtml()
+	}
+	
+	func setPlace(place: String, address: String){
+		self.lbLocation.text = place.decode().stripHtml()
+	}
+	
+	
+	/**
+	Opens an event dialog.
+	*/
+	func openItinerary(_ sender:UITapGestureRecognizer? = nil){
+		// TODO implement openItinerary.
+		NSLog(":ROWITINERARY:DEBUG: Open Itinerary")
+	}
+}

+ 139 - 0
app/RowItinerary.xib

@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="Rowitinerary" customModule="app" customModuleProvider="target">
+            <connections>
+                <outlet property="container" destination="EhP-FW-f8V" id="t03-Fa-qsA"/>
+                <outlet property="lbLocation" destination="uRl-ey-EbX" id="lHa-cl-mdu"/>
+                <outlet property="lbText" destination="qBt-Fr-7yc" id="uYt-t9-bvT"/>
+                <outlet property="lbTime" destination="9A7-eH-but" id="Ekg-l7-hwE"/>
+                <outlet property="lbTitle" destination="olV-oe-BVn" id="aXe-tE-yTK"/>
+            </connections>
+        </placeholder>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
+            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EhP-FW-f8V" userLabel="Container">
+                    <rect key="frame" x="0.5" y="273.5" width="375" height="120"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1UU-eM-8rG" userLabel="Entry">
+                            <rect key="frame" x="0.0" y="0.0" width="375" height="120"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9A7-eH-but" userLabel="Time">
+                                    <rect key="frame" x="10" y="10" width="55" height="22"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="55" id="cfM-Es-4BC"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
+                                    <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <imageView userInteractionEnabled="NO" alpha="0.75" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="04F-rE-gcn" userLabel="Line">
+                                    <rect key="frame" x="76" y="-0.5" width="2" height="120"/>
+                                    <color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="2" id="W5y-7c-FbE"/>
+                                    </constraints>
+                                </imageView>
+                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ScheduleBullet" translatesAutoresizingMaskIntoConstraints="NO" id="Pne-3z-V34" userLabel="Bullet">
+                                    <rect key="frame" x="67" y="11" width="20" height="20"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="20" id="2pe-00-Pl0"/>
+                                        <constraint firstAttribute="height" constant="20" id="uvd-36-GaV"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="olV-oe-BVn" userLabel="Title">
+                                    <rect key="frame" x="92" y="10" width="283" height="22"/>
+                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
+                                    <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Text" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qBt-Fr-7yc" userLabel="Text">
+                                    <rect key="frame" x="102" y="37" width="263" height="21"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                    <nil key="textColor"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Pinpoint" translatesAutoresizingMaskIntoConstraints="NO" id="Oyf-6H-nyi" userLabel="Pinpoint">
+                                    <rect key="frame" x="107" y="68" width="10" height="13"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="10" id="2XO-EO-huO"/>
+                                        <constraint firstAttribute="height" constant="13" id="SmO-lI-jeP"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Location" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uRl-ey-EbX">
+                                    <rect key="frame" x="122" y="66.5" width="243" height="17"/>
+                                    <fontDescription key="fontDescription" type="italicSystem" pointSize="14"/>
+                                    <color key="textColor" red="0.32931472080000002" green="0.32931472080000002" blue="0.32931472080000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                            </subviews>
+                            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstItem="Pne-3z-V34" firstAttribute="centerY" secondItem="9A7-eH-but" secondAttribute="centerY" id="1dN-8O-oB5"/>
+                                <constraint firstItem="uRl-ey-EbX" firstAttribute="trailing" secondItem="qBt-Fr-7yc" secondAttribute="trailing" id="6Oo-nZ-4s3"/>
+                                <constraint firstItem="Oyf-6H-nyi" firstAttribute="top" secondItem="qBt-Fr-7yc" secondAttribute="bottom" constant="10" id="A2q-yN-Iyq"/>
+                                <constraint firstItem="uRl-ey-EbX" firstAttribute="leading" secondItem="Oyf-6H-nyi" secondAttribute="trailing" constant="5" id="Bc8-R8-h8w"/>
+                                <constraint firstItem="9A7-eH-but" firstAttribute="leading" secondItem="1UU-eM-8rG" secondAttribute="leading" constant="10" id="Cs3-Oz-o5l"/>
+                                <constraint firstItem="qBt-Fr-7yc" firstAttribute="top" secondItem="olV-oe-BVn" secondAttribute="bottom" constant="5" id="DB6-Jb-AGq"/>
+                                <constraint firstItem="olV-oe-BVn" firstAttribute="leading" secondItem="Pne-3z-V34" secondAttribute="trailing" constant="5" id="JVf-b7-HDS"/>
+                                <constraint firstItem="qBt-Fr-7yc" firstAttribute="width" secondItem="olV-oe-BVn" secondAttribute="width" constant="-20" id="Nsn-Ui-8Ps"/>
+                                <constraint firstAttribute="trailing" secondItem="olV-oe-BVn" secondAttribute="trailing" id="Stw-8D-5t9"/>
+                                <constraint firstItem="uRl-ey-EbX" firstAttribute="centerY" secondItem="Oyf-6H-nyi" secondAttribute="centerY" id="TGQ-2i-XtB"/>
+                                <constraint firstItem="Oyf-6H-nyi" firstAttribute="leading" secondItem="qBt-Fr-7yc" secondAttribute="leading" constant="5" id="ZF0-zr-8EU"/>
+                                <constraint firstItem="04F-rE-gcn" firstAttribute="centerX" secondItem="Pne-3z-V34" secondAttribute="centerX" id="i3w-iX-ZQX"/>
+                                <constraint firstItem="Pne-3z-V34" firstAttribute="leading" secondItem="9A7-eH-but" secondAttribute="trailing" constant="2" id="iJ7-Ke-nqO"/>
+                                <constraint firstItem="9A7-eH-but" firstAttribute="top" secondItem="1UU-eM-8rG" secondAttribute="top" constant="10" id="joe-bR-4kc"/>
+                                <constraint firstItem="qBt-Fr-7yc" firstAttribute="centerX" secondItem="olV-oe-BVn" secondAttribute="centerX" id="phh-bC-fo7"/>
+                                <constraint firstItem="04F-rE-gcn" firstAttribute="top" secondItem="1UU-eM-8rG" secondAttribute="top" id="yPF-Ef-pJl"/>
+                                <constraint firstItem="olV-oe-BVn" firstAttribute="centerY" secondItem="9A7-eH-but" secondAttribute="centerY" id="zRU-yr-HSW"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                    <real key="value" value="0.0"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="0.0"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                    </subviews>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="120" id="S1t-ne-rLH"/>
+                        <constraint firstItem="1UU-eM-8rG" firstAttribute="leading" secondItem="EhP-FW-f8V" secondAttribute="leading" id="Sj6-i1-pJV"/>
+                        <constraint firstItem="04F-rE-gcn" firstAttribute="height" secondItem="EhP-FW-f8V" secondAttribute="height" id="cb8-Lg-GQP"/>
+                        <constraint firstItem="1UU-eM-8rG" firstAttribute="bottom" secondItem="EhP-FW-f8V" secondAttribute="bottom" id="iTi-VX-QEp"/>
+                        <constraint firstAttribute="trailing" secondItem="1UU-eM-8rG" secondAttribute="trailing" id="xDv-a5-7wM"/>
+                        <constraint firstAttribute="top" secondItem="1UU-eM-8rG" secondAttribute="top" id="y1f-q3-Um8"/>
+                    </constraints>
+                    <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                            <real key="value" value="0.0"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="EhP-FW-f8V" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="444-cT-i3J"/>
+                <constraint firstItem="EhP-FW-f8V" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="H8x-AV-wUI"/>
+                <constraint firstItem="EhP-FW-f8V" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="wxV-2s-Ojx"/>
+            </constraints>
+        </view>
+    </objects>
+    <resources>
+        <image name="Pinpoint" width="10" height="13"/>
+        <image name="ScheduleBullet" width="12" height="12"/>
+    </resources>
+</document>

+ 1 - 1
app/RowLabel.swift

@@ -46,7 +46,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
 	

+ 1 - 1
app/RowLablancaDay.swift

@@ -49,7 +49,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 		
 		self.frame = self.bounds
 		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]

+ 1 - 2
app/RowLablancaOffer.swift

@@ -48,7 +48,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 		
 		self.frame = self.bounds
 		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
@@ -68,7 +68,6 @@ Extension of UIView to be formatted as sections.
 	:param: i Custom identifier
 	*/
 	init(s: String, i: Int) {
-		NSLog(":ROWLABLANCAOFFER:DEBUG: Init \(s), \(i)")
 		
 		super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
 		loadViewFromNib()

+ 9 - 10
app/RowPastActivity.swift

@@ -26,15 +26,15 @@ Extension of UIView to be formatted as sections.
 */
 @IBDesignable class RowPastActivity: UIView {
 	
-	//This view
-	var v: UIView!
-	
 	// Outlets
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var descript: UILabel!
 	
+	// Activity ID.
+	var id = -1
+	
 	/**
 	Default constructor
 	*/
@@ -71,10 +71,9 @@ Extension of UIView to be formatted as sections.
 		self.addSubview(self.container)
 		
 		// Set tap recognizer
-		/*print("ROW_PAST_ACTIVITY:DEBUG: set tap recognizer")
-		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (self.openActivity (_:)))
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowPastActivity.openActivity (_:)))
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		addGestureRecognizer(tapRecognizer)*/
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	
 	
@@ -119,13 +118,13 @@ Extension of UIView to be formatted as sections.
 			image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 	}
-	
-	
+
+
 	/**
 	Opens an activity.
 	*/
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
-		// TODO: Implement openActivity.
-		NSLog(":ROW_PAST_ACTIVITY:DEBUG: open activity")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPastActivity(id: self.id)
 	}
 }

+ 3 - 3
app/RowPastActivity.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -35,7 +35,7 @@
                                     <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                 </label>
-                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="dtJ-G2-LyM" userLabel="Image">
+                                <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="dtJ-G2-LyM" userLabel="Image">
                                     <rect key="frame" x="10" y="40" width="71" height="64"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="64" id="5JB-2b-om6"/>

+ 2 - 8
app/RowSchedule.swift

@@ -49,7 +49,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil)
 	}
 	
 	
@@ -70,12 +70,6 @@ Extension of UIView to be formatted as sections.
 		
 		container.frame = self.bounds
 		self.addSubview(container)
-		
-		// Set tap recognizer
-		/*print("ROW_BLOG:DEBUG: set tap recognizer")
-		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (self.openPost (_:)))
-		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		addGestureRecognizer(tapRecognizer)*/
 	}
 	
 	
@@ -164,6 +158,6 @@ Extension of UIView to be formatted as sections.
 	*/
 	func openEvent(_ sender:UITapGestureRecognizer? = nil){
 		// TODO implement openEvent.
-		print("ROW_BLOG:DEBUG: Open Event")
+		NSLog(":ROWSCHEDULE:DEBUG: Open Event")
 	}
 }

+ 2 - 3
app/ScheduleViewController.swift

@@ -259,7 +259,7 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 			for r in searchResults! {
 				
 				title = r.value(forKey: "title_\(lang!)") as! String
-				if let tx = r.value(forKey: "description_\(lang!)"){
+				if r.value(forKey: "description_\(lang!)") != nil{
 					text = r.value(forKey: "description_\(lang!)") as! String
 				}
 				else{
@@ -279,7 +279,7 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 				locationFetchRequest.fetchLimit = 1
 				do{
 					var locationSearchResults = try self.context?.fetch(locationFetchRequest)
-					var locationR = locationSearchResults?[0]
+					let locationR = locationSearchResults?[0]
 					location = locationR?.value(forKey: "name_\(lang!)")! as! String
 					
 					row.setLocation(text: location)
@@ -325,7 +325,6 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 	:param: increment Days to advance the schedule. Negative values to back it up.
 	*/
 	func changeDay(increment: Int){
-		NSLog(":SCHEDULECONTROLLER:DEBUG: Change day increment: \(increment)")
 		self.selectedDay = self.selectedDay + increment
 		if self.selectedDay <= -1{
 			self.selectedDay = 0

+ 134 - 65
app/Sync.swift

@@ -28,7 +28,12 @@ Class to handle server sync.
 class Sync{
 	
 	var initial: Bool = false
-	
+	var vBlog: Int = 0
+	var vActivities: Int = 0
+	var vGallery: Int = 0
+	var vBlanca: Int = 0
+	var vAll: Int = 0
+		
 	/**
 	Starts the sync process.
 	Always asynchronously.
@@ -46,6 +51,7 @@ class Sync{
 		if synchronous == true{
 			NSLog(":SYNC:LOG: Synchronous sync started.")
 			self.initial = true
+			
 		}
 		let url = buildUrl();
 		sync(url: url)
@@ -56,19 +62,41 @@ class Sync{
 	:returns: The URL.
 	*/
 	func buildUrl() -> URL{
-		let url = URL(string: "https://margolariak.com/API/v1/sync.php?client=com.margolariak.app")
-		//TODO add parameters
+		let defaults = UserDefaults.standard
+		var uId: String = "unknown"
+		if defaults.value(forKey: "versionAll") != nil{
+			self.vAll = defaults.value(forKey: "versionAll") as! Int
+		}
+		if defaults.value(forKey: "versionBlog") != nil{
+			self.vAll = defaults.value(forKey: "versionBlog") as! Int
+		}
+		if defaults.value(forKey: "versionActivities") != nil{
+			self.vActivities = defaults.value(forKey: "versionActivities") as! Int
+		}
+		if defaults.value(forKey: "versionGallery") != nil{
+			self.vGallery = defaults.value(forKey: "versionGallery") as! Int
+		}
+		if defaults.value(forKey: "versionBlanca") != nil{
+			self.vBlanca = defaults.value(forKey: "versionBlanca") as! Int
+		}
+		if defaults.value(forKey: "userId") != nil{
+			uId = defaults.value(forKey: "userId") as! String
+		}
+		let url = URL(string: "https://margolariak.com/API/v1/sync.php?client=com.margolariak.app&user=\(uId)&action=sync&version=\(self.vAll)")
+		
 		return url!
 	}
 	
 	/**
 	Performs an asynchronous sync.
-	It fethes the info from the server and stores as Core Data
+	It fetches the info from the server and stores as Core Data
 	:param: url The url to sync.
 	*/
 	func sync(url: URL){
 		
 		NSLog(":SYNC:LOG: Sync started.")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.syncController?.nowSyncing = true
 		
 		//Synchronously get data
 		let task = URLSession.shared.dataTask(with: url) { data, response, error in
@@ -82,71 +110,101 @@ class Sync{
 			}
 			
 			NSLog(":SYNC:LOG: Data received.")
+			let defaults = UserDefaults.standard
 			
 			var strData = String(data:data, encoding: String.Encoding.utf8)
 			
+			var strVersions = ""
+			if strData != nil{
+				strVersions = (strData?.subStr(start : (strData?.indexOf(target : "\"version\":")!)! + 11, end : (strData?.indexOf(target : "}]}")!)! + 1))!
+			}
+			var vrAll: Int = 0
+			var vrBlog: Int = 0
+			var vrActivities: Int = 0
+			var vrGallery: Int = 0
+			var vrBlanca: Int = 0
+			vrAll = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"all\":")! + 7, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",")! + 1, end : strVersions.length - 1)
+			vrBlog = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"blog\":")! + 8, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",")! + 1, end : strVersions.length - 1)
+			vrActivities = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"activities\":")! + 14, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",")! + 1, end : strVersions.length - 1)
+			vrGallery = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"gallery\":")! + 11, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",")! + 1, end : strVersions.length - 1)
+			vrBlanca = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"lablanca\":")! + 12, end : strVersions.indexOf(target : "}")!-2))!
+			
 			let dataIdx = strData?.indexOf(target: "{\"data\"")
 			strData = strData!.subStr(start: dataIdx!, end: strData!.length - 1)
 			
-			//TODO: do something with versions
-			
-			//Get tables
-			let dataActivity : [String] = self.getTable(data: strData!, table: "activity")
-			let dataActivityComment : [String] = self.getTable(data: strData!, table: "activity_comment")
-			let dataActivityImage : [String] = self.getTable(data: strData!, table: "activity_image")
-			let dataActivityTag : [String] = self.getTable(data: strData!, table: "activity_tag")
-			let dataActivityItinerary : [String] = self.getTable(data: strData!, table: "activity_itinerary")
-			let dataAlbum : [String] = self.getTable(data: strData!, table: "album")
-			let dataFestival : [String] = self.getTable(data: strData!, table: "festival")
-			let dataFestivalDay : [String] = self.getTable(data: strData!, table: "festival_day")
-			let dataFestivalEvent : [String] = self.getTable(data: strData!, table: "festival_event")
-			//let dataFestivalEventImage : [String] = self.getTable(data: strData!, table: "festival_event_image")
-			let dataFestivalOffer : [String] = self.getTable(data: strData!, table: "festival_offer")
-			let dataPeople : [String] = self.getTable(data: strData!, table: "people")
-			let dataPhoto : [String] = self.getTable(data: strData!, table: "photo")
-			let dataPhotoAlbum : [String] = self.getTable(data: strData!, table: "photo_album")
-			//let dataPhotoComment : [String] = self.getTable(data: strData!, table: "photo_comment")
-			let dataPlace : [String] = self.getTable(data: strData!, table: "place")
-			let dataPost : [String] = self.getTable(data: strData!, table: "post")
-			let dataPostComment : [String] = self.getTable(data: strData!, table: "post_comment")
-			let dataPostImage : [String] = self.getTable(data: strData!, table: "post_image")
-			let dataPostTag : [String] = self.getTable(data: strData!, table: "post_tag")
+			//Get tables and save them
+			if vrActivities > self.vActivities || vrBlanca > self.vBlanca{
+				let dataPlace : [String] = self.getTable(data: strData!, table: "place")
+				self.saveTablePlace(entries: dataPlace)
+			}
+			if vrActivities > self.vActivities {
+				let dataActivity : [String] = self.getTable(data: strData!, table: "activity")
+				self.saveTableActivity(entries : dataActivity)
+				let dataActivityComment : [String] = self.getTable(data: strData!, table: "activity_comment")
+				self.saveTableActivityComment(entries : dataActivityComment)
+				let dataActivityImage : [String] = self.getTable(data: strData!, table: "activity_image")
+				self.saveTableActivityImage(entries : dataActivityImage)
+				let dataActivityTag : [String] = self.getTable(data: strData!, table: "activity_tag")
+				self.saveTableActivityTag(entries : dataActivityTag)
+				let dataActivityItinerary : [String] = self.getTable(data: strData!, table: "activity_itinerary")
+				self.saveTableActivityItinerary(entries : dataActivityItinerary)
+				defaults.set(vrActivities, forKey: "versionActivities")
+			}
+			if vrBlanca > self.vBlanca {
+				let dataPeople : [String] = self.getTable(data: strData!, table: "people")
+				self.saveTablePeople(entries: dataPeople)
+				let dataFestival : [String] = self.getTable(data: strData!, table: "festival")
+				self.saveTableFestival(entries: dataFestival)
+				let dataFestivalDay : [String] = self.getTable(data: strData!, table: "festival_day")
+				self.saveTableFestivalDay(entries: dataFestivalDay)
+				let dataFestivalEvent : [String] = self.getTable(data: strData!, table: "festival_event")
+				self.saveTableFestivalEvent(entries: dataFestivalEvent)
+				//let dataFestivalEventImage : [String] = self.getTable(data: strData!, table: "festival_event_image")
+				//
+				let dataFestivalOffer : [String] = self.getTable(data: strData!, table: "festival_offer")
+				self.saveTableFestivalOffer(entries: dataFestivalOffer)
+				defaults.set(vrBlanca, forKey: "versionBlanca")
+			}
+			if vrGallery > self.vGallery {
+				let dataAlbum : [String] = self.getTable(data: strData!, table: "album")
+				self.saveTableAlbum(entries: dataAlbum)
+				let dataPhoto : [String] = self.getTable(data: strData!, table: "photo")
+				self.saveTablePhoto(entries: dataPhoto)
+				let dataPhotoAlbum : [String] = self.getTable(data: strData!, table: "photo_album")
+				self.saveTablePhotoAlbum(entries: dataPhotoAlbum)
+				//let dataPhotoComment : [String] = self.getTable(data: strData!, table: "photo_comment")
+				//
+				defaults.set(vrGallery, forKey: "versionGallery")
+			}
+			if vrBlog > self.vBlog {
+				let dataPost : [String] = self.getTable(data: strData!, table: "post")
+				self.saveTablePost(entries: dataPost)
+				let dataPostComment : [String] = self.getTable(data: strData!, table: "post_comment")
+				self.saveTablePostComment(entries: dataPostComment)
+				let dataPostImage : [String] = self.getTable(data: strData!, table: "post_image")
+				self.saveTablePostImage(entries: dataPostImage)
+				let dataPostTag : [String] = self.getTable(data: strData!, table: "post_tag")
+				self.saveTablePostTag(entries: dataPostTag)
+				defaults.set(vrBlog, forKey: "versionBlog")
+			}
 			let dataSponsor : [String] = self.getTable(data: strData!, table: "sponsor")
-			let dataSettings: [String] = self.getTable(data: strData!, table: "settings")
-			
-			//One by one, save the received data
-			self.saveTableActivity(entries : dataActivity)
-			self.saveTableActivityComment(entries : dataActivityComment)
-			self.saveTableActivityImage(entries : dataActivityImage)
-			self.saveTableActivityTag(entries : dataActivityTag)
-			self.saveTableActivityItinerary(entries : dataActivityItinerary)
-			
-			self.saveTablePost(entries: dataPost)
-			self.saveTablePostComment(entries: dataPostComment)
-			self.saveTablePostImage(entries: dataPostImage)
-			self.saveTablePostTag(entries: dataPostTag)
-			
-			self.saveTablePlace(entries: dataPlace)
-			self.saveTablePeople(entries: dataPeople)
-			
-			self.saveTableAlbum(entries: dataAlbum)
-			self.saveTablePhoto(entries: dataPhoto)
-			self.saveTablePhotoAlbum(entries: dataPhotoAlbum)
-			
-			self.saveTableFestival(entries: dataFestival)
-			self.saveTableFestivalDay(entries: dataFestivalDay)
-			self.saveTableFestivalOffer(entries: dataFestivalOffer)
-			self.saveTableFestivalEvent(entries: dataFestivalEvent)
-			
 			self.saveTableSponsor(entries: dataSponsor)
-			
+			let dataSettings: [String] = self.getTable(data: strData!, table: "settings")
 			self.saveSettings(entries: dataSettings)
-			
+			defaults.set(vrAll, forKey: "versionAll")
+				
+
 			// If it's the initial sync, hide the segue
 			if self.initial == true{
 				NSLog(":SYNC:LOG: Finishing synchronous sync.")
+				//let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+				//delegate.syncController?.startApp()
 				let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-				delegate.controller?.initialSync(showScreen: false)
+				delegate.syncController?.nowSyncing = false
 			}
 		}
 		
@@ -493,9 +551,9 @@ class Sync{
 			var str = entry
 			let id : Int = Int(str.subStr(start : str.indexOf(target : "\"id\":")! + 6, end : str.indexOf(target : ",\"")! - 2))!
 			
-			//Get activity
+			//Get post
 			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
-			let post : String = str.subStr(start : str.indexOf(target : "\"post\":")! + 8, end : str.indexOf(target : ",\"")! - 2)
+			let post : Int = Int(str.subStr(start : str.indexOf(target : "\"post\":")! + 8, end : str.indexOf(target : ",\"")! - 2))!
 			
 			//Get text
 			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
@@ -503,7 +561,7 @@ class Sync{
 			
 			//Get dtime
 			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
-			dateFormatter.dateFormat = "yyyy-MM-dd"
+			dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
 			let dtime = dateFormatter.date(from : str.subStr(start : str.indexOf(target : "\"dtime\":")! + 9, end : str.indexOf(target : ",\"")! - 2))!
 			
 			//Get username
@@ -1270,17 +1328,23 @@ class Sync{
 			//Get title_es
 			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
 			let title_es : String = str.subStr(start : str.indexOf(target : "\"title_es\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
-			row.setValue(title_es, forKey: "title_es")
+			if (title_es != "ul"){ //From "null"
+				row.setValue(title_es, forKey: "title_es")
+			}
 			
 			//Get title_en
 			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
 			let title_en : String = str.subStr(start : str.indexOf(target : "\"title_en\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
-			row.setValue(title_en, forKey: "title_en")
+			if (title_en != "ul"){ //From "null"
+				row.setValue(title_en, forKey: "title_en")
+			}
 			
 			//Get title_eu
 			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
 			let title_eu : String = str.subStr(start : str.indexOf(target : "\"title_eu\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
-			row.setValue(title_eu, forKey: "title_eu")
+			if (title_eu != "ul"){ //From "null"
+				row.setValue(title_eu, forKey: "title_eu")
+			}
 			
 			//Get description_es
 			str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
@@ -1758,11 +1822,16 @@ class Sync{
 
 			// Get day
 			// Special item, not in the sync content
-			dateFormatter.dateFormat = "yyyy-MM-dd"
-			var day = dateFormatter.date(from: str.subStr(start : str.indexOf(target : "\"start\":")! + 9, end : str.indexOf(target : ",\"")! - 11))!
+			dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
+			dateFormatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.ISO8601)! as Calendar
+			dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale!
+			dateFormatter.timeZone = NSTimeZone.local
+			let dayString = "\(str.subStr(start : str.indexOf(target : "\"start\":")! + 9, end : str.indexOf(target : ",\"")! - 11)) 00:00:00"
+			var day = dateFormatter.date(from: dayString)!
 			// If on the first hours of the next day...
 			let calendar = Calendar.current
-			let hours = calendar.component(.hour, from: day )
+			let hours = calendar.component(.hour, from: start )
+			
 			// ... the event belongs to the previous day.
 			if hours < 6{
 				day = Calendar.current.date(byAdding: .day, value: -1, to: day)!	

+ 72 - 5
app/SyncController.swift

@@ -26,6 +26,11 @@ The view controller of the app.
 */
 class SyncController: UIViewController{
 	
+	var delegate: AppDelegate?
+	
+	var nowSyncing: Bool = false
+	var syncTimer: Timer? = nil
+	
 	@IBOutlet weak var pb: UIProgressView!
 	@IBOutlet weak var lb: UILabel!
 	
@@ -39,18 +44,80 @@ class SyncController: UIViewController{
 	*/
 	override func viewDidLoad() {
 		
-		NSLog(":SYNC:LOG: SyncController shown.")
+		NSLog(":SYNCCONTROLLER:LOG: SyncController shown.")
+		self.delegate = UIApplication.shared.delegate as? AppDelegate
+		self.delegate?.syncController = self
 		
 		super.viewDidLoad()
 		
-		// Initial setup
-		pb.progress = 0
 		
-		// Start the timer
-		Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(progress), userInfo: nil, repeats: true)
 		
 	}
 	
+	override func viewDidAppear(_ animated: Bool) {
+		if UserDefaults.standard.object(forKey: "userId") == nil{
+			NSLog(":SYNCCONTROLLER:LOG: First run. Generating user ID and syncing...")
+			let newUid = randomString(length: 16)
+			let defaults = UserDefaults.standard
+			defaults.set(newUid, forKey: "userId")
+			// Initial setup
+			pb.progress = 0
+			
+			// Start the timer
+			Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(progress), userInfo: nil, repeats: true)
+			
+			syncTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(endSync), userInfo: nil, repeats: true)
+			
+			initialSync()
+		}
+		else{
+			startApp()
+		}
+	}
+	
+	func endSync(){
+		if self.nowSyncing == false{
+			syncTimer?.invalidate()
+			startApp()
+		}
+	}
+	
+	func startApp(){
+		performSegue(withIdentifier: "SegueInit", sender: nil)
+	}
+	
+	/**
+	Handles the initial sync process.
+	It can start it, showing the sync screen, or finish it, hidding the screen.
+	:param: showScreen True to start the sync, false to end it.
+	*/
+	func initialSync(){
+		//performSegue(withIdentifier: "SegueSync", sender: nil)
+		Sync(synchronous: true)
+	}
+	
+	
+	/**
+	Generates a random string to be used as a user identifier.
+	:param: length The length of the generated string.
+	:return: A random alphanumeric string with the indicated length.
+	*/
+	func randomString(length: Int) -> String {
+		
+		let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+		let len = UInt32(letters.length)
+		
+		var randomString = ""
+		
+		for _ in 0 ..< length {
+			let rand = arc4random_uniform(len)
+			var nextChar = letters.character(at: Int(rand))
+			randomString += NSString(characters: &nextChar, length: 1) as String
+		}
+		
+		return randomString
+	}
+	
 	
 	/**
 	Signal to update the progressbar and, maybe, the tag.

+ 2 - 6
app/UIImageView.swift

@@ -79,14 +79,10 @@ extension UIImageView {
 			let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
 				if let tempLocalUrl = tempLocalUrl, error == nil {
 					
-					// Success
-					if let statusCode = (response as? HTTPURLResponse)?.statusCode {
-						// TODO something.
-					}
-					
 					do {
 						try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
-					} catch (let writeError) {
+					}
+					catch (let writeError) {
 						NSLog(":IMAGE:ERROR: Error creating a file \(destinationFileUrl) : \(writeError)")
 					}
 					

+ 0 - 1
app/UIView.swift

@@ -63,7 +63,6 @@ import UIKit
 	
 	var parentViewController: ViewController? {
 		var parentResponder: UIResponder? = self
-		var i = 0
 		while parentResponder != nil {
 			parentResponder = parentResponder!.next
 			if let viewController = parentResponder as? ViewController {

+ 63 - 43
app/ViewController.swift

@@ -45,6 +45,7 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	
 	// Passed id to perform segues.
 	var passId: Int = -1
+	var passAlbum: Int = -1
 	
 	// Location-related variables.
 	var locationManager = CLLocationManager()
@@ -59,7 +60,7 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	:param: coder Coder.
 	*/
 	required init?(coder aDecoder: NSCoder) {
-		NSLog(":CONTROLLER:DEBUG: Init!")
+		NSLog(":CONTROLLER:DEBUG: Init.")
 		super.init(coder: aDecoder)
 		
 	}
@@ -85,29 +86,57 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	:param: id The post id.
 	*/
 	func showPost(id: Int){
-		NSLog(":CONTROLLER:DEBUG: Showing Post \(id)")
 		self.passId = id
 		performSegue(withIdentifier: "SeguePost", sender: nil)
 	}
 	
 	
+	/**
+	Shows a past activity.
+	:param: id The activity id.
+	*/
+	func showPastActivity(id: Int){
+		self.passId = id
+		performSegue(withIdentifier: "SeguePastActivity", sender: nil)
+	}
+	
+	
+	/**
+	Shows a future activity.
+	:param: id The activity id.
+	*/
+	func showFutureActivity(id: Int){
+		self.passId = id
+		performSegue(withIdentifier: "SegueFutureActivity", sender: nil)
+	}
+	
+	
 	/**
 	Shows an album.
 	:param: id The album id.
 	*/
 	func showAlbum(id: Int){
-		NSLog(":CONTROLLER:DEBUG: Showing album \(id)")
 		self.passId = id
 		performSegue(withIdentifier: "SegueAlbum", sender: nil)
 	}
 	
 	
+	/**
+	Shows a photo.
+	:param: id The album id.
+	*/
+	func showPhoto(album: Int, photo: Int){
+		self.passAlbum = album
+		self.passId = photo
+		performSegue(withIdentifier: "SeguePhoto", sender: nil)
+	}
+	
+	
 	/**
 	Shows a schedule.
 	:param: margolari True for the margolari schedule, false for the city one.
 	*/
 	func showSchedule(margolari: Bool){
-		NSLog(":CONTROLLER:DEBUG: Showing schedule. Margolari: \(margolari)")
 		if margolari == true{
 			self.passId = 1
 		}
@@ -118,19 +147,18 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	}
 	
 	
-	/**
+	/** 
 	Handles the initial sync process.
 	It can start it, showing the sync screen, or finish it, hidding the screen.
 	:param: showScreen True to start the sync, false to end it.
 	*/
 	func initialSync(showScreen: Bool){
 		if showScreen == true{
-			NSLog(":CONTROLLER:DEBUG: Showing initial sync screen.")
-			performSegue(withIdentifier: "SegueSync", sender: nil)
+			//performSegue(withIdentifier: "SegueSync", sender: nil)
 			Sync(synchronous: true)
 		}
 		else{
-			NSLog(":CONTROLLER:DEBUG: Re-populating views and hidding initial sync screen.")
+			// TODO CHECK this
 			NSLog(":CONTROLLER:DEBUG: Re-populating disabled: Throws error.")
 			//self.populate()
 			syncSegue?.destination.dismiss(animated: true, completion: nil)
@@ -144,13 +172,16 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	:sender: The calling view.
 	*/
 	override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-		NSLog(":CONTROLLER:DEBUG: preparing for segue '\(String(describing: segue.identifier))' with id \(self.passId)")
 		if segue.identifier == "SeguePost"{
 			(segue.destination as! PostViewController).id = passId
 		}
 		if segue.identifier == "SegueAlbum"{
 			(segue.destination as! AlbumViewController).id = passId
 		}
+		if segue.identifier == "SeguePhoto"{
+			(segue.destination as! PhotoViewController).photoId = passId
+			(segue.destination as! PhotoViewController).albumId = passAlbum
+		}
 		if segue.identifier == "SegueSchedule"{
 			if passId == 1{
 				(segue.destination as! ScheduleViewController).margolari = true
@@ -162,6 +193,17 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		if segue.identifier == "SegueSync"{
 			self.syncSegue = segue
 		}
+		if segue.identifier == "SeguePastActivity"{
+			(segue.destination as! PastActivityViewController).id = passId
+		}
+		if segue.identifier == "SegueFutureActivity"{
+			(segue.destination as! FutureActivityViewController).id = passId
+		}
+	}
+	
+	override func viewWillAppear(_ animated: Bool) {
+		self.populate()
+		super.viewWillAppear(animated)
 	}
 	
 	/**
@@ -185,14 +227,15 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		self.locationTimer = Timer.scheduledTimer(timeInterval: 90, target: self, selector: #selector(fetchLocation), userInfo: nil, repeats: true)
 				
 		NSLog(":CONTROLLER:DEBUG: Don't skyp sync")
-		Sync()
+		//NSLog(":CONTROLLER:DEBUG: Skyp sync")
+		//Notifications()
+		//Sync()
 
 		
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
 		self.delegate?.controller = self
 		
-		NSLog(":CONTROLLER:DEBUG: NOT Forcing a call to populate")
-		//self.populate()
+		//self.sectionCollection.visibleCells[0].isSelected = true
 		
 		super.viewDidLoad()
 		
@@ -207,8 +250,9 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	As of now, not working.
 	*/
 	func populate(){
+		// TODO Set this up.
 		if (self.containerViewHome != nil){
-			//(self.containerViewHome as HomeView).populate2()
+			//(self.containerViewHome as HomeView).populate()
 			//let ng = self.containerViewHome.dbgTxt
 			//NSLog("AAAAA \(ng)")
 		}
@@ -230,12 +274,12 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	*/
 	override func viewDidAppear(_ animated: Bool) {
 		super.viewDidAppear(animated)
-		if UserDefaults.standard.object(forKey: "userId") == nil{
+		/*if UserDefaults.standard.object(forKey: "userId") == nil{
 			let newUid = randomString(length: 16)
 			let defaults = UserDefaults.standard
 			defaults.set(newUid, forKey: "userId")
 			initialSync(showScreen: true)
-		}
+		}*/
 		
 	}
 	
@@ -286,23 +330,16 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	
 	//Make a cell for each section
 	func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-				
+		
 		//Get a reference to our storyboard cell
 		let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MenuCollectionViewCell
 		
 		//Set text
 		cell.label.text = self.items[indexPath.item]
 		
-		//Mark the first cell as selected...
-		if indexPath.item == selected{
-			cell.bar.backgroundColor = UIColor(red: 90/255, green: 180/255, blue: 255/255, alpha: 1)
-			cell.label.font = UIFont.boldSystemFont(ofSize: cell.label.font.pointSize)
-		}
-			
-		//... and the others as unselected
-		else{
-			cell.bar.backgroundColor = UIColor(red: 148/255, green: 209/255, blue: 255/255, alpha: 1)
-			cell.label.font = UIFont.systemFont(ofSize: cell.label.font.pointSize)
+		// Mark the first one as selected.
+		if indexPath.item == 0{
+			cell.isSelected = true
 		}
 		
 		return cell
@@ -320,21 +357,7 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	:param: selected Index of the selected item.
 	*/
 	@IBAction func showComponent(selected: Int) {
-		//Activate label
-		var i = 0
-		for cell in sectionCollection.visibleCells as! [MenuCollectionViewCell]{ //TODO: Not only visibles!
-			if i == selected + 1{
-				cell.bar.backgroundColor = UIColor(red: 90/255, green: 180/255, blue: 255/255, alpha: 1)
-				cell.label.font = UIFont.boldSystemFont(ofSize: cell.label.font.pointSize)
-			}
-			else{
-				cell.bar.backgroundColor = UIColor(red: 148/255, green: 209/255, blue: 255/255, alpha: 1)
-				cell.label.font = UIFont.systemFont(ofSize: cell.label.font.pointSize)
 				
-			}
-			i = i + 1
-		}
-		
 		//Show the view
 		if selected == 0 {
 			UIView.animate(withDuration: 0.5, animations: {
@@ -396,9 +419,6 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 				self.containerViewGallery.alpha = 1
 			})
 		}
-		
 	}
-
-
 }