Browse Source

Make Share Events section on the event detail page.

pull/41/head
Berkan Sasmaz 5 years ago
parent
commit
caee6b5aaa
  1. 2
      src/EventHub.Application.Contracts/Events/IEventAppService.cs
  2. 10
      src/EventHub.Application/Events/EventAppService.cs
  3. 44
      src/EventHub.Web.Theme/Themes/EventHub/Layouts/Application.cshtml
  4. 15
      src/EventHub.Web/Controllers/EventController.cs
  5. 42
      src/EventHub.Web/Pages/Events/Detail.cshtml
  6. 30
      src/EventHub.Web/Pages/Events/Detail.js

2
src/EventHub.Application.Contracts/Events/IEventAppService.cs

@ -21,5 +21,7 @@ namespace EventHub.Events
Task<bool> IsEventOwnerAsync(Guid id);
Task UpdateAsync(Guid id, UpdateEventDto input);
Task<byte[]> GetCoverImageAsync(Guid id);
}
}

10
src/EventHub.Application/Events/EventAppService.cs

@ -261,19 +261,19 @@ namespace EventHub.Events
await _eventRepository.UpdateAsync(@event);
}
private async Task SaveCoverImageAsync(Guid id, byte[] coverImageContent)
public async Task<byte[]> GetCoverImageAsync(Guid id)
{
var blobName = id.ToString();
await _eventBlobContainer.SaveAsync(blobName, coverImageContent, overrideExisting: true);
return await _eventBlobContainer.GetAllBytesOrNullAsync(blobName);
}
private async Task<byte[]> GetCoverImageAsync(Guid id)
private async Task SaveCoverImageAsync(Guid id, byte[] coverImageContent)
{
var blobName = id.ToString();
return await _eventBlobContainer.GetAllBytesOrNullAsync(blobName);
await _eventBlobContainer.SaveAsync(blobName, coverImageContent, overrideExisting: true);
}
}
}

44
src/EventHub.Web.Theme/Themes/EventHub/Layouts/Application.cshtml

@ -9,6 +9,8 @@
@using EventHub.Web.Theme.Themes.EventHub.Components.Footer
@using EventHub.Web.Theme.Themes.EventHub.Components.MainNavbar
@using EventHub.Web.Theme.Themes.EventHub.Components.PageAlerts
@using EventHub.Web
@using Microsoft.AspNetCore.Http.Extensions
@inject IBrandingProvider BrandingProvider
@inject IPageLayout PageLayout
@{
@ -39,6 +41,18 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>@pageTitle</title>
@* TODO(berkansasmaz): Get SEO content from the marketing team *@
<meta name="description" content="@(!string.IsNullOrEmpty(ViewBag.Description) ? ViewBag.Description : "EventHub Description")"/>
<meta property="og:title" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgTitle) ? ViewBag.OgTitle : "EventHub Title")"/>
<meta property="og:url" content="@Context.Request.GetDisplayUrl()"/>
<meta property="og:type" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgType) ? ViewBag.OgType : "website")"/>
<meta property="og:description" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgDescription) ? ViewBag.OgDescription : "EventHub Description")"/>
<meta property="og:image" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgImage) ? ViewBag.OgImage : EventHubExternalUrls.EhWww + "/assets/slide.jpg")"/>
<meta property="twitter:card" content="summary_large_image"/>
<meta property="twitter:site" content="@Html.Raw("@openeventhub")"/>
<meta property="twitter:title" content="@(!string.IsNullOrWhiteSpace(ViewBag.TwitterTitle) ? ViewBag.TwitterTitle : "EventHub")"/>
<meta property="twitter:description" content="@(!string.IsNullOrWhiteSpace(ViewBag.TwitterDescription) ? ViewBag.TwitterDescription : "EventHub Description")"/>
<meta property="twitter:image" content="@(!string.IsNullOrWhiteSpace(ViewBag.TwitterImage) ? ViewBag.TwitterImage : EventHubExternalUrls.EhWww + "/assets/slide.jpg")"/>
<!-- TODO: Include into the solution and use as packages! -->
<link rel="preconnect" href="https://fonts.gstatic.com">
@ -46,7 +60,7 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css" integrity="sha512-tS3S5qG0BlhnQROyJXvNjeEM4UpMXHrQfTGmbQ1gKmelCxlSEBUaxhRBj/EFTzpbP4RVSrpEikbmdJobCvhE3g==" crossorigin="anonymous"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.theme.default.css" integrity="sha512-OTcub78R3msOCtY3Tc6FzeDJ8N9qvQn1Ph49ou13xgA9VsH9+LRxoFU6EqLhW4+PKRfU+/HReXmSZXHEkpYoOA==" crossorigin="anonymous"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flag-icon-css@3.5.0/css/flag-icon.min.css"/>
<abp-style-bundle name="@EventHubThemeBundles.Styles.Global"/>
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent))
@ -56,19 +70,19 @@
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Application)
</head>
<body class="abp-application-layout @rtl">
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Application)
@(await Component.InvokeAsync<MainNavbarViewComponent>())
@(await Component.InvokeAsync<PageAlertsViewComponent>())
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Application)
@RenderBody()
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Application)
@(await Component.InvokeAsync<FooterViewComponent>())
<abp-script-bundle name="@EventHubThemeBundles.Scripts.Global"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js" integrity="sha512-bPs7Ae6pVvhOSiIcyUClR7/q2OAsRiovw4vAkX+zJbw3ShAeeqezq50RIIcIURq7Oa20rW2n2q+fyXBNcU9lrw==" crossorigin="anonymous"></script>
<script src="~/Abp/ApplicationConfigurationScript"></script>
<script src="~/Abp/ServiceProxyScript"></script>
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
@await RenderSectionAsync("scripts", false)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Application)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Application)
@(await Component.InvokeAsync<MainNavbarViewComponent>())
@(await Component.InvokeAsync<PageAlertsViewComponent>())
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Application)
@RenderBody()
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Application)
@(await Component.InvokeAsync<FooterViewComponent>())
<abp-script-bundle name="@EventHubThemeBundles.Scripts.Global"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js" integrity="sha512-bPs7Ae6pVvhOSiIcyUClR7/q2OAsRiovw4vAkX+zJbw3ShAeeqezq50RIIcIURq7Oa20rW2n2q+fyXBNcU9lrw==" crossorigin="anonymous"></script>
<script src="~/Abp/ApplicationConfigurationScript"></script>
<script src="~/Abp/ServiceProxyScript"></script>
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
@await RenderSectionAsync("scripts", false)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Application)
</body>
</html>

15
src/EventHub.Web/Controllers/EventController.cs

@ -1,3 +1,4 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Events;
@ -28,5 +29,19 @@ namespace EventHub.Web.Controllers
ViewData = ViewData
};
}
[HttpGet]
[Route("cover-picture-source/{eventId}")]
public async Task<IActionResult> GetArticleCoverImageAsync(Guid eventId)
{
var coverImageContent = await _eventAppService.GetCoverImageAsync(eventId);
if (coverImageContent == null)
{
return NotFound();
}
return File(coverImageContent, "image/jpeg");
}
}
}

42
src/EventHub.Web/Pages/Events/Detail.cshtml

@ -1,6 +1,7 @@
@page "/events/{url}"
@inject IHtmlLocalizer<EventHubResource> L
@using EventHub.Localization
@using EventHub.Web
@using EventHub.Web.Helpers
@using EventHub.Web.Pages.Events
@using EventHub.Web.Pages.Events.Components.AttendeesArea
@ -13,6 +14,37 @@
@inject ICurrentUser CurrentUser
@inject IClock Clock
@model EventHub.Web.Pages.Events.DetailPageModel
@section scripts {
<abp-script src="/Pages/Events/Detail.js"/>
}
@{
string description = Model.Event.Description.Length >= 160 ? Model.Event.Description.TruncateWithPostfix(155) : Model.Event.Description;
string title = Model.Event.Title;
string coverImageUrl;
if (Model.Event.CoverImageContent is null)
{
// TODO(berkansasmaz): Get a default image from the design team to be used in social media posts
coverImageUrl = EventHubExternalUrls.EhWww + "/assets/slide.jpg";
}
else
{
coverImageUrl = $"{EventHubExternalUrls.EhWww}/api/event/cover-picture-source/{Model.Event.Id}";
}
ViewBag.Title = title;
ViewBag.Description = description;
ViewBag.OgTitle = title;
ViewBag.OgType = "event";
ViewBag.OgDescription = description;
ViewBag.TwitterTitle = title;
ViewBag.TwitterDescription = description;
ViewBag.TwitterImage = coverImageUrl;
ViewBag.OgImage = coverImageUrl;
}
<div class="bg-white py-5">
<div class="container detail-page pb-4">
<div class="row">
@ -38,7 +70,7 @@
</div>
<div class="col-md-5 pl-md-5">
<h1 class="mt-4 mt-md-0">@Model.Event.Title</h1>
<h1 id="EventTitle" class="mt-4 mt-md-0">@Model.Event.Title</h1>
@await Component.InvokeAsync(typeof(LocationAreaViewComponent), new {eventId = Model.Event.Id})
<h5 class="detail-head mt-4">Owner</h5>
@ -54,12 +86,18 @@
</a>
}
@await Component.InvokeAsync(typeof(RegistrationAreaViewComponent), new {eventId = Model.Event.Id})
<h5 class="detail-head mt-5 font-weight-bold">Share Event</h5>
<div class="share-container">
<a href="#" target="_blank" id="TwitterShareLink" title="Twitter"><img src="/assets/twitter2.svg"></a>
<a href="#" target="_blank" id="LinkedinShareLink" title="LinkedIn"><img src="/assets/in2.svg"></a>
<a href="#" target="_blank" id="FacebookShareLink" title="Facebook"><img src="/assets/facebook2.png"></a>
</div>
</div>
</div>
<div class="row">
<div class="col-md-7">
<h5 class="detail-head mt-5 font-weight-bold">Event Description</h5>
<p>
<p id="EventDescription">
@Model.Event.Description
</p>

30
src/EventHub.Web/Pages/Events/Detail.js

@ -0,0 +1,30 @@
$(function () {
var initSocialShareLinks = function () {
var pageHeader = $('#EventTitle').text();
$('#TwitterShareLink').attr(
'href',
'https://twitter.com/intent/tweet?text=' +
encodeURI(
pageHeader + ' | EventHub | ' + window.location.href
)
);
$('#LinkedinShareLink').attr(
'href',
'https://www.linkedin.com/shareArticle?' +
'url=' +
encodeURI(window.location.href) +
'&' +
'mini=true'
);
$('#FacebookShareLink').attr(
'href',
'https://www.facebook.com/sharer/sharer.php?' +
'u=' +
encodeURI(window.location.href)
);
};
initSocialShareLinks();
});
Loading…
Cancel
Save