Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,6 @@ nohup.out

# docker db files
db/dump

#share images
public/assets/share-images
15 changes: 14 additions & 1 deletion app/controllers/GalleryController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import formats.json.GalleryFormats._
import models.user._
import models.label.{LabelTable, LabelTypeTable}
import models.label.LabelTable._
import scala.language.postfixOps
import com.mohiva.play.silhouette.api.{Environment, Silhouette}
import com.mohiva.play.silhouette.impl.authenticators.SessionAuthenticator
import formats.json.LabelFormat
Expand All @@ -15,6 +16,9 @@ import play.api.Play.current
import play.api.mvc._
import play.api.libs.json.{JsError, JsObject, Json}
import scala.concurrent.Future
import java.net.URL
import java.io.File
import sys.process._


/**
Expand Down Expand Up @@ -81,5 +85,14 @@ class GalleryController @Inject() (implicit val env: Environment[User, SessionAu
}
}
)
}
}

def saveShareImage(url: String) = UserAwareAction.async { implicit request =>
val filename = java.util.UUID.randomUUID.toString + ".jpg"
val file_path = "public/assets/share-images/" + filename
Future.successful{
new URL(url) #> new File(file_path) !!
}
Future.successful(Ok(Json.obj("filename" -> filename)))
}
}
107 changes: 107 additions & 0 deletions app/views/gallery.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
@(title: String, user: Option[User] = None, cityId: String, otherCityURLs: List[(String, String, String, String)], label: String, labels: List[(String, String)], severity: List[Int])(implicit lang: Lang)

@main(title) {
<head>
<meta property="og:type" content="website">
<meta property="og:image" content="https://sidewalk-columbus.cs.washington.edu/assets/assets/sidewalk-logo.png">
<meta property="og:image:width" content="720">
<meta property="og:image:height" content="480">
<meta property="og:title" content="Sidewalk Gallery">
<meta property="og:url" content="https://sidewalk-sea.cs.washington.edu/gallery">
<meta property="og:description" content="Checkout this accesabilty issue I saw">
</head>
<script type="text/javascript" src='@routes.Assets.at("javascripts/Gallery/build/Gallery.js")'></script>
<script type="text/javascript" src='@routes.Assets.at("javascripts/lib/i18next-21.9.1.min.js")'></script>
<script type="text/javascript" src='@routes.Assets.at("javascripts/lib/i18nextXHRBackend.min.js")'></script>
Expand Down Expand Up @@ -76,6 +85,31 @@ <h5 id="tags-header" class="filter-subheader">@Messages("gallery.tags")</h5>
<div class="gallery-modal-info-tags"></div>
<div class="gallery-modal-info-temporary"></div>
<div class="gallery-modal-info-description"></div>
<div class="gallery-modal-share">
<div id="share-popup">
<button class="facebook share-button">
<img class="share-icon" src="/assets/javascripts/SVLabel/img/icons/facebook_share_icon.svg">
</button>
<button class="twitter share-button">
<img class="share-icon" src="/assets/javascripts/SVLabel/img/icons/twitter_share_icon.svg">
</button>
<button class="linkedin share-button">
<img class="share-icon" src="/assets/javascripts/SVLabel/img/icons/linkedin_share_icon.svg">
</button>
<button class="tumblr share-button">
<img class="share-icon" src="/assets/javascripts/SVLabel/img/icons/tumblr_share_icon.svg">
</button>
<div class="vertical-divider"></div>
<button class="copy share-button">
<img class="share-icon" src="/assets/javascripts/SVLabel/img/icons/copy_icon.svg">
<div class="copy-text">copy link</div>
</button>
</div>
<button class="modal-share-button">
<img class="share-button-image" src="/assets/javascripts/SVLabel/img/icons/share_icon.svg">
Share
</button>
</div>
</div>
</div>
</div>
Expand All @@ -102,6 +136,79 @@ <h5 id="tags-header" class="filter-subheader">@Messages("gallery.tags")</h5>

sg.main = new Main(params);
</script>
<script type="text/javascript">
let current_url = window.location.href;
let title = document.title;

$(document).click(function(event) {
var $target = $(event.target);
if(!$target.closest('.gallery-modal-share').length && $('#share-popup').is(":visible")) {
$('#share-popup').hide("fast");
$('.copy-text').text("copy link")
}
});

$('.modal-share-button').click(function() {
$('#share-popup').show("fast", function() {
$('#share-popup').css("display", "flex");
});
});

$('.facebook').click(function() {
let share_url = "https://www.facebook.com/sharer/sharer.php?u=" + current_url;
window.open(share_url, "_blank");
saveImagePost(current_url);
});

$('.twitter').click(function() {
let share_url = "https://twitter.com/intent/tweet?text=" + title + "&url=" + current_url;
window.open(share_url, "_blank");
saveImagePost(current_url);
});

$('.linkedin').click(function() {
let share_url = "https://www.linkedin.com/cws/share?url=" + current_url;
window.open(share_url, "_blank");
saveImagePost(current_url);
});

$('.tumblr').click(function() {
let share_url = "http://tumblr.com/widgets/share/tool?canonicalUrl=" + current_url;
window.open(share_url, "_blank");
saveImagePost(current_url);
});

$('.copy').click(async function() {
navigator.clipboard.writeText(current_url);
$('.copy-text').text("copied!")
saveImagePost(current_url);
});

function saveImagePost(url) {
let imageSaveLocation = url.substring(0, url.length - 8) + "/assets/assets/share-images/"
// Save the image on server via post request
$.ajax({
async: true,
contentType: 'application/json; charset=utf-8',
url: "/saveShareImage?url=" +
encodeURIComponent(document.querySelector('meta[property="og:image"]')
.getAttribute("content")),
type: 'GET',
dataType: "json",
success: function (result) {
document.querySelector('meta[property="og:image"]').setAttribute("content",
imageSaveLocation + result.filename);
document.querySelector('meta[name="twitter:image"]').setAttribute("content",
imageSaveLocation + result.filename);
},
error: function(xhr, textStatus, error){
console.error(xhr.statusText);
console.error(textStatus);
console.error(error);
}
});
}
</script>

<link rel="stylesheet" href='@routes.Assets.at("javascripts/Gallery/build/Gallery.css")'/>
}
16 changes: 16 additions & 0 deletions app/views/main.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@
<script src='@routes.Assets.at("javascripts/lib/countUp.js")'></script>
<script src='@routes.Assets.at("javascripts/lib/bowser.min.js")'></script>
<script src='@routes.Assets.at("javascripts/common/pagetop-padding.js")'></script>

<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@@umd_sidewalk">
<meta name="twitter:creator" content="@@umd_sidewalk">
<meta name="twitter:title" content="Project Sidewalk">
<meta name="twitter:description" content="Help us make sidewalks more accessible, for everyone.">
@*TODO: url should not be hardcoded*@
<meta name="twitter:image" content="http://[email protected]("images/twitter_card.png")">

<!-- Facebook Link Info -->
<meta property="og:image" content="http://[email protected]("images/twitter_card.png")">
<meta property="og:type" content="website" />
<meta property="og:description" content='Help us make sidewalks more accessible, for everyone.' />
<meta property="og:url" content="http:/sidewalk.umiacs.umd.edu" />
<meta property="og:title" content="Project Sidewalk" />
</head>
<body onload="checkIfPaddingNeeded()">
<div id="wrap">
Expand Down
3 changes: 3 additions & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,6 @@ GET /userLabelsToCluster @controllers.Attrib
GET /clusteredLabelsInRegion @controllers.AttributeController.getClusteredLabelsInRegion(key: String, regionId: Int)
POST /singleUserClusteringResults @controllers.AttributeController.postSingleUserClusteringResults(key: String, userId: String)
POST /multiUserClusteringResults @controllers.AttributeController.postMultiUserClusteringResults(key: String, regionId: Int)

# Saving gallery image for open graph sharing
GET /saveShareImage @controllers.GalleryController.saveShareImage(url: String)
97 changes: 93 additions & 4 deletions public/javascripts/Gallery/css/modal.css
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,8 @@
}

.gallery-modal-info-tags {
width: 60%;
height: 5.5vw;
overflow-y: auto;
width: 40%;
height: 40%;
}

.gallery-modal-info-temporary {
Expand All @@ -120,7 +119,7 @@
}

.gallery-modal-info-description {
width: 60%;
width: 40%;
height: 60%;
display: flex;
flex-direction: column;
Expand All @@ -145,6 +144,96 @@
background-color: gray;
}

.gallery-modal-share {
display: flex;
flex-direction: column;
}

.share-button-image {
width: 45%;
height: auto;
}

.modal-share-button {
flex-direction: row;
width: 10%;
padding: 8px 0px;
position: absolute;
border-radius: 14px;
flex-wrap: wrap;
border: none;
background-color: Transparent;
transition: 0.6s;
bottom: 7%;
right: 6%;
}

.modal-share-button:hover {
transition: 0.6s;
background-color: #e5e5e5;
}

#share-popup {
z-index: 10;
display: none;
align-content: center;
justify-content: space-evenly;
position: absolute;
bottom: 20%;
right: 5%;
border-radius: 6px;
border-color: black;
border-style: solid;
border-width: 1.5px;
background-color: #fff;
width: 40%;
height: 8%;
}

.share-button {
width: 10%;
background: none;
aspect-ratio: 1/1;
display: flex;
align-content: center;
justify-content: center;
align-self: center;
justify-self: center;
border-radius: 25px;
border-style: none;
transition: 0.6s;
}

.share-button:hover {
transition: 0.6s;
background-color: #e5e5e5;
}


.share-icon {
height: 100%;
width: auto;
}

.copy {
height: 50%;
width: 40%;
aspect-ratio: initial;
}

.copy-text {
margin-left: 5px;
align-self: center;
font-size: 115%;
}

.vertical-divider {
align-self: center;
background: black;
height: 80%;
width: 2px;
}

.modal-top-holder {
display: flex;
align-content: space-between;
Expand Down
6 changes: 6 additions & 0 deletions public/javascripts/Gallery/src/cards/CardContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ function CardContainer(uiCardContainer) {
sg.ui.cardContainer.holder.on('click', '.static-gallery-image, .additional-count', (event) => {
$('.gallery-modal').attr('style', 'display: flex');
$('.grid-container').css("grid-template-columns", "1fr 5fr");

// Set share preview image to image of modal that is currently active
let newImageUrl = event.target.src;
document.querySelector('meta[property="og:image"]').setAttribute("content", newImageUrl);
document.querySelector('meta[name="twitter:image"]').setAttribute("content", newImageUrl);

// If the user clicks on the image body in the card, just use the provided id.
// Otherwise, the user will have clicked on an existing "+n" icon on the card, meaning we need to acquire
// the cardId from the card-tags DOM element (as well as perform an additional prepend to put the ID in
Expand Down
1 change: 1 addition & 0 deletions public/javascripts/SVLabel/img/icons/copy_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/javascripts/SVLabel/img/icons/share_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/javascripts/SVLabel/img/icons/tumblr_share_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.