Skip to content

07. User profiles and publishes

Nick Doiron edited this page Mar 24, 2016 · 9 revisions

In 1batch, there are two URLs for profiles:

/profile - your own profile / editing space

/profile/mapmeld - the profile for another user ("mapmeld"). If you go to your own profile with this URL, you should be redirected back to /profile

These are two separate router.get() calls in app.js. The simpler one is another user's profile, because we only request public information, and we don't require you to be logged in at all:

// someone else's profile
router.get('/profile/:username', async function (ctx) {
  var requser = ctx.req.user;
  if (requser && ctx.params.username.toLowerCase() === requser.name) {
    // redirect to your own profile
    return ctx.redirect('/profile');
  }
  if (ctx.params.username.indexOf('@') > -1) {
    // usernames which are still emails are anonymous
    return printNoExist(ctx);
  }

  // we're looking for the one user with this name (there should only be one)
  // the only public information that's interesting to us is their _id, username, and whether they publicly posted yet
  // your app may need more fields to be public
  var user = await User.findOne({ name: req.params.username.toLowerCase() }, '_id username posted').exec();
  if (!user) { throw 'user does not exist'; }

  // request all images which are published by this user, get source urls
  var images = await Image.find({ published: true, hidden: false, user_id: user.name }).select('_id src').exec();

  // there's a function called responsiveImg which returns proper URLs from Cloudinary
  // we'll talk about it later
  images = images.map(responsiveImg);

  ctx.render('profile', {
    user: user, // the user who created this profile
    images: images, // the user's images
    posted: user.posted, // the user's post date (if they posted)
    forUser: (requser || null), // whether the browsing user is signed in or not
    csrfToken: ctx.csrf
  });
});

responsiveImg is going to be used several times. It takes in an array of Image objects, and asks Cloudinary to return formatted URLs for returning that image. It also requests the image in multiple sizes for the HTML 'srcset' attribute, because people could be looking at this page on desktop, mobile, or retina iPad, we don't know the best size of image to show the user. responsiveImg looks like this:

function responsiveImg(img, makeBig) {
  var baseSize = 300;
    if (makeBig) {
    baseSize *= 2;
  }
  var geturl = cloudinary.url;
  var out = {
    _id: img._id,
    src: {
      mini: geturl(img.src, { format: "jpg", width: baseSize * 2/3, height: baseSize * 2/3, crop: "fill" }).replace('http:', ''),
      main: geturl(img.src, { format: "jpg", width: baseSize, height: baseSize, crop: "fill" }).replace('http:', ''),
      retina: geturl(img.src, { format: "jpg", width: baseSize * 2, height: baseSize * 2, crop: "fill" }).replace('http:', '')
    }
  };
  return out;
}

Clone this wiki locally