Comments (10)
@jzhou100 I was thinking about this on the walk home - and I had a different idea.
The best time to render the social media image is after a candidate has uploaded a recording. That's when it needs an update. app/api/create-participant is where that happens. after cb(result) we should add a call to a function updateSocialMediaImage
That should render the image, using
var parent= await Iota.findOne({_id: iota.parentId});
Then app/server/server.js getIota() shows what to do to use the parent, above, to get the dataComponents() and then the next() is the call to serverReactRender() but we'll have to separate out serverReactRander from the req, res, next parameters because you won't have those.
We should upload the image to cloudinary. You can look at app/server/api.js look for 'upload video' near the bottom. Thats for uploading a video from a stream, but you will be doing it from a blob or buffer or something that your image is in. Cloudinary has good docs online.
When you get back a URL from cloudinary, then update the parent to include a property 'og:image' with that url. (which might overwrite the previous one which is what we want).
Then in serverReactRender, if og:image is present, we add the meta tag for it.
It's a lot of touch points that probably only makes sense to me. Maybe we should talk about it more after you've had a change to look at this. Maybe there's an easier way.
Thanks so much for helping with this!
from undebate.
@jzhou100 : Hi Joe, Please provide a quick update in the comment section with below 4 key points before today's meeting for us to review:
- Progress
- Challenges / road blocks
- Expected completion date
- Availability during the week
from undebate.
Update from 03/16 standup: David will tie out with Joe on coming Sunday on this action item
from undebate.
03/25: Follow up with Joe on this action item; Poorna / David
from undebate.
In our call today we create this drawing: https://whiteboardfox.com/1540048-4640-0038
from undebate.
@jzhou100 wrote:
I had completed the part of updating iota on a particular parentId. Next step is to integration socket API once you have it. Here based on our discussion today I assume that Smpreview will receives the parentId from socketAPI, which collection requires social preview image creation or update,
--
Lets discuss these on the github issue so we can keep track of it here.
Here is an example of a participant recording iota that the server would send:
{
"_id": {
"$oid": "5d65a6b877fff400177d50ed"
},
"parentId": "5d6350b0e7179a084ef376b9",
"subject": "Participant:School Board Candidate Conversation - Candidate Conversation",
"description": "A participant in the following discussion:A prototype Candidate Conversation for schoolboard",
"component": {
"component": "MergeParticipants",
"participant": {
"speaking": [
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566942893/5d5dc697d32514001766ca87-1-speaking20190827T215452394Z.webm",
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566942898/5d5dc697d32514001766ca87-2-speaking20190827T215455964Z.webm",
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566942903/5d5dc697d32514001766ca87-3-speaking20190827T215503161Z.webm"
],
"name": "Will",
"listening": "https://res.cloudinary.com/hf6mryjpf/video/upload/v1566942901/5d5dc697d32514001766ca87-2-nextUp20190827T215500659Z.webm"
}
},
"userId": "5d5dc697d32514001766ca87"
},
There are many more in iota.json of the latest repo
Then this is a chunk of code that uses a socket to talk to a process (on a different project).
https://github.com/EnCiv/get-enciv-info/blob/master/index.js
In this case, I think we need to do a little bit more though. I think the smpreview server needs to send an message saying that it wants to subscribe to "participantEvents", and then socket.join("participantEvents")
and then use socket.on("participanEvents", iota=>{ your code here}) to receive the events.
see this for stuff on socket.io
https://www.npmjs.com/package/socket.io
We probably have to talk this through a little more, but it's a start.
Thx.
from undebate.
@jzhou100 FYI I did this #128, so next we have to modify app/components/date-components/merge-participants.js to find the iota that smpreview creates, and pull the info into webcomponent.
from undebate.
Here's what we talked about on the call today:
var newParticipantDocs = await Iota.aggregate([
{ $match: { parentId: undebate._id.toString(), 'component.component': 'MergeParticipants', _id: {$gt: smpreviewId} } },
{ $sort: { _id: -1 } },
{ $group: { _id: '$userId', latest: { $first: '$$ROOT' } } },
{ $limit: maxParticipants },
{ $replaceRoot: { newRoot: '$latest' } },
])
if(newParticipantDocs.length){
update the smprevew image for the parentId
Iota.create({_id: ...
subject: required
description: required
component: {
component: "socialpreview",
url: 'https://cloudinary.........'
}
parentId: id for viewer
}
)
}
But since then I realized that the aggregate takes in the _id of the viewer as the parentId. But we have way more viewers than we have participants at this point. So it would be more expedient to find all the new participants and then find the viewer.
var lastSocialPreviews = await Iota.aggregate([
{ $match: { 'component.component': 'socialpreview' } },
{ $sort: { _id: -1 } },
{$limit: 1}
])
if(lastSocialPreviews.length) {
let lastSocialPreview=lastSocialPreviews[0];
var newParticipantDocs = await Iota.aggregate([
{ $match: { 'component.component': 'MergeParticipants', _id: {$gt: lastSocialPreview} } },
{ $sort: { _id: -1 } },
{ $group: { _id: '$userId', latest: { $first: '$$ROOT' } } },
{ $limit: maxParticipants },
{ $replaceRoot: { newRoot: '$latest' } },
])
newParticipantDocs.forEach(doc=>{
var viewer=await Iota.findOne({_id: Iota.ObjectID(doc.parentId)
generate preview from viewer.path
generate socialpreview from preview
})
This would find all the participants that have recorded since you last generated a preview, then you could look up the parentId's to get the viewer path and generate the smpreview.
d.
from undebate.
The implementation is completed. Here is what in the final code
var lastSocalPreviews = await Iota.aggregate([
{ $match: { 'component.component': 'socialpreview' } },
{ $sort: { _id: -1 } },
{$limit: 1}
])
if(lastSocalPreviews.length) {
let lastSocalPreview=lastSocalPreviews[0];
data = await Iota.aggregate([
{ $match: {'component.component': 'MergeParticipants', parentId: {$exists: true}, _id: {$gt: lastSocalPreview} } },
{ $sort: { _id: -1 } },
{ $group: { _id: '$userId', latest: {
// { $limit: maxParticipants },
{ $replaceRoot: { newRoot: '$latest' } },
]);
} else {
data = await Iota.aggregate([
{ $match: {'component.component': 'MergeParticipants', parentId: {$exists: true}}},
{ $sort: { _id: -1 } },
{ $group: { _id: '$parentId', latest: {
// { $limit: maxParticipants },
{ $replaceRoot: { newRoot: '$latest' } },
]);
}
First of all , it searches for last socal preview generation time. I cover the first time cases also.
Then searches for any new participant recording. Here I use $match: {'component.component': 'MergeParticipants', parentId: {$exists: true}. In this way, it filters out non-participant-recording records.
In main.js, it wakes up every 24 hours to do its work.
from undebate.
There is another repo smreview. A new issue has been raised #174. we can close this one.
from undebate.
Related Issues (20)
- Hangup still hears playback
- Hangup Button HOT 3
- Investigate using Google Civic Information API HOT 1
- Iframe for address lookup then candidate conversation
- Record Landscape Video while in Portrait Mode on Smartphone
- Candidate Lookup Page
- Load balancing on heroku HOT 1
- Prev Speaker, Prev Section shouldn't be active
- "Sitting there" recording task
- Candidate video showed twice
- Self-service Portal for Election Leaders to Create Undebates for their Election HOT 6
- customer recorder invite must use specified email HOT 2
- Rerecord countdown confusion
- Retry upload if error
- undebate creator doesn't put listening in the right spot
- Feedback function in footer.
- Portrait Mode header messed up
- Bad experience when PC doesn't have GPU
- Poor experience if camera/mic blocked
- Poor experience if no camera
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from undebate.