mirror of
https://github.com/openmhz/trunk-server.git
synced 2026-11-15 10:17:33 -05:00
Twitter cards
This commit is contained in:
@@ -21,4 +21,5 @@ RUN cp -a /tmp/node_modules /app
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY server /app
|
COPY server /app
|
||||||
COPY --from=build /app/build /app/public
|
COPY --from=build /app/build /app/public
|
||||||
|
RUN sed 's/<meta name="temp" conent="replace"\/>/<%- TWITTER_META%>/g' /app/public/index.html > /app/index.ejs
|
||||||
CMD ["node", "index.js"]
|
CMD ["node", "index.js"]
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// Create an instance
|
|
||||||
let wavesurfer;
|
|
||||||
|
|
||||||
// Init & load audio file
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
// Init
|
|
||||||
wavesurfer = WaveSurfer.create({
|
|
||||||
container: document.querySelector('#waveform'),
|
|
||||||
waveColor: '#A8DBA8',
|
|
||||||
progressColor: '#3B8686',
|
|
||||||
backend: 'MediaElement',
|
|
||||||
mediaControls: false
|
|
||||||
});
|
|
||||||
|
|
||||||
wavesurfer.once('ready', function() {
|
|
||||||
console.log('Using wavesurfer.js ' + WaveSurfer.VERSION);
|
|
||||||
});
|
|
||||||
|
|
||||||
wavesurfer.on('error', function(e) {
|
|
||||||
console.warn(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load audio from URL
|
|
||||||
wavesurfer.load('https://s3.us-west-1.wasabisys.com/openmhz-west/media/dcfd-1039-1613917169.m4a');
|
|
||||||
|
|
||||||
// toggle play button
|
|
||||||
document
|
|
||||||
.querySelector('[data-action="play"]')
|
|
||||||
.addEventListener('click', wavesurfer.playPause.bind(wavesurfer));
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
name="%REACT_APP_SITE_NAME%"
|
name="%REACT_APP_SITE_NAME%"
|
||||||
content="Listen to live Police and Fire radio broadcasts. Archived for 30 days and searchable."
|
content="Listen to live Police and Fire radio broadcasts. Archived for 30 days and searchable."
|
||||||
/>
|
/>
|
||||||
|
<meta name="temp" conent="replace"/>
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" />
|
||||||
<!--
|
<!--
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
|
|||||||
@@ -1,30 +1,57 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<title>wavesurfer.js | Media Element Example</title>
|
<title>OpenMHz</title>
|
||||||
<script src="https://unpkg.com/wavesurfer.js"></script>
|
<script src="https://unpkg.com/wavesurfer.js"></script>
|
||||||
<script src="/card.js"></script>
|
<script>
|
||||||
</head>
|
// Create an instance
|
||||||
|
let wavesurfer;
|
||||||
|
var call_url="<%- url%>";
|
||||||
|
// Init & load audio file
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
// Init
|
||||||
|
wavesurfer = WaveSurfer.create({
|
||||||
|
container: document.querySelector("#waveform"),
|
||||||
|
waveColor: "#A8DBA8",
|
||||||
|
progressColor: "#3B8686",
|
||||||
|
backend: "MediaElement",
|
||||||
|
mediaControls: true,
|
||||||
|
});
|
||||||
|
|
||||||
<body >
|
wavesurfer.once("ready", function () {
|
||||||
|
console.log("Using wavesurfer.js " + WaveSurfer.VERSION);
|
||||||
|
});
|
||||||
|
|
||||||
<div id="demo">
|
wavesurfer.on("error", function (e) {
|
||||||
<div id="waveform">
|
console.warn(e);
|
||||||
<!-- Here be the waveform -->
|
});
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="controls">
|
// Load audio from URL
|
||||||
<button class="btn btn-primary" data-action="play">
|
wavesurfer.load(call_url);
|
||||||
<i class="glyphicon glyphicon-play"></i>
|
|
||||||
Play
|
// toggle play button
|
||||||
/
|
document
|
||||||
<i class="glyphicon glyphicon-pause"></i>
|
.querySelector('[data-action="play"]')
|
||||||
Pause
|
.addEventListener("click", wavesurfer.playPause.bind(wavesurfer));
|
||||||
</button>
|
});
|
||||||
</div>
|
</script>
|
||||||
</div>
|
</head>
|
||||||
</body>
|
|
||||||
|
<body>
|
||||||
|
<div id="demo">
|
||||||
|
<div id="waveform">
|
||||||
|
<!-- Here be the waveform -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<button class="btn btn-primary" data-action="play">
|
||||||
|
<i class="glyphicon glyphicon-play"></i>
|
||||||
|
Play /
|
||||||
|
<i class="glyphicon glyphicon-pause"></i>
|
||||||
|
Pause
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="icon" href="<%= PUBLIC_URL%>/favicon.ico" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
<meta
|
|
||||||
name="<%= REACT_APP_SITE_NAME%>"
|
|
||||||
content="Listen to live Police and Fire radio broadcasts. Archived for 30 days and searchable."
|
|
||||||
/>
|
|
||||||
<meta name="twitter:card" content="player"/>
|
|
||||||
<meta name="twitter:site" content="@openmhz"/>
|
|
||||||
<!--if channel
|
|
||||||
meta(name="twitter:title" content="#{channel.alpha} #{time} #{date}")
|
|
||||||
meta(name="twitter:description" content="This is a call from talkgroup #{channel.desc}")-->
|
|
||||||
<meta name="twitter:image" content="https://openmhz.com/img/player.png"/>
|
|
||||||
<meta name="twitter:player" content="https://openmhz.com/cards/<%= CALL_ID%>"/>
|
|
||||||
<meta name="twitter:player:stream" content="<%= CALL_URL%>"/>
|
|
||||||
<meta name="twitter:player:stream:content_type" content="audio/mp4"/>
|
|
||||||
<meta name="twitter:player:width" content="422"/>
|
|
||||||
<meta name="twitter:player:height" content="114"/>
|
|
||||||
<link rel="apple-touch-icon" href="<%= PUBLIC_URL%>/apple-touch-icon.png" />
|
|
||||||
<!--
|
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
||||||
-->
|
|
||||||
<link rel="manifest" href="<%= PUBLIC_URL%>/site.webmanifest" />
|
|
||||||
<!--
|
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
|
||||||
-->
|
|
||||||
<script src="<%= REACT_APP_BACKEND_SERVER%>/socket.io/socket.io.js"></script>
|
|
||||||
<script>
|
|
||||||
window.socket = io('<%= REACT_APP_BACKEND_SERVER%>');
|
|
||||||
</script>
|
|
||||||
<title>%REACT_APP_SITE_NAME%</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
|
||||||
-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -61,6 +61,7 @@ function getCard(req, res, next) {
|
|||||||
var time = new Date(item.time);
|
var time = new Date(item.time);
|
||||||
var timeString = time.toLocaleTimeString("en-US");
|
var timeString = time.toLocaleTimeString("en-US");
|
||||||
var dateString = time.toDateString();
|
var dateString = time.toDateString();
|
||||||
|
//console.log(item)
|
||||||
res.render('card.ejs', {
|
res.render('card.ejs', {
|
||||||
item: item,
|
item: item,
|
||||||
url: item.url,
|
url: item.url,
|
||||||
@@ -115,12 +116,53 @@ exports.get_card = function(req, res) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function getCalls(req, res, next) {
|
function getCalls(req, res, next) {
|
||||||
for (const key in req.query) {
|
|
||||||
console.log(key, req.query[key])
|
|
||||||
}
|
|
||||||
if (req.query && req.query["call-id"]) {
|
if (req.query && req.query["call-id"]) {
|
||||||
const callId = req.query["call-id"];
|
|
||||||
res.render("index.ejs", { PUBLIC_URL: "/", REACT_APP_SITE_NAME: process.env["REACT_APP_SITE_NAME"], REACT_APP_BACKEND_SERVER: process.env["REACT_APP_BACKEND_SERVER"], CALL_ID: callId, CALL_URL: "https://s3.us-west-1.wasabisys.com/openmhz-west/media/dcfd-1039-1613917169.m4a" })
|
var objectId = req.query["call-id"];
|
||||||
|
try {
|
||||||
|
var o_id = ObjectID.createFromHexString(objectId);
|
||||||
|
} catch (err) {
|
||||||
|
next()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.get().collection('calls', function (err, transCollection) {
|
||||||
|
transCollection.findOne({
|
||||||
|
'_id': o_id
|
||||||
|
},
|
||||||
|
function (err, item) {
|
||||||
|
if (item) {
|
||||||
|
var time = new Date(item.time);
|
||||||
|
var timeString = time.toLocaleTimeString("en-US");
|
||||||
|
var dateString = time.toDateString();
|
||||||
|
//console.log(item)
|
||||||
|
|
||||||
|
const callId = req.query["call-id"];
|
||||||
|
const callUrl = "https://s3.us-west-1.wasabisys.com/openmhz-west/media/dcfd-1039-1613917169.m4a"
|
||||||
|
const twitterMeta = `
|
||||||
|
<meta name="twitter:card" content="player"/>
|
||||||
|
<meta name="twitter:site" content="@openmhz"/>
|
||||||
|
<!--if channel
|
||||||
|
meta(name="twitter:title" content="#{channel.alpha} #{time} #{date}")
|
||||||
|
meta(name="twitter:description" content="This is a call from talkgroup #{channel.desc}")-->
|
||||||
|
<meta name="twitter:image" content="https://openmhz.com/img/player.png"/>
|
||||||
|
<meta name="twitter:player" content="${process.env['REACT_APP_FRONTEND_SERVER']}/cards/${callId}"/>
|
||||||
|
<meta name="twitter:player:stream" content="${item.url}"/>
|
||||||
|
<meta name="twitter:player:stream:content_type" content="audio/mp4"/>
|
||||||
|
<meta name="twitter:player:width" content="422"/>
|
||||||
|
<meta name="twitter:player:height" content="114"/>`
|
||||||
|
res.render("index.ejs", { TWITTER_META: twitterMeta })
|
||||||
|
} else {
|
||||||
|
console.warn("Error - /card/:id Could not find Item " + err);
|
||||||
|
res.send(404, 'Sorry, we cannot find that!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
@@ -129,7 +171,7 @@ function getCalls(req, res, next) {
|
|||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
app.use(express.static(path.join(__dirname, "public")));
|
app.use(express.static(path.join(__dirname, "public")));
|
||||||
|
|
||||||
app.get("/systems/:shortName", getCalls)
|
app.get("/system/:shortName", getCalls)
|
||||||
app.get("/cards/:id", getCard)
|
app.get("/cards/:id", getCard)
|
||||||
|
|
||||||
app.get("*", (req, res, next) => {
|
app.get("*", (req, res, next) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user