diff --git a/app/controllers/ApplicationController.scala b/app/controllers/ApplicationController.scala index 25187015b5..9dc534b2db 100644 --- a/app/controllers/ApplicationController.scala +++ b/app/controllers/ApplicationController.scala @@ -15,11 +15,11 @@ import models.audit.AuditTaskInteractionTable import models.daos.slick.DBTableDefinitions.UserTable import models.label.TagTable.selectTagsByLabelType import models.street.StreetEdgePriorityTable -import models.utils.Configs +import models.utils.{CityInfo, Configs} import models.attribute.ConfigTable import play.api.Play import play.api.Play.current -import play.api.i18n.Messages +import play.api.i18n.{Lang, Messages} import java.util.Calendar import play.api.mvc._ import scala.concurrent.Future @@ -129,17 +129,15 @@ class ApplicationController @Inject() (implicit val env: Environment[User, Sessi WebpageActivityTable.save(WebpageActivity(0, user.userId.toString, ipAddress, "Visit_Index", timestamp)) // Get city configs. val cityStr: String = Play.configuration.getString("city-id").get - val cityName: String = Play.configuration.getString("city-params.city-name." + cityStr).get - val stateAbbreviation: String = Play.configuration.getString("city-params.state-abbreviation." + cityStr).get - val cityShortName: String = Play.configuration.getString("city-params.city-short-name." + cityStr).get val mapathonLink: Option[String] = ConfigTable.getMapathonEventLink // Get names and URLs for other cities so we can link to them on landing page. - val otherCityUrls: List[(String, String, String, String)] = Configs.getAllCityInfo(excludeCity = cityStr) + val lang: Lang = request.cookies.get("PLAY_LANG").map(l => Lang(l.value)).getOrElse(request.acceptLanguages.head) + val cityUrls: List[CityInfo] = Configs.getAllCityInfo(lang) // Get total audited distance. If using metric system, convert from miles to kilometers. val auditedDistance: Float = if (Messages("measurement.system") == "metric") StreetEdgePriorityTable.auditedStreetDistanceUsingPriority * 1.60934.toFloat else StreetEdgePriorityTable.auditedStreetDistanceUsingPriority - Future.successful(Ok(views.html.index("Project Sidewalk", Some(user), cityName, stateAbbreviation, cityShortName, mapathonLink, cityStr, otherCityUrls, auditedDistance))) + Future.successful(Ok(views.html.index("Project Sidewalk", Some(user), mapathonLink, cityUrls, auditedDistance))) } case None => if(qString.isEmpty){ @@ -374,10 +372,9 @@ class ApplicationController @Inject() (implicit val env: Environment[User, Sessi val timestamp: Timestamp = new Timestamp(Instant.now.toEpochMilli) val ipAddress: String = request.remoteAddress - // Get current city. - val cityStr: String = Play.configuration.getString("city-id").get // Get names and URLs for cities to display in Gallery dropdown. - val cityUrls: List[(String, String, String, String)] = Configs.getAllCityInfo() + val lang: Lang = request.cookies.get("PLAY_LANG").map(l => Lang(l.value)).getOrElse(request.acceptLanguages.head) + val cityInfo: List[CityInfo] = Configs.getAllCityInfo(lang) val labelTypes: List[(String, String)] = List( ("Assorted", Messages("gallery.all")), ("CurbRamp", Messages("curb.ramp")), @@ -403,7 +400,7 @@ class ApplicationController @Inject() (implicit val env: Environment[User, Sessi val activityStr: String = s"Visit_Gallery_LabelType=${labType}_Severity=${severityList}_Tags=${tagList}_Validations=$valOptions" WebpageActivityTable.save(WebpageActivity(0, user.userId.toString, ipAddress, activityStr, timestamp)) - Future.successful(Ok(views.html.gallery("Gallery", Some(user), cityStr, cityUrls, labType, labelTypes, severityList, tagList, valOptions))) + Future.successful(Ok(views.html.gallery("Gallery", Some(user), cityInfo, labType, labelTypes, severityList, tagList, valOptions))) case None => // Send them through anon signup so that there activities on sidewalk gallery are logged as anon. // UTF-8 codes needed to pass a URL that contains parameters: ? is %3F, & is %26 @@ -474,8 +471,8 @@ class ApplicationController @Inject() (implicit val env: Environment[User, Sessi WebpageActivityTable.save(WebpageActivity(0, user.userId.toString, ipAddress, "Visit_Map", timestamp)) val cityStr: String = Play.configuration.getString("city-id").get - val cityShortName: String = Play.configuration.getString("city-params.city-short-name." + cityStr).get - Future.successful(Ok(views.html.accessScoreDemo("Project Sidewalk - Explore Accessibility", Some(user), cityShortName))) + val cityNameShort: Option[String] = Play.configuration.getString(s"city-params.city-short-name.$cityStr") + Future.successful(Ok(views.html.accessScoreDemo("Project Sidewalk - Explore Accessibility", Some(user), cityStr, cityNameShort))) case None => Future.successful(Redirect("/anonSignUp?url=/demo")) } diff --git a/app/controllers/AuditController.scala b/app/controllers/AuditController.scala index fdf9ec397a..ea7ea077e2 100644 --- a/app/controllers/AuditController.scala +++ b/app/controllers/AuditController.scala @@ -136,15 +136,15 @@ class AuditController @Inject() (implicit val env: Environment[User, SessionAuth // mission, but only after every third explore mission after that. val completedMissions: Boolean = MissionTable.countCompletedMissions(user.userId, missionType = "audit") > 0 - val cityStr: String = Play.configuration.getString("city-id").get + val cityId: String = Play.configuration.getString("city-id").get val tutorialStreetId: Int = ConfigTable.getTutorialStreetId - val cityShortName: String = Play.configuration.getString("city-params.city-short-name." + cityStr).get + val cityNameShort: Option[String] = Play.configuration.getString("city-params.city-short-name." + cityId) if (missionSetProgress.missionType != "audit") { Future.successful(Redirect("/validate")) } else { // On the crowdstudy server, we want to assign users to a study group. - val response = Ok(views.html.explore("Project Sidewalk - Audit", task, mission, region.get, userRoute, missionSetProgress.numComplete, completedMissions, nextTempLabelId, Some(user), cityShortName, tutorialStreetId)) - if (cityStr == "crowdstudy" && studyGroup.nonEmpty) Future.successful(response.withCookies(Cookie("SIDEWALK_STUDY_GROUP", studyGroup, httpOnly = false))) + val response = Ok(views.html.explore("Project Sidewalk - Audit", task, mission, region.get, userRoute, missionSetProgress.numComplete, completedMissions, nextTempLabelId, Some(user), cityId, cityNameShort, tutorialStreetId)) + if (cityId == "crowdstudy" && studyGroup.nonEmpty) Future.successful(response.withCookies(Cookie("SIDEWALK_STUDY_GROUP", studyGroup, httpOnly = false))) else Future.successful(response) } // For anonymous users. @@ -201,13 +201,13 @@ class AuditController @Inject() (implicit val env: Environment[User, SessionAuth // mission, but only after every third explore mission after that. val completedMission: Boolean = MissionTable.countCompletedMissions(user.userId, missionType = "audit") > 0 - val cityStr: String = Play.configuration.getString("city-id").get + val cityId: String = Play.configuration.getString("city-id").get val tutorialStreetId: Int = ConfigTable.getTutorialStreetId - val cityShortName: String = Play.configuration.getString("city-params.city-short-name." + cityStr).get + val cityNameShort: Option[String] = Play.configuration.getString("city-params.city-short-name." + cityId) if (missionSetProgress.missionType != "audit") { Future.successful(Redirect("/validate")) } else { - Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", task, mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityShortName, tutorialStreetId))) + Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", task, mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityId, cityNameShort, tutorialStreetId))) } case None => Logger.error(s"Tried to explore region $regionId, but there is no neighborhood with that id.") @@ -267,9 +267,9 @@ class AuditController @Inject() (implicit val env: Environment[User, SessionAuth mission = MissionTable.resumeOrCreateNewAuditMission(userId, regionId, payPerMeter, tutorialPay).get } - val cityStr: String = Play.configuration.getString("city-id").get + val cityId: String = Play.configuration.getString("city-id").get val tutorialStreetId: Int = ConfigTable.getTutorialStreetId - val cityShortName: String = Play.configuration.getString("city-params.city-short-name." + cityStr).get + val cityNameShort: Option[String] = Play.configuration.getString("city-params.city-short-name." + cityId) if (missionSetProgress.missionType != "audit") { Future.successful(Redirect("/validate")) @@ -277,15 +277,15 @@ class AuditController @Inject() (implicit val env: Environment[User, SessionAuth // If user is an admin and a panoId or lat/lng are supplied, send to that location, o/w send to street. if (isAdmin(request.identity) && (startAtPano || startAtLatLng)) { panoId match { - case Some(panoId) => Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityShortName, tutorialStreetId, None, None, Some(panoId)))) + case Some(panoId) => Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityId, cityNameShort, tutorialStreetId, None, None, Some(panoId)))) case None => (lat, lng) match { - case (Some(lat), Some(lng)) => Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityShortName, tutorialStreetId, Some(lat), Some(lng)))) - case (_, _) => Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, None, cityShortName, tutorialStreetId))) + case (Some(lat), Some(lng)) => Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityId, cityNameShort, tutorialStreetId, Some(lat), Some(lng)))) + case (_, _) => Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, None, cityId, cityNameShort, tutorialStreetId))) } } } else { - Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityShortName, tutorialStreetId))) + Future.successful(Ok(views.html.explore("Project Sidewalk - Audit", Some(task), mission, region, None, missionSetProgress.numComplete, completedMission, nextTempLabelId, Some(user), cityId, cityNameShort, tutorialStreetId))) } } } diff --git a/app/controllers/ConfigController.scala b/app/controllers/ConfigController.scala index c50e9d41e6..fb58369101 100644 --- a/app/controllers/ConfigController.scala +++ b/app/controllers/ConfigController.scala @@ -34,15 +34,6 @@ class ConfigController @Inject() (implicit val env: Environment[User, SessionAut ))) } - /** - * Get the short version of the current city name. - */ - def getCityShortNameParam() = Action.async { implicit request => - val cityStr: String = Play.configuration.getString("city-id").get - val cityShortName: String = Play.configuration.getString("city-params.city-short-name." + cityStr).get - Future.successful(Ok(Json.obj("city_short_name" -> cityShortName))) - } - /** * Get all city-specific parameters needed for the API page demos. */ diff --git a/app/models/utils/Configs.scala b/app/models/utils/Configs.scala index a76f100413..bd6d2799d8 100644 --- a/app/models/utils/Configs.scala +++ b/app/models/utils/Configs.scala @@ -3,22 +3,35 @@ package models.utils import play.api.Play import play.api.Play.current import scala.collection.JavaConverters._ +import play.api.i18n.{Lang, Messages} + +case class CityInfo(cityId: String, countryId: String, cityNameShort: String, cityNameFormatted: String, URL: String, visibility: String) object Configs { /** - * Returns list of all cities -- (cityId, name + ", " + state, cityURL, visibility) -- excluding the city specified. + * Returns list of info for all cities, including formatted names (in current language), URL, visibility. */ - def getAllCityInfo(excludeCity: String = ""): List[(String, String, String, String)] = { + def getAllCityInfo(lang: Lang): List[CityInfo] = { + val currentCityId: String = Play.configuration.getString("city-id").get + val currentCountryId: String = Play.configuration.getString(s"city-params.country-id.$currentCityId").get val envType: String = Play.configuration.getString("environment-type").get + // Get names and URLs for cities to display in Gallery dropdown. - val cities: List[String] = - Play.configuration.getStringList("city-params.city-ids").get.asScala.toList.filterNot(_ == excludeCity) - val cityInfo: List[(String, String, String, String)] = cities.map { cityId => - val name: String = Play.configuration.getString("city-params.city-name." + cityId).get - val state: String = Play.configuration.getString("city-params.state-abbreviation." + cityId).get - val cityURL: String = Play.configuration.getString("city-params.landing-page-url." + envType + "." + cityId).get - val visibility: String = Play.configuration.getString("city-params.status." + cityId).get - (cityId, name + ", " + state, cityURL, visibility) + val cityIds: List[String] = Play.configuration.getStringList("city-params.city-ids").get.asScala.toList + val cityInfo: List[CityInfo] = cityIds.map { cityId => + val stateId: Option[String] = Play.configuration.getString(s"city-params.state-id.$cityId") + val countryId: String = Play.configuration.getString(s"city-params.country-id.$cityId").get + val cityURL: String = Play.configuration.getString(s"city-params.landing-page-url.$envType.$cityId").get + val visibility: String = Play.configuration.getString(s"city-params.status.$cityId").get + + // Get the name of the city in frequently used formats in the current language. + val cityName: String = Messages(s"city.name.$cityId")(lang) + val cityNameShort: String = Play.configuration.getString(s"city-params.city-short-name.$cityId").getOrElse(cityName) + val cityNameFormatted: String = if (currentCountryId == "usa" && stateId.isDefined && countryId == "usa") + Messages("city.state", cityName, Messages(s"state.name.${stateId.get}")(lang))(lang) + else + Messages("city.state", cityName, Messages(s"country.name.$countryId")(lang))(lang) + CityInfo(cityId, countryId, cityNameShort, cityNameFormatted, cityURL, visibility) } cityInfo } diff --git a/app/views/accessScoreDemo.scala.html b/app/views/accessScoreDemo.scala.html index 2a62657970..328e97aea6 100644 --- a/app/views/accessScoreDemo.scala.html +++ b/app/views/accessScoreDemo.scala.html @@ -1,5 +1,5 @@ @import models.user.User -@(title: String, user: Option[User] = None, cityShortName: String)(implicit lang: Lang) +@(title: String, user: Option[User] = None, cityId: String, cityNameShort: Option[String])(implicit lang: Lang) @main(title) { @navbar(user, Some("/demo")) @@ -16,7 +16,7 @@

Access Scorebeta in Action

- Find out about neighborhood accessibility of @cityShortName! Here, accessible neighborhoods are colored in green + Find out about neighborhood accessibility of @{cityNameShort.getOrElse(Messages(s"city.name.$cityId"))}! Here, accessible neighborhoods are colored in green and inaccessible neighborhoods are colored in red.

diff --git a/app/views/explore.scala.html b/app/views/explore.scala.html index b7dd4ed12d..20e48c0840 100644 --- a/app/views/explore.scala.html +++ b/app/views/explore.scala.html @@ -5,10 +5,9 @@ @import models.amt.AMTAssignmentTable @import models.route.UserRoute @import views.html.bootstrap._ -@import play.api.Play -@import play.api.Play.current -@(title: String, task: Option[models.audit.NewTask] = None, mission: Mission, region: Region, userRoute: Option[UserRoute], missionSetProgress: Int, hasCompletedMission: Boolean, nextTempLabelId: Int, user: Option[User] = None, cityShortName: String, tutorialStreetId: Int, lat: Option[Double] = None, lng: Option[Double] = None, panoId: Option[String] = None)(implicit lang: Lang) +@(title: String, task: Option[models.audit.NewTask] = None, mission: Mission, region: Region, userRoute: Option[UserRoute], missionSetProgress: Int, hasCompletedMission: Boolean, nextTempLabelId: Int, user: Option[User] = None, cityId: String, cityNameShort: Option[String], tutorialStreetId: Int, lat: Option[Double] = None, lng: Option[Double] = None, panoId: Option[String] = None)(implicit lang: Lang) +@cityName = @{cityNameShort.getOrElse(Messages(s"city.name.$cityId"))} @main(title, Some("/explore")) { @navbar(user, Some("/explore")) @@ -366,7 +365,7 @@

@Messages("audit.right.ui.overall.stats")

@Messages("audit.right.ui.current.neighborhood")

- @cityShortName + @cityName
@Messages( 0.00 @Messages("audit.right.ui.distance") @@ -1027,7 +1026,8 @@ } mainParam.language = "@lang.code"; - mainParam.cityId = "@Play.configuration.getString("city-id").get" + mainParam.cityId = "@cityId"; + mainParam.cityName = "@cityName"; svl.main = new Main(mainParam); } diff --git a/app/views/gallery.scala.html b/app/views/gallery.scala.html index 12523a7c31..d3bf3913fb 100644 --- a/app/views/gallery.scala.html +++ b/app/views/gallery.scala.html @@ -1,5 +1,9 @@ @import models.user.User -@(title: String, user: Option[User] = None, cityId: String, otherCityURLs: List[(String, String, String, String)], labelType: String, labels: List[(String, String)], severities: List[Int], tags: List[String], valOptions: List[String])(implicit lang: Lang) +@import models.utils.CityInfo +@import play.api.Play +@import play.api.Play.current +@(title: String, user: Option[User] = None, cityInfo: List[CityInfo], labelType: String, labels: List[(String, String)], severities: List[Int], tags: List[String], valOptions: List[String])(implicit lang: Lang) +@currentCity = @{cityInfo.filter(c => c.cityId == Play.configuration.getString("city-id").get).head} @main(title) { @@ -37,11 +41,11 @@

@Messages("navbar.city")

diff --git a/app/views/index.scala.html b/app/views/index.scala.html index bbd7e993b1..62b88d3943 100644 --- a/app/views/index.scala.html +++ b/app/views/index.scala.html @@ -5,8 +5,10 @@ @import play.api.Play.current @import models.street.StreetEdgePriorityTable @import models.attribute.ConfigTable -@(title: String, user: Option[User] = None, cityName: String, stateAbbreviation: String, cityShortName: String, mapathonLink: Option[String], cityId: String, otherCityURLs: List[(String, String, String, String)], auditedDistance: Float)(implicit lang: Lang) -@skylineImg =@{Play.configuration.getString("city-params.skyline-img." + cityId).get} +@import models.utils.CityInfo +@(title: String, user: Option[User] = None, mapathonLink: Option[String], cityInfo: List[CityInfo], auditedDistance: Float)(implicit lang: Lang) +@currentCity = @{cityInfo.filter(c => c.cityId == Play.configuration.getString("city-id").get).head} +@skylineImg =@{Play.configuration.getString("city-params.skyline-img." + currentCity.cityId).get} @main(title) { @navbar(user, Some("/")) @@ -30,16 +32,16 @@ @Messages("landing.create.path")


- @Messages("landing.start.exploring") @cityShortName + @Messages("landing.start.exploring") @currentCity.cityNameShort

@Messages("landing.also.in") - @for((id, cityName, cityURL, visible) <- Random.shuffle(otherCityURLs.filter(c => c._4 == "public")).take(4)) { + @for(city <- Random.shuffle(cityInfo.filter(c => c.visibility == "public" && c.cityId != currentCity.cityId)).take(4)) { - @cityName.replace(" ", " ")   + @city.cityNameFormatted.replace(" ", " ")   }
@if(mapathonLink.isDefined) { - @Html(Messages("landing.mapathon", cityShortName, mapathonLink.get)) + @Html(Messages("landing.mapathon", currentCity.cityNameShort, mapathonLink.get)) }
@@ -126,7 +128,7 @@
- @if(cityName == "Washington" || cityName == "Seattle") { + @if(currentCity.cityId == "washington-dc" || currentCity.cityId == "seattle-wa") { @Messages(s } else { @Messages(s @@ -141,7 +143,7 @@ @if(ConfigTable.getOpenStatus == "partially") { @Messages("landing.stats.percent.partial") } else { - @Messages("landing.stats.percent.full", cityShortName) + @Messages("landing.stats.percent.full", currentCity.cityNameShort) } @Messages("landing.stats.distance") @Messages("landing.stats.labels") @@ -158,13 +160,13 @@