<commit_before>import fetch from 'isomorphic-fetch';
import { getToken } from './auth';
import { api as apiConfig, frontendPreferences as frontendPrefsConfig } from '../config';

const getRequestOptions = () => ({
  headers: {
    'Accept': 'application/json',
    'X-Authentication-Token': getToken()
  }
});

export function getWhoAmI() {
  return fetch(`${apiConfig.host}/v2/users/whoami`, getRequestOptions());
}

export function getHome({ offset }) {
  return fetch(
    `${apiConfig.host}/v2/timelines/home?offset=${offset}`, getRequestOptions());
}

export function getDiscussions({ offset }) {
  return fetch(
    `${apiConfig.host}/v1/timelines/filter/discussions?offset=${offset}`, getRequestOptions());
}

export function getDirect({ offset }) {
  return fetch(
    `${apiConfig.host}/v1/timelines/filter/directs?offset=${offset}`, getRequestOptions());
}

export function getUserFeed({ username, offset }) {
  return fetch(
    `${apiConfig.host}/v1/timelines/${username}?offset=${offset}`, getRequestOptions());
}

const MAX_COMMENTS = 2;

export function getLikesOnly({ postId, commentsExpanded }) {
  const maxComments = commentsExpanded ? 'all' : `${MAX_COMMENTS}`;
  return fetch(
    `${apiConfig.host}/v1/posts/${postId}?maxComments=${maxComments}&maxLikes=all`, getRequestOptions());
}

export function getPost({ postId, maxComments = MAX_COMMENTS }) {
  return fetch(
    `${apiConfig.host}/v1/posts/${postId}?maxComments=${maxComments}`, getRequestOptions());
}

export function createPost({ feeds, postText, attachmentIds, more }) {
  return fetch(`${apiConfig.host}/v1/posts`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({
      post: {
        body: postText,
        attachments: attachmentIds
      },
      meta: {
        feeds: feeds,
        commentsDisabled: !!more.commentsDisabled
      }
    })
  });
}

export function createBookmarkletPost({ feeds, postText, imageUrls, commentText }) {
  return fetch(`${apiConfig.host}/v1/bookmarklet`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({
      title: postText,
      images: imageUrls,
      comment: commentText,
      meta: {
        feeds: feeds
      }
    })
  });
}

export function updatePost({ postId, newPost }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ post: newPost })
  });
}

export function deletePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}`, {
    'method': 'DELETE',
    'headers': {
      'Accept': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function addComment({ postId, commentText }) {
  return fetch(`${apiConfig.host}/v1/comments`, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ comment: { body: commentText, postId } })
  });
}

export function updateComment({ commentId, newCommentBody }) {
  return fetch(`${apiConfig.host}/v1/comments/${commentId}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ comment: { body: newCommentBody } })
  });
}

export function deleteComment({ commentId }) {
  return fetch(`${apiConfig.host}/v1/comments/${commentId}`, {
    'method': 'DELETE',
    'headers': {
      'Accept': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function likePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/like`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function unlikePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/unlike`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function hidePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/hide`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function unhidePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/unhide`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function disableComments({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/disableComments`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function enableComments({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/enableComments`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function signIn({ username, password }) {
  const encodedBody = _.map({ username, password },
    (value, key) => key + '=' + encodeURIComponent(value)
  ).join('&');

  return fetch(`${apiConfig.host}/v1/session`, {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    method: 'POST',
    body: encodedBody
  });
}

export function signUp({ username, password, email, captcha }) {
  const encodedBody = _.map({ username, password, email, captcha },
    (value, key) => key + '=' + encodeURIComponent(value)
  ).join('&');

  return fetch(`${apiConfig.host}/v1/users`, {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    method: 'POST',
    body: encodedBody
  });
}

export function updateUser({ id, screenName, email, description, isPrivate, isProtected }) {
  return fetch(`${apiConfig.host}/v1/users/${id}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ user: { screenName, email, description, isPrivate, isProtected } })
  });
}

export function updateFrontendPreferences({ userId, prefs }) {
  const frontendPreferences = {
    [frontendPrefsConfig.clientId]: prefs
  };

  return fetch(`${apiConfig.host}/v1/users/${userId}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ user: { frontendPreferences } })
  });
}

export function updatePassword({ currentPassword, password, passwordConfirmation }) {
  const encodedBody = _.map({ currentPassword, password, passwordConfirmation },
    (value, key) => key + '=' + encodeURIComponent(value)
  ).join('&');

  return fetch(`${apiConfig.host}/v1/users/updatePassword`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-Authentication-Token': getToken()
    },
    'body': encodedBody
  });
}

export function updateUserPicture({ picture }) {
  let data = new FormData();
  data.append('file', picture);

  return fetch(`${apiConfig.host}/v1/users/updateProfilePicture`, {
    'method': 'POST',
    'headers': {
      'X-Authentication-Token': getToken()
    },
    'body': data
  });
}

const userAction = action => ({ username }) => {
  return fetch(`${apiConfig.host}/v1/users/${username}/${action}`, {
    method: 'POST',
    'headers': {
      'X-Authentication-Token': getToken(),
    },
  });
};

export const ban = userAction('ban');
export const unban = userAction('unban');
export const subscribe = userAction('subscribe');
export const unsubscribe = userAction('unsubscribe');
export const sendSubscriptionRequest = userAction('sendRequest');

export function getUserComments({ username, offset }) {
  return fetch(`${apiConfig.host}/v1/timelines/${username}/comments?offset=${offset}`, getRequestOptions());
}

export function getUserLikes({ username, offset }) {
  return fetch(`${apiConfig.host}/v1/timelines/${username}/likes?offset=${offset}`, getRequestOptions());
}

export function getUserSubscribers({ username }) {
  return fetch(`${apiConfig.host}/v1/users/${username}/subscribers`, getRequestOptions());
}

export function getUserSubscriptions({ username }) {
  return fetch(`${apiConfig.host}/v1/users/${username}/subscriptions`, getRequestOptions());
}

export function getUserInfo({ username }) {
  return fetch(`${apiConfig.host}/v1/users/${username}`, getRequestOptions());
}

export function createGroup(groupSettings) {
  return fetch(`${apiConfig.host}/v1/groups`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ group: groupSettings })
  });
}

export function updateGroup({ id, groupSettings }) {
  return fetch(`${apiConfig.host}/v1/users/${id}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ user: groupSettings })
  });
}

export function updateGroupPicture({ groupName, file }) {
  let data = new FormData();
  data.append('file', file);

  return fetch(`${apiConfig.host}/v1/groups/${groupName}/updateProfilePicture`, {
    'method': 'POST',
    'headers': {
      'X-Authentication-Token': getToken()
    },
    'body': data
  });
}

export function acceptGroupRequest({ groupName, userName }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/acceptRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function rejectGroupRequest({ groupName, userName }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/rejectRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function acceptUserRequest({ userName }) {
  return fetch(`${apiConfig.host}/v1/users/acceptRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function rejectUserRequest({ userName }) {
  return fetch(`${apiConfig.host}/v1/users/rejectRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function unsubscribeFromGroup({ groupName, userName }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/unsubscribeFromGroup/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function promoteGroupAdmin({ groupName, user }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/subscribers/${user.username}/admin`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function demoteGroupAdmin({ groupName, user }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/subscribers/${user.username}/unadmin`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function revokeSentRequest({ username }) {
  return fetch(`${apiConfig.host}/v2/requests/${username}/revoke`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function getBlockedByMe() {
  return fetch(`${apiConfig.host}/v2/users/blockedByMe`, getRequestOptions());
}

export function getSearchResults({ query, offset }) {
  // For empty query, just mock the call to API without actual request/response
  if (!query) {
    return new Promise(function(resolve) {
      resolve({
        status: 200,
        json: () => new Promise(function(resolve) { resolve({}); })
      });
    });
  }

  const encodedQuery = encodeURIComponent(query);
  return fetch(`${apiConfig.host}/v2/search?qs=${encodedQuery}&offset=${offset}`, getRequestOptions());
}

export function getUnreadDirects() {
  return fetch(`${apiConfig.host}/v2/users/getUnreadDirectsNumber`, getRequestOptions());
}

export function markDirectsAsRead() {
  return fetch(`${apiConfig.host}/v2/users/markAllDirectsAsRead`, getRequestOptions());
}
<commit_msg>Switch all remaining v1 timelines to v2<commit_after>import fetch from 'isomorphic-fetch';
import { getToken } from './auth';
import { api as apiConfig, frontendPreferences as frontendPrefsConfig } from '../config';

const getRequestOptions = () => ({
  headers: {
    'Accept': 'application/json',
    'X-Authentication-Token': getToken()
  }
});

export function getWhoAmI() {
  return fetch(`${apiConfig.host}/v2/users/whoami`, getRequestOptions());
}

export function getHome({ offset }) {
  return fetch(
    `${apiConfig.host}/v2/timelines/home?offset=${offset}`, getRequestOptions());
}

export function getDiscussions({ offset }) {
  return fetch(
    `${apiConfig.host}/v2/timelines/filter/discussions?offset=${offset}`, getRequestOptions());
}

export function getDirect({ offset }) {
  return fetch(
    `${apiConfig.host}/v2/timelines/filter/directs?offset=${offset}`, getRequestOptions());
}

export function getUserFeed({ username, offset }) {
  return fetch(
    `${apiConfig.host}/v2/timelines/${username}?offset=${offset}`, getRequestOptions());
}

const MAX_COMMENTS = 2;

export function getLikesOnly({ postId, commentsExpanded }) {
  const maxComments = commentsExpanded ? 'all' : `${MAX_COMMENTS}`;
  return fetch(
    `${apiConfig.host}/v1/posts/${postId}?maxComments=${maxComments}&maxLikes=all`, getRequestOptions());
}

export function getPost({ postId, maxComments = MAX_COMMENTS }) {
  return fetch(
    `${apiConfig.host}/v1/posts/${postId}?maxComments=${maxComments}`, getRequestOptions());
}

export function createPost({ feeds, postText, attachmentIds, more }) {
  return fetch(`${apiConfig.host}/v1/posts`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({
      post: {
        body: postText,
        attachments: attachmentIds
      },
      meta: {
        feeds: feeds,
        commentsDisabled: !!more.commentsDisabled
      }
    })
  });
}

export function createBookmarkletPost({ feeds, postText, imageUrls, commentText }) {
  return fetch(`${apiConfig.host}/v1/bookmarklet`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({
      title: postText,
      images: imageUrls,
      comment: commentText,
      meta: {
        feeds: feeds
      }
    })
  });
}

export function updatePost({ postId, newPost }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ post: newPost })
  });
}

export function deletePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}`, {
    'method': 'DELETE',
    'headers': {
      'Accept': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function addComment({ postId, commentText }) {
  return fetch(`${apiConfig.host}/v1/comments`, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ comment: { body: commentText, postId } })
  });
}

export function updateComment({ commentId, newCommentBody }) {
  return fetch(`${apiConfig.host}/v1/comments/${commentId}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ comment: { body: newCommentBody } })
  });
}

export function deleteComment({ commentId }) {
  return fetch(`${apiConfig.host}/v1/comments/${commentId}`, {
    'method': 'DELETE',
    'headers': {
      'Accept': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function likePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/like`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function unlikePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/unlike`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function hidePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/hide`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function unhidePost({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/unhide`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function disableComments({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/disableComments`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function enableComments({ postId }) {
  return fetch(`${apiConfig.host}/v1/posts/${postId}/enableComments`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': '{}'
  });
}

export function signIn({ username, password }) {
  const encodedBody = _.map({ username, password },
    (value, key) => key + '=' + encodeURIComponent(value)
  ).join('&');

  return fetch(`${apiConfig.host}/v1/session`, {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    method: 'POST',
    body: encodedBody
  });
}

export function signUp({ username, password, email, captcha }) {
  const encodedBody = _.map({ username, password, email, captcha },
    (value, key) => key + '=' + encodeURIComponent(value)
  ).join('&');

  return fetch(`${apiConfig.host}/v1/users`, {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    method: 'POST',
    body: encodedBody
  });
}

export function updateUser({ id, screenName, email, description, isPrivate, isProtected }) {
  return fetch(`${apiConfig.host}/v1/users/${id}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ user: { screenName, email, description, isPrivate, isProtected } })
  });
}

export function updateFrontendPreferences({ userId, prefs }) {
  const frontendPreferences = {
    [frontendPrefsConfig.clientId]: prefs
  };

  return fetch(`${apiConfig.host}/v1/users/${userId}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ user: { frontendPreferences } })
  });
}

export function updatePassword({ currentPassword, password, passwordConfirmation }) {
  const encodedBody = _.map({ currentPassword, password, passwordConfirmation },
    (value, key) => key + '=' + encodeURIComponent(value)
  ).join('&');

  return fetch(`${apiConfig.host}/v1/users/updatePassword`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-Authentication-Token': getToken()
    },
    'body': encodedBody
  });
}

export function updateUserPicture({ picture }) {
  let data = new FormData();
  data.append('file', picture);

  return fetch(`${apiConfig.host}/v1/users/updateProfilePicture`, {
    'method': 'POST',
    'headers': {
      'X-Authentication-Token': getToken()
    },
    'body': data
  });
}

const userAction = action => ({ username }) => {
  return fetch(`${apiConfig.host}/v1/users/${username}/${action}`, {
    method: 'POST',
    'headers': {
      'X-Authentication-Token': getToken(),
    },
  });
};

export const ban = userAction('ban');
export const unban = userAction('unban');
export const subscribe = userAction('subscribe');
export const unsubscribe = userAction('unsubscribe');
export const sendSubscriptionRequest = userAction('sendRequest');

export function getUserComments({ username, offset }) {
  return fetch(`${apiConfig.host}/v2/timelines/${username}/comments?offset=${offset}`, getRequestOptions());
}

export function getUserLikes({ username, offset }) {
  return fetch(`${apiConfig.host}/v2/timelines/${username}/likes?offset=${offset}`, getRequestOptions());
}

export function getUserSubscribers({ username }) {
  return fetch(`${apiConfig.host}/v1/users/${username}/subscribers`, getRequestOptions());
}

export function getUserSubscriptions({ username }) {
  return fetch(`${apiConfig.host}/v1/users/${username}/subscriptions`, getRequestOptions());
}

export function getUserInfo({ username }) {
  return fetch(`${apiConfig.host}/v1/users/${username}`, getRequestOptions());
}

export function createGroup(groupSettings) {
  return fetch(`${apiConfig.host}/v1/groups`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ group: groupSettings })
  });
}

export function updateGroup({ id, groupSettings }) {
  return fetch(`${apiConfig.host}/v1/users/${id}`, {
    'method': 'PUT',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    },
    'body': JSON.stringify({ user: groupSettings })
  });
}

export function updateGroupPicture({ groupName, file }) {
  let data = new FormData();
  data.append('file', file);

  return fetch(`${apiConfig.host}/v1/groups/${groupName}/updateProfilePicture`, {
    'method': 'POST',
    'headers': {
      'X-Authentication-Token': getToken()
    },
    'body': data
  });
}

export function acceptGroupRequest({ groupName, userName }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/acceptRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function rejectGroupRequest({ groupName, userName }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/rejectRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function acceptUserRequest({ userName }) {
  return fetch(`${apiConfig.host}/v1/users/acceptRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function rejectUserRequest({ userName }) {
  return fetch(`${apiConfig.host}/v1/users/rejectRequest/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function unsubscribeFromGroup({ groupName, userName }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/unsubscribeFromGroup/${userName}`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function promoteGroupAdmin({ groupName, user }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/subscribers/${user.username}/admin`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function demoteGroupAdmin({ groupName, user }) {
  return fetch(`${apiConfig.host}/v1/groups/${groupName}/subscribers/${user.username}/unadmin`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function revokeSentRequest({ username }) {
  return fetch(`${apiConfig.host}/v2/requests/${username}/revoke`, {
    'method': 'POST',
    'headers': {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Authentication-Token': getToken()
    }
  });
}

export function getBlockedByMe() {
  return fetch(`${apiConfig.host}/v2/users/blockedByMe`, getRequestOptions());
}

export function getSearchResults({ query, offset }) {
  // For empty query, just mock the call to API without actual request/response
  if (!query) {
    return new Promise(function(resolve) {
      resolve({
        status: 200,
        json: () => new Promise(function(resolve) { resolve({}); })
      });
    });
  }

  const encodedQuery = encodeURIComponent(query);
  return fetch(`${apiConfig.host}/v2/search?qs=${encodedQuery}&offset=${offset}`, getRequestOptions());
}

export function getUnreadDirects() {
  return fetch(`${apiConfig.host}/v2/users/getUnreadDirectsNumber`, getRequestOptions());
}

export function markDirectsAsRead() {
  return fetch(`${apiConfig.host}/v2/users/markAllDirectsAsRead`, getRequestOptions());
}
<|endoftext|>


<commit_before>var path = require('path');
var MultiRange = require('multi-integer-range').MultiRange;
var getPixels = require('get-pixels-jpeg-js-upgrade');
var savePixels = require('save-pixels-jpeg-js-upgrade');

function nopromises () {
  throw new Error(
    'Promises not supported in your environment. ' +
    'Use the callback argument or a Promise polyfill.'
  );
}

var brokenPromise = {
  then: nopromises,
  catch: nopromises
};

function gifFrames (options, callback) {
  options = options || {};
  callback = callback || function () {};

  var promise;
  var resolve;
  var reject;
  if (typeof Promise === 'function') {
    promise = new Promise(function (_resolve, _reject) {
      resolve = function (res) {
        callback(null, res);
        _resolve(res);
      };
      reject = function (err) {
        callback(err);
        _reject(err);
      };
    });
  } else {
    promise = brokenPromise;
    resolve = function (res) {
      callback(null, res);
    };
    reject = callback;
  }

  var url = options.url;
  if (!url) {
    reject(new Error('"url" option is required.'));
    return promise;
  }
  var frames = options.frames;
  if (!frames && frames !== 0) {
    reject(new Error('"frames" option is required.'));
    return promise;
  }
  var outputType = options.outputType || 'jpg';
  var quality = options.quality;
  var cumulative = options.cumulative;

  var acceptedFrames = frames === 'all' ? 'all' : new MultiRange(frames);

  // Necessary to check if we're in Node or the browser until this is fixed:
  // https://github.com/scijs/get-pixels/issues/33
  var inputType = typeof window === 'undefined' ? 'image/gif' : '.GIF';
  getPixels(url, inputType, function (err, pixels) {
    if (err) {
      reject(err);
      return;
    }
    if (pixels.shape.length < 4) {
      reject(new Error('"url" input should be multi-frame GIF.'));
      return;
    }
    var frameData = [];
    var maxAccumulatedFrame = 0;
    for (var i = 0; i < pixels.shape[0]; i++) {
      if (acceptedFrames !== 'all' && !acceptedFrames.has(i)) {
        continue;
      }
      (function (frameIndex) {
        frameData.push({
          getImage: function () {
            if (cumulative && frameIndex > maxAccumulatedFrame) {
              // for each frame, replace any invisible pixel with
              // the corresponding pixel from the previous frame (beginning
              // with the second frame).
              // to avoid doing too much work at once we only compute the
              // frames up to and including the requested frame.
              var lastFrame = pixels.pick(maxAccumulatedFrame);
              for (var f = maxAccumulatedFrame + 1; f <= frameIndex; f++) {
                var frame = pixels.pick(f);
                for (var x = 0; x < frame.shape[0]; x++) {
                  for (var y = 0; y < frame.shape[1]; y++) {
                    if (frame.get(x, y, 3) === 0) {
                      // if alpha is fully transparent, use the pixel
                      // from the last frame
                      frame.set(x, y, 0, lastFrame.get(x, y, 0));
                      frame.set(x, y, 1, lastFrame.get(x, y, 1));
                      frame.set(x, y, 2, lastFrame.get(x, y, 2));
                      frame.set(x, y, 3, lastFrame.get(x, y, 3));
                    }
                  }
                }
                lastFrame = frame;
              }
              maxAccumulatedFrame = frameIndex;
            }
            return savePixels(pixels.pick(frameIndex), outputType, {
              quality: quality
            });
          },
          frameIndex: frameIndex
        });
      })(i);
    }
    resolve(frameData);
  });

  return promise;
}

module.exports = gifFrames;
<commit_msg>Remove unused 'path' import.<commit_after>var MultiRange = require('multi-integer-range').MultiRange;
var getPixels = require('get-pixels-jpeg-js-upgrade');
var savePixels = require('save-pixels-jpeg-js-upgrade');

function nopromises () {
  throw new Error(
    'Promises not supported in your environment. ' +
    'Use the callback argument or a Promise polyfill.'
  );
}

var brokenPromise = {
  then: nopromises,
  catch: nopromises
};

function gifFrames (options, callback) {
  options = options || {};
  callback = callback || function () {};

  var promise;
  var resolve;
  var reject;
  if (typeof Promise === 'function') {
    promise = new Promise(function (_resolve, _reject) {
      resolve = function (res) {
        callback(null, res);
        _resolve(res);
      };
      reject = function (err) {
        callback(err);
        _reject(err);
      };
    });
  } else {
    promise = brokenPromise;
    resolve = function (res) {
      callback(null, res);
    };
    reject = callback;
  }

  var url = options.url;
  if (!url) {
    reject(new Error('"url" option is required.'));
    return promise;
  }
  var frames = options.frames;
  if (!frames && frames !== 0) {
    reject(new Error('"frames" option is required.'));
    return promise;
  }
  var outputType = options.outputType || 'jpg';
  var quality = options.quality;
  var cumulative = options.cumulative;

  var acceptedFrames = frames === 'all' ? 'all' : new MultiRange(frames);

  // Necessary to check if we're in Node or the browser until this is fixed:
  // https://github.com/scijs/get-pixels/issues/33
  var inputType = typeof window === 'undefined' ? 'image/gif' : '.GIF';
  getPixels(url, inputType, function (err, pixels) {
    if (err) {
      reject(err);
      return;
    }
    if (pixels.shape.length < 4) {
      reject(new Error('"url" input should be multi-frame GIF.'));
      return;
    }
    var frameData = [];
    var maxAccumulatedFrame = 0;
    for (var i = 0; i < pixels.shape[0]; i++) {
      if (acceptedFrames !== 'all' && !acceptedFrames.has(i)) {
        continue;
      }
      (function (frameIndex) {
        frameData.push({
          getImage: function () {
            if (cumulative && frameIndex > maxAccumulatedFrame) {
              // for each frame, replace any invisible pixel with
              // the corresponding pixel from the previous frame (beginning
              // with the second frame).
              // to avoid doing too much work at once we only compute the
              // frames up to and including the requested frame.
              var lastFrame = pixels.pick(maxAccumulatedFrame);
              for (var f = maxAccumulatedFrame + 1; f <= frameIndex; f++) {
                var frame = pixels.pick(f);
                for (var x = 0; x < frame.shape[0]; x++) {
                  for (var y = 0; y < frame.shape[1]; y++) {
                    if (frame.get(x, y, 3) === 0) {
                      // if alpha is fully transparent, use the pixel
                      // from the last frame
                      frame.set(x, y, 0, lastFrame.get(x, y, 0));
                      frame.set(x, y, 1, lastFrame.get(x, y, 1));
                      frame.set(x, y, 2, lastFrame.get(x, y, 2));
                      frame.set(x, y, 3, lastFrame.get(x, y, 3));
                    }
                  }
                }
                lastFrame = frame;
              }
              maxAccumulatedFrame = frameIndex;
            }
            return savePixels(pixels.pick(frameIndex), outputType, {
              quality: quality
            });
          },
          frameIndex: frameIndex
        });
      })(i);
    }
    resolve(frameData);
  });

  return promise;
}

module.exports = gifFrames;
<|endoftext|>


<commit_before>var Backbone = require('backbone');
var Input = require('./Input');
var Spectrum = require('spectrum-colorpicker');

module.exports = Input.extend({

  template: _.template(`
  <div class='<%= ppfx %>input-holder'>

  <div class="<%= ppfx %>field-colorp">
    <div class="<%= ppfx %>field-colorp-c">
      <div class="<%= ppfx %>checker-bg">

`),

  initialize(opts) {
    Input.prototype.initialize.apply(this, arguments);
    var ppfx = this.ppfx;
    this.colorCls = ppfx + 'field-color-picker';
    this.inputClass = ppfx + 'field ' + ppfx + 'field-color';
    this.colorHolderClass = ppfx + 'field-colorp-c';

    this.listenTo(this.model, 'change:value', this.handleModelChange);
  },

  /**
   * Updates the view when the model is changed
   * */
  handleModelChange() {
    Input.prototype.handleModelChange.apply(this, arguments);

    var value = this.model.get('value');
    var colorEl = this.getColorEl();

    // If no color selected I will set white for the picker
    value = value === 'none' ? '#fff' : value;
    colorEl.get(0).style.backgroundColor = value;
  },

  /**
   * Get the color input element
   * @return {HTMLElement}
   */
  getColorEl() {
    if(!this.colorEl) {
      var model = this.model;
      var colorEl = $('
', {class: this.colorCls});
      var cpStyle = colorEl.get(0).style;
      var elToAppend = this.target && this.target.config ? this.target.config.el : '';

      if (typeof colorEl.spectrum == 'undefined') {
        throw 'Spectrum missing, probably you load jQuery twice';
      }

      const getColor = color => {
        let cl = color.getAlpha() == 1 ? color.toHexString() : color.toRgbString();
        return cl.replace(/ /g, '');
      }

      let changed = 0;
      let previousСolor;
      colorEl.spectrum({
        appendTo: elToAppend || 'body',
        maxSelectionSize: 8,
        showPalette: true,
        showAlpha:   true,
        chooseText: 'Ok',
        cancelText: '⨯',
        palette: [],
        move(color) {
          const cl = getColor(color);
          cpStyle.backgroundColor = cl;
          model.set('value', cl, {avoidStore: 1});
        },
        change(color) {
          changed = 1;
          const cl = getColor(color);
          cpStyle.backgroundColor = cl;
          model.set('value', '', {avoidStore: 1});
          model.set('value', cl);
          colorEl.spectrum('set', cl);
        },
        show(color) {
          changed = 0;
          console.log('Show color', color, getColor(color));
          previousСolor = getColor(color);
        },
        hide(color) {
           if (!changed && previousСolor) {
             cpStyle.backgroundColor = previousСolor;
             colorEl.spectrum('set', previousСolor);
             model.set('value', previousСolor, {avoidStore: 1});
           }
        }
      });
      this.colorEl = colorEl;
    }
    return this.colorEl;
  },

  render(...args) {
    Input.prototype.render.apply(this, args);
    this.$el.find('.' + this.colorHolderClass).html(this.getColorEl());
    return this;
  }

});
<commit_msg>Updates on color input<commit_after>var Backbone = require('backbone');
var Input = require('./Input');
var Spectrum = require('spectrum-colorpicker');

module.exports = Input.extend({

  template: _.template(`
  <div class='<%= ppfx %>input-holder'>

  <div class="<%= ppfx %>field-colorp">
    <div class="<%= ppfx %>field-colorp-c">
      <div class="<%= ppfx %>checker-bg">

`),

  initialize(opts) {
    Input.prototype.initialize.apply(this, arguments);
    var ppfx = this.ppfx;
    this.colorCls = ppfx + 'field-color-picker';
    this.inputClass = ppfx + 'field ' + ppfx + 'field-color';
    this.colorHolderClass = ppfx + 'field-colorp-c';

    this.listenTo(this.model, 'change:value', this.handleModelChange);
  },

  /**
   * Updates the view when the model is changed
   * */
  handleModelChange(mdl, vl, opts = {}) {
    Input.prototype.handleModelChange.apply(this, arguments);

    var value = this.model.get('value');
    var colorEl = this.getColorEl();

    // If no color selected I will set white for the picker
    value = value === 'none' ? '#fff' : value;
    colorEl.get(0).style.backgroundColor = value;

    // Prevent usuless palette updating
    if (!opts.avoidStore) {
      console.log('COlor to set', value, mdl, vl, opts);
      colorEl.spectrum('set', value);
    }
  },

  /**
   * Get the color input element
   * @return {HTMLElement}
   */
  getColorEl() {
    if(!this.colorEl) {
      var model = this.model;
      var colorEl = $('
', {class: this.colorCls});
      var cpStyle = colorEl.get(0).style;
      var elToAppend = this.target && this.target.config ? this.target.config.el : '';

      if (typeof colorEl.spectrum == 'undefined') {
        throw 'Spectrum missing, probably you load jQuery twice';
      }

      const getColor = color => {
        let cl = color.getAlpha() == 1 ? color.toHexString() : color.toRgbString();
        return cl.replace(/ /g, '');
      }

      let changed = 0;
      let previousСolor;
      colorEl.spectrum({
        //color: "#f00"
        appendTo: elToAppend || 'body',
        maxSelectionSize: 8,
        showPalette: true,
        showAlpha:   true,
        chooseText: 'Ok',
        cancelText: '⨯',
        palette: [],
        move(color) {
          const cl = getColor(color);
          cpStyle.backgroundColor = cl;
          model.set('value', cl, {avoidStore: 1});
        },
        change(color) {
          changed = 1;
          const cl = getColor(color);
          cpStyle.backgroundColor = cl;
          model.set('value', '', {avoidStore: 1});
          model.set('value', cl);
          colorEl.spectrum('set', cl);
        },
        show(color) {
          changed = 0;
          console.log('Show color', color, getColor(color));
          previousСolor = getColor(color);
        },
        hide(color) {
           if (!changed && previousСolor) {
             cpStyle.backgroundColor = previousСolor;
             colorEl.spectrum('set', previousСolor);
             model.set('value', previousСolor, {avoidStore: 1});
           }
        }
      });
      this.colorEl = colorEl;
    }
    return this.colorEl;
  },

  render(...args) {
    Input.prototype.render.apply(this, args);
    this.$el.find('.' + this.colorHolderClass).html(this.getColorEl());
    return this;
  }

});
<|endoftext|>


<commit_before>jIRCs.prototype.irc_PING = function(prefix, args) {
    this.send('PONG',args);
};

jIRCs.prototype.irc_NICK = function(prefix, args) {
    var oldNick = this.getNick(prefix),
        newNick = args.pop();
    if(oldNick == this.nickname) {
        this.nickname = newNick;
    }
    this.forEach(this.channels, function(c, channel) {
        if(c.names && oldNick in c.names) {
            this.renderLine(channel,'',oldNick + ' is now known as ' + newNick);
            c.names[newNick] = c.names[oldNick];
            delete(c.names[oldNick]);
        }
    }, this);
    this.forEach(this.displays, function(disobj) {
        this.render(disobj);
    }, this);
};

jIRCs.prototype.irc_JOIN = function(prefix, args) {
    var channel = args.pop().toLowerCase();
    if(prefix != this.nickname) {
        this.renderLine(channel, '', prefix + " joined " + channel);
    } else {
        this.renderLine(channel, '', "You have joined " + channel);
    }
    if(!this.channels[channel].names) {
        this.channels[channel].names = {};
    }
    this.channels[channel].names[prefix] = "";
    if (!this.channels[channel].modes) {
        this.channels[channel].modes = {};
        this.send('MODE', [channel]); // Get the initial modes because the server doesn't send them by default
    }
    this.forEach(this.displays, function(disobj) {
        if(document.activeElement == disobj.messagebox && prefix == this.nickname) {
            this.activateChan(channel, disobj);
        }
        if(disobj.window == channel) {
            this.render(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_PART = function(prefix, args) {
    var channel = args.shift().toLowerCase();
    var reason = args.pop();
    if(this.getNick(prefix) == this.nickname) {
        this.destroyChan(channel);
    } else {
        this.renderLine(channel, '', prefix + " left " + channel + " [" + reason + "]");
        delete(this.channels[channel].names[prefix]);
        this.forEach(this.displays, function(disobj) {
            if(disobj.window == channel) {
                this.render(disobj);
            }
        }, this);
    }
};

jIRCs.prototype.irc_QUIT = function(prefix, args) {
    var reason = args.pop();
    this.forEach(this.channels, function(c, channel) {
        if(channel == 'Status') {
            return;
        }
        if(c.names && prefix in c.names) {
            this.renderLine(channel, '', prefix + ' quit (' + reason + ')');
            delete(c.names[prefix]);
        }
    }, this);
    if(this.getNick(prefix) == this.nickname) {
        // Let ondisconnect handle cleanup
    } else {
        this.forEach(this.displays, function(disobj) {
            this.render(disobj);
        }, this);
    }
};

jIRCs.prototype.irc_PRIVMSG = function(prefix, args) {
    var channel = args.shift().toLowerCase();
    var message = args.pop();
    //account for private messages
    if (channel == this.nickname.toLowerCase()) {
        channel = prefix.toLowerCase();
    }
    if (channel.charAt(0) in this.statuses) {
        prefix += ":" + channel; // give a visible indication that the message isn't for the whole channel
        channel = channel.substr(1); // trim the status char off so the message gets displayed to the correct channel
    }
    if(message.charAt(0) == '\u0001') {
        message = message.split('\u0001')[1];
        if(message.substr(0,6).toUpperCase() == 'ACTION') {
            message = prefix + message.substr(6);
            prefix = '';
            this.renderLine(channel, prefix, message);
        } else {
            args = message.split(' ');
            var method = 'ctcp_' + args.shift().toUpperCase();
            console.log("<<<<<< " + method + "('" + channel + "'," + JSON.stringify(args) + ")");
            if(method in this) {
                this[method](channel, args);
            }
        }
    } else {
        this.renderLine(channel, "<"+prefix+">", message);
    }
};

jIRCs.prototype.irc_NOTICE = function(prefix, args) {
    var nick = '\u2013 ' + this.getNick(prefix);
    var message = args.pop();
    var dest = args.shift().toLowerCase(); // It'll only be used if it's a channel name, anyway
    if (this.chantypes.indexOf(dest.charAt(0)) !== -1 || this.chantypes.indexOf(dest.charAt(1)) !== -1) { // There may or may not be a channel status in the parameter
        nick += ":" + dest + ' \u2013'; // Give a visible indication that the message is a channel notice
        if (dest.charAt(0) in this.statuses) { // it's not going directly to all of a channel
            dest = dest.substr(1); // display it in the correct window
        }
        this.renderLine(dest, nick, message);
    } else {
        nick += ' \u2013'; // \u2013 is an en-dash
        this.forEach(this.displays, function(disobj) {
            this.renderLine(disobj.window, nick, message, disobj);
        }, this);
    }
};

jIRCs.prototype.irc_MODE = function(prefix, args) {
    var channel = args.shift().toLowerCase();
    var modes = args.shift().split('');
    if (channel == this.nickname.toLowerCase()) { // handle user modes here
        var adding = true;
        this.forEach(modes, function(mode) {
            switch (mode) {
                case '+':
                    adding = true;
                    break;
                case '-':
                    adding = false;
                    break;
                default:
                    if (adding) {
                        this.userModes.push(mode);
                    } else {
                        var modePos = this.userModes.indexOf(mode);
                        if (modePos != -1) {
                            this.userModes.splice(modePos, 1);
                        }
                    }
            }
        }, this);
    } else {
        // At this point, what's left in args is the parameter list
        this.parseModes(channel, modes, args); // handle the channel modes
    }
};

jIRCs.prototype.irc_CAP = function(prefix, args) {
    // :server CAP dest subcommand :capability list
    if (args[1] == "LS") {
        var supportedCaps = args[2].split(' ');
        if (supportedCaps.indexOf("multi-prefix") != -1) {
            this.send("CAP", ["REQ", ":multi-prefix"]);
        } else if (!this.registered) {
            this.send("CAP", ["END"]);
        }
    } else if (args[1] == "ACK" && !this.registered) {
        this.send("CAP", ["END"]);
    }
}

jIRCs.prototype.irc_001 = function(prefix, args) {
    this.registered = true;
}

jIRCs.prototype.irc_005 = function(prefix, args) {
    var server = args.shift();
    var message = args.pop();
    this.forEach(args, function(arg) {
        if(arg.substr(0,7).toUpperCase() == 'PREFIX=') {
            var modes = arg.substr(8).split(')'); // exclude the open paren, split close paren
            var symbols = modes[1].split('');
            var letters = modes[0].split('');
            this.statuses = this.zip(symbols.concat(letters), letters.concat(symbols));
            this.statusOrder = letters;
            this.statuses[''] = '';
            this.statusOrder.push('');
        }
        if (arg.substr(0, 10) == 'CHANMODES=') {
            var modes = arg.substr(10); // get all the channel modes
            var groups = modes.split(',');
            this.forEach(groups, function(group, groupNum) {
                this.forEach(group, function(mode) {
                    this.chanModes[mode] = groupNum; // map modes to their group index for easy lookup
                }, this);
            }, this);
        }
        if (arg.substr(0, 10) == 'CHANTYPES=') {
            this.chantypes = arg.substr(10).split('');
        }
    }, this);
};

jIRCs.prototype.irc_324 = function(prefix, args) {
    args.shift(); // discard our nick; it's not useful
    var channel = args.shift().toLowerCase();
    var modes = args.shift().split('');
    // At this point, what's left in args (if anything) is the mode parameter list
    this.channels[channel].modes = {}; // Reset the channel modes list as 324 is all of the channel's current modes
    this.parseModes(channel, modes, args);
};

jIRCs.prototype.irc_353 = function(prefix, args) {
    var channel = args[2].toLowerCase();
    if (!this.channels[channel].moreNames) {
        this.channels[channel].names = {};
        this.channels[channel].moreNames = true;
    }
    var names = args[3].split(' '); // Strip the colon and split the names out
    this.forEach(names, function(name) {
        var statusList = '';
        while (name.charAt(0) in this.statuses) {
            statusList += name.charAt(0);
            name = name.substr(1);
        }
        this.channels[channel].names[name] = statusList;
    }, this);
};

jIRCs.prototype.irc_366 = function(prefix, args) {
    var channel = args[1].toLowerCase();
    this.channels[channel].moreNames = false;
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.render(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_332 = function(prefix, args) {
    var channel = args[1].toLowerCase();
    if(!this.channels[channel].topic) {
        this.channels[channel].topic = {};
    }
    this.channels[channel].topic.message = args[2];
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.renderTopic(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_333 = function(prefix, args) {
    var channel = args[1].toLowerCase();
    if(!this.channels[channel].topic) {
        this.channels[channel].topic = {};
    }
    this.channels[channel].topic.creator = args[2];
    this.channels[channel].topic.time = new Date(args[3] * 1000);
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.renderTopic(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_TOPIC = function(prefix, args) {
    var channel = args[0].toLowerCase();
    if(!this.channels[channel].topic) {
        this.channels[channel].topic = {};
    }
    this.channels[channel].topic.creator = prefix;
    this.channels[channel].topic.time = new Date();
    this.channels[channel].topic.message = args[1];
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.renderTopic(disobj);
        }
    }, this);
};
<commit_msg>Make notice work properly again<commit_after>jIRCs.prototype.irc_PING = function(prefix, args) {
    this.send('PONG',args);
};

jIRCs.prototype.irc_NICK = function(prefix, args) {
    var oldNick = this.getNick(prefix),
        newNick = args.pop();
    if(oldNick == this.nickname) {
        this.nickname = newNick;
    }
    this.forEach(this.channels, function(c, channel) {
        if(c.names && oldNick in c.names) {
            this.renderLine(channel,'',oldNick + ' is now known as ' + newNick);
            c.names[newNick] = c.names[oldNick];
            delete(c.names[oldNick]);
        }
    }, this);
    this.forEach(this.displays, function(disobj) {
        this.render(disobj);
    }, this);
};

jIRCs.prototype.irc_JOIN = function(prefix, args) {
    var channel = args.pop().toLowerCase();
    if(prefix != this.nickname) {
        this.renderLine(channel, '', prefix + " joined " + channel);
    } else {
        this.renderLine(channel, '', "You have joined " + channel);
    }
    if(!this.channels[channel].names) {
        this.channels[channel].names = {};
    }
    this.channels[channel].names[prefix] = "";
    if (!this.channels[channel].modes) {
        this.channels[channel].modes = {};
        this.send('MODE', [channel]); // Get the initial modes because the server doesn't send them by default
    }
    this.forEach(this.displays, function(disobj) {
        if(document.activeElement == disobj.messagebox && prefix == this.nickname) {
            this.activateChan(channel, disobj);
        }
        if(disobj.window == channel) {
            this.render(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_PART = function(prefix, args) {
    var channel = args.shift().toLowerCase();
    var reason = args.pop();
    if(this.getNick(prefix) == this.nickname) {
        this.destroyChan(channel);
    } else {
        this.renderLine(channel, '', prefix + " left " + channel + " [" + reason + "]");
        delete(this.channels[channel].names[prefix]);
        this.forEach(this.displays, function(disobj) {
            if(disobj.window == channel) {
                this.render(disobj);
            }
        }, this);
    }
};

jIRCs.prototype.irc_QUIT = function(prefix, args) {
    var reason = args.pop();
    this.forEach(this.channels, function(c, channel) {
        if(channel == 'Status') {
            return;
        }
        if(c.names && prefix in c.names) {
            this.renderLine(channel, '', prefix + ' quit (' + reason + ')');
            delete(c.names[prefix]);
        }
    }, this);
    if(this.getNick(prefix) == this.nickname) {
        // Let ondisconnect handle cleanup
    } else {
        this.forEach(this.displays, function(disobj) {
            this.render(disobj);
        }, this);
    }
};

jIRCs.prototype.irc_PRIVMSG = function(prefix, args) {
    var channel = args.shift().toLowerCase();
    var message = args.pop();
    //account for private messages
    if (channel == this.nickname.toLowerCase()) {
        channel = prefix.toLowerCase();
    }
    if (channel.charAt(0) in this.statuses) {
        prefix += ":" + channel; // give a visible indication that the message isn't for the whole channel
        channel = channel.substr(1); // trim the status char off so the message gets displayed to the correct channel
    }
    if(message.charAt(0) == '\u0001') {
        message = message.split('\u0001')[1];
        if(message.substr(0,6).toUpperCase() == 'ACTION') {
            message = prefix + message.substr(6);
            prefix = '';
            this.renderLine(channel, prefix, message);
        } else {
            args = message.split(' ');
            var method = 'ctcp_' + args.shift().toUpperCase();
            console.log("<<<<<< " + method + "('" + channel + "'," + JSON.stringify(args) + ")");
            if(method in this) {
                this[method](channel, args);
            }
        }
    } else {
        this.renderLine(channel, "<"+prefix+">", message);
    }
};

jIRCs.prototype.irc_NOTICE = function(prefix, args) {
    var nick = '\u2013 ' + this.getNick(prefix);
    var message = args.pop();
    var dest = args.shift().toLowerCase(); // It'll only be used if it's a channel name, anyway
    if (this.chantypes.indexOf(dest.charAt(0)) !== -1 || this.chantypes.indexOf(dest.charAt(1)) !== -1) { // There may or may not be a channel status in the parameter
        nick += ":" + dest + ' \u2013'; // Give a visible indication that the message is a channel notice
        if (dest.charAt(0) in this.statuses) { // it's not going directly to all of a channel
            dest = dest.substr(1); // display it in the correct window
        }
        this.renderLine(dest, nick, message);
    } else {
        nick += ' \u2013'; // \u2013 is an en-dash
        this.forEach(this.displays, function(disobj) {
            this.renderLine(disobj.viewing, nick, message, disobj);
        }, this);
    }
};

jIRCs.prototype.irc_MODE = function(prefix, args) {
    var channel = args.shift().toLowerCase();
    var modes = args.shift().split('');
    if (channel == this.nickname.toLowerCase()) { // handle user modes here
        var adding = true;
        this.forEach(modes, function(mode) {
            switch (mode) {
                case '+':
                    adding = true;
                    break;
                case '-':
                    adding = false;
                    break;
                default:
                    if (adding) {
                        this.userModes.push(mode);
                    } else {
                        var modePos = this.userModes.indexOf(mode);
                        if (modePos != -1) {
                            this.userModes.splice(modePos, 1);
                        }
                    }
            }
        }, this);
    } else {
        // At this point, what's left in args is the parameter list
        this.parseModes(channel, modes, args); // handle the channel modes
    }
};

jIRCs.prototype.irc_CAP = function(prefix, args) {
    // :server CAP dest subcommand :capability list
    if (args[1] == "LS") {
        var supportedCaps = args[2].split(' ');
        if (supportedCaps.indexOf("multi-prefix") != -1) {
            this.send("CAP", ["REQ", ":multi-prefix"]);
        } else if (!this.registered) {
            this.send("CAP", ["END"]);
        }
    } else if (args[1] == "ACK" && !this.registered) {
        this.send("CAP", ["END"]);
    }
}

jIRCs.prototype.irc_001 = function(prefix, args) {
    this.registered = true;
}

jIRCs.prototype.irc_005 = function(prefix, args) {
    var server = args.shift();
    var message = args.pop();
    this.forEach(args, function(arg) {
        if(arg.substr(0,7).toUpperCase() == 'PREFIX=') {
            var modes = arg.substr(8).split(')'); // exclude the open paren, split close paren
            var symbols = modes[1].split('');
            var letters = modes[0].split('');
            this.statuses = this.zip(symbols.concat(letters), letters.concat(symbols));
            this.statusOrder = letters;
            this.statuses[''] = '';
            this.statusOrder.push('');
        }
        if (arg.substr(0, 10) == 'CHANMODES=') {
            var modes = arg.substr(10); // get all the channel modes
            var groups = modes.split(',');
            this.forEach(groups, function(group, groupNum) {
                this.forEach(group, function(mode) {
                    this.chanModes[mode] = groupNum; // map modes to their group index for easy lookup
                }, this);
            }, this);
        }
        if (arg.substr(0, 10) == 'CHANTYPES=') {
            this.chantypes = arg.substr(10).split('');
        }
    }, this);
};

jIRCs.prototype.irc_324 = function(prefix, args) {
    args.shift(); // discard our nick; it's not useful
    var channel = args.shift().toLowerCase();
    var modes = args.shift().split('');
    // At this point, what's left in args (if anything) is the mode parameter list
    this.channels[channel].modes = {}; // Reset the channel modes list as 324 is all of the channel's current modes
    this.parseModes(channel, modes, args);
};

jIRCs.prototype.irc_353 = function(prefix, args) {
    var channel = args[2].toLowerCase();
    if (!this.channels[channel].moreNames) {
        this.channels[channel].names = {};
        this.channels[channel].moreNames = true;
    }
    var names = args[3].split(' '); // Strip the colon and split the names out
    this.forEach(names, function(name) {
        var statusList = '';
        while (name.charAt(0) in this.statuses) {
            statusList += name.charAt(0);
            name = name.substr(1);
        }
        this.channels[channel].names[name] = statusList;
    }, this);
};

jIRCs.prototype.irc_366 = function(prefix, args) {
    var channel = args[1].toLowerCase();
    this.channels[channel].moreNames = false;
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.render(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_332 = function(prefix, args) {
    var channel = args[1].toLowerCase();
    if(!this.channels[channel].topic) {
        this.channels[channel].topic = {};
    }
    this.channels[channel].topic.message = args[2];
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.renderTopic(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_333 = function(prefix, args) {
    var channel = args[1].toLowerCase();
    if(!this.channels[channel].topic) {
        this.channels[channel].topic = {};
    }
    this.channels[channel].topic.creator = args[2];
    this.channels[channel].topic.time = new Date(args[3] * 1000);
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.renderTopic(disobj);
        }
    }, this);
};

jIRCs.prototype.irc_TOPIC = function(prefix, args) {
    var channel = args[0].toLowerCase();
    if(!this.channels[channel].topic) {
        this.channels[channel].topic = {};
    }
    this.channels[channel].topic.creator = prefix;
    this.channels[channel].topic.time = new Date();
    this.channels[channel].topic.message = args[1];
    this.forEach(this.displays, function(disobj) {
        if(disobj.window == channel) {
            this.renderTopic(disobj);
        }
    }, this);
};
<|endoftext|>


<commit_before>function applyQuirks(text,pattern) {

    // Case
    try {
        switch (pattern.character['case']) {
            case "lower":
                text = text.toLowerCase();
                break;
            case "upper":
                text = text.toUpperCase();
                break;
            case "title":
                text = text.toLowerCase().replace(/\b\w/g, function(t) { return t.toUpperCase(); });
                break;
            case "inverted":
                text = text.replace(/[a-zA-Z]/g, function(t) {
                    var out = t.toUpperCase();
                    if (out==t) {
                        return t.toLowerCase();
                    } else {
                        return out;
                    }
                });
                break;
            case "alternating":
                var buffer = text.toLowerCase().split('');
                for(var i=0; i<buffer.length; i+=2){
                    buffer[i] = buffer[i].toUpperCase();
                }
                text = buffer.join('');
                break;
            case "alt-lines":
                if (pattern.line == 0) {
                    buffer = text.toLowerCase();
                } else {
                    buffer = text.toUpperCase();
                }
                text = buffer;
                break;
        }
    } catch(e) {}

    // Replacements
    try {
        var replace = {};
        for (i=0; i<pattern.replacements.length; i++) {
            var replacement = pattern.replacements[i];
            replace[replacement[0]] = replacement[1];
        }
    } catch(e) {
        replace = {};
    }

    try {
        var regex = {};
        for (i=0; i<pattern.regexes.length; i++) {
            var re = pattern.regexes[i];
            regex[re[0]] = re[1];
        }
    } catch(e) {
        regex = {};
    }

    var empty = true;
    for(var key in replace) {
        empty = false;
        break;
    }
    for(var key in regex) {
        empty = false;
        break;
    }

    try {
        if (!empty) {
            try {
                var replacementStrings = Object.keys(replace);
            } catch(e) {
                var replacementStrings = [];
            }
            for (i=0;i<replacementStrings.length;i++) {
                replacementStrings[i] = replacementStrings[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
            }
            try {
                var regexStrings = Object.keys(regex);
            } catch(e) {
                var regexStrings = [];
            }
            if (replacementStrings.length!=0 && regexStrings.length!=0) {
                var reg_from = new RegExp(replacementStrings.join("|")+"|"+regexStrings.join("|"), "g");
            } else if (replacementStrings.length!=0 && regexStrings.length==0) {
                var reg_from = new RegExp(replacementStrings.join("|"), "g");
            } else if (replacementStrings.length==0 && regexStrings.length!=0) {
                var reg_from = new RegExp(regexStrings.join("|"), "g");
            } else {
                var reg_from = new RegExp("", "g");
            }
            text = text.replace(reg_from, function($1) {
                if (replace[$1]) {
                    return replace[$1]
                } else {
                    for (var reg in regexStrings) {
                        var original_text = $1;
                        if (RegExp(regexStrings[reg],'g').test($1)) {
                            var insert_text = regex[regexStrings[reg]];
                            insert_text = insert_text.replace(/([^\\]|^)(\$1)/g, function($1,$2,$3) {
                                return $2+original_text;
                            });
                            insert_text = insert_text.replace(/\\\$1/g, "\$1");
                            return insert_text;
                        }
                    }
                }
                return "";
            });
        }
    } catch(e) {}

    // Prefix
    if (pattern.quirk_prefix) {
        text = pattern.quirk_prefix+' '+text;
    }

    // Suffix
    if (pattern.quirk_suffix) {
        text = text+' '+pattern.quirk_suffix;
    }

    return text
}

function depunct(txt) {
    return txt.replace(/[.,?!']/g, '');
}<commit_msg>casing<commit_after>function applyQuirks(text,pattern) {

    // Case
    //try {
        switch (pattern.character['case']) {
            case "lower":
                text = text.toLowerCase();
                break;
            case "upper":
                text = text.toUpperCase();
                break;
            case "title":
                text = text.toLowerCase().replace(/\b\w/g, function(t) { return t.toUpperCase(); });
                break;
            case "inverted":
                text = text.replace(/[a-zA-Z]/g, function(t) {
                    var out = t.toUpperCase();
                    if (out==t) {
                        return t.toLowerCase();
                    } else {
                        return out;
                    }
                });
                break;
            case "alternating":
                var buffer = text.toLowerCase().split('');
                for(var i=0; i<buffer.length; i+=2){
                    buffer[i] = buffer[i].toUpperCase();
                }
                text = buffer.join('');
                break;
            case "alt-lines":
                if (pattern.line == 0) {
                    buffer = text.toLowerCase();
                } else {
                    buffer = text.toUpperCase();
                }
                text = buffer;
                break;
        }
    //} catch(e) {}

    // Replacements
    try {
        var replace = {};
        for (i=0; i<pattern.replacements.length; i++) {
            var replacement = pattern.replacements[i];
            replace[replacement[0]] = replacement[1];
        }
    } catch(e) {
        replace = {};
    }

    try {
        var regex = {};
        for (i=0; i<pattern.regexes.length; i++) {
            var re = pattern.regexes[i];
            regex[re[0]] = re[1];
        }
    } catch(e) {
        regex = {};
    }

    var empty = true;
    for(var key in replace) {
        empty = false;
        break;
    }
    for(var key in regex) {
        empty = false;
        break;
    }

    try {
        if (!empty) {
            try {
                var replacementStrings = Object.keys(replace);
            } catch(e) {
                var replacementStrings = [];
            }
            for (i=0;i<replacementStrings.length;i++) {
                replacementStrings[i] = replacementStrings[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
            }
            try {
                var regexStrings = Object.keys(regex);
            } catch(e) {
                var regexStrings = [];
            }
            if (replacementStrings.length!=0 && regexStrings.length!=0) {
                var reg_from = new RegExp(replacementStrings.join("|")+"|"+regexStrings.join("|"), "g");
            } else if (replacementStrings.length!=0 && regexStrings.length==0) {
                var reg_from = new RegExp(replacementStrings.join("|"), "g");
            } else if (replacementStrings.length==0 && regexStrings.length!=0) {
                var reg_from = new RegExp(regexStrings.join("|"), "g");
            } else {
                var reg_from = new RegExp("", "g");
            }
            text = text.replace(reg_from, function($1) {
                if (replace[$1]) {
                    return replace[$1]
                } else {
                    for (var reg in regexStrings) {
                        var original_text = $1;
                        if (RegExp(regexStrings[reg],'g').test($1)) {
                            var insert_text = regex[regexStrings[reg]];
                            insert_text = insert_text.replace(/([^\\]|^)(\$1)/g, function($1,$2,$3) {
                                return $2+original_text;
                            });
                            insert_text = insert_text.replace(/\\\$1/g, "\$1");
                            return insert_text;
                        }
                    }
                }
                return "";
            });
        }
    } catch(e) {}

    // Prefix
    if (pattern.quirk_prefix) {
        text = pattern.quirk_prefix+' '+text;
    }

    // Suffix
    if (pattern.quirk_suffix) {
        text = text+' '+pattern.quirk_suffix;
    }

    return text
}

function depunct(txt) {
    return txt.replace(/[.,?!']/g, '');
}<|endoftext|>


<commit_before>import Axios from 'axios'
import decodeHtmlEntities from 'services/decodeHtmlEntities'
import camelCase from 'camelcase'

const axios = Axios.create({
  xsrfCookieName: 'csrftoken',
  xsrfHeaderName: 'X-CSRFTOKEN'
})

axios.interceptors.response.use(response => {
  response.data = camelizeKeys(response.data)
  return response
})

export default {

  login (email, password) {
    return axios.post('/api/v1/session/', {
      email, password
    }).then(({ data: { user } }) => {
      return { user }
    })
  },

  checkLogin () {
    return axios.get('/api/v1/session/').then(({ data: user }) => {
      return user
    }).catch(err => {
      if (err.response && err.response.status === 404) {
        // 404 means we have no current session
        return null
      }
      else {
        // actually an error
        return Promise.reject(err)
      }
    })
  },

  logout () {
    return axios.delete('/api/v1/session/')
  },

  getConversationList () {
    return axios.get('/api/v1/conversations/').then(({ data: conversations }) => {
      conversations.forEach(conversationDecodeHtmlEntities)
      return conversations
    })
  },

  getConversation (id) {
    return axios.get(`/api/v1/conversations/${id}/`).then(({ data: conversation }) => {
      conversationDecodeHtmlEntities(conversation)
      return conversation
    })
  },

  getNextPickupList () {
    return axios.get('/api/v1/pickups/next/').then(({ data: pickups }) => {
      console.log('pickups:', pickups)
      pickups.forEach(setPickupId)
      return pickups
    })
  },

  getPickup (id) {
    return axios.get(`/api/v1/pickups/${id}/`).then(({ data: pickup }) => {
      setPickupId(pickup)
      return pickup
    })
  },

  getStoreList () {
    return axios.get('/api/v1/stores/').then(({ data: stores }) => {
      return stores
    })
  },

  getStore (id) {
    return axios.get(`/api/v1/stores/${id}/`).then(({ data: store }) => {
      return store
    })
  }
}

export function setPickupId (pickup) {
  pickup.id = [pickup.store.id, pickup.at].join('/')
}

export function conversationDecodeHtmlEntities (conversation) {
  if (conversation.messages) {
    conversation.messages.forEach(message => {
      message.body = decodeHtmlEntities(message.body)
    })
  }
  if (conversation.lastMessage) {
    conversation.lastMessage.body = decodeHtmlEntities(conversation.lastMessage.body)
  }
}

export function isObject (x) {
  return typeof x === 'object' &&
    x !== null &&
    !(x instanceof RegExp) &&
    !(x instanceof Error) &&
    !(x instanceof Date)
}

export function camelizeKeys (val) {
  if (isObject(val)) {
    if (Array.isArray(val)) {
      return val.map(camelizeKeys)
    }
    else {
      let newVal = {}
      for (const key of Object.keys(val)) {
        newVal[camelCase(key)] = camelizeKeys(val[key])
      }
      return newVal
    }
  }
  else {
    return val
  }
}
<commit_msg>Fix user data retrieval on login<commit_after>import Axios from 'axios'
import decodeHtmlEntities from 'services/decodeHtmlEntities'
import camelCase from 'camelcase'

const axios = Axios.create({
  xsrfCookieName: 'csrftoken',
  xsrfHeaderName: 'X-CSRFTOKEN'
})

axios.interceptors.response.use(response => {
  response.data = camelizeKeys(response.data)
  return response
})

export default {

  login (email, password) {
    return axios.post('/api/v1/session/', {
      email, password
    }).then(({ data: user }) => {
      return { user }
    })
  },

  checkLogin () {
    return axios.get('/api/v1/session/').then(({ data: user }) => {
      return user
    }).catch(err => {
      if (err.response && err.response.status === 404) {
        // 404 means we have no current session
        return null
      }
      else {
        // actually an error
        return Promise.reject(err)
      }
    })
  },

  logout () {
    return axios.delete('/api/v1/session/')
  },

  getConversationList () {
    return axios.get('/api/v1/conversations/').then(({ data: conversations }) => {
      conversations.forEach(conversationDecodeHtmlEntities)
      return conversations
    })
  },

  getConversation (id) {
    return axios.get(`/api/v1/conversations/${id}/`).then(({ data: conversation }) => {
      conversationDecodeHtmlEntities(conversation)
      return conversation
    })
  },

  getNextPickupList () {
    return axios.get('/api/v1/pickups/next/').then(({ data: pickups }) => {
      console.log('pickups:', pickups)
      pickups.forEach(setPickupId)
      return pickups
    })
  },

  getPickup (id) {
    return axios.get(`/api/v1/pickups/${id}/`).then(({ data: pickup }) => {
      setPickupId(pickup)
      return pickup
    })
  },

  getStoreList () {
    return axios.get('/api/v1/stores/').then(({ data: stores }) => {
      return stores
    })
  },

  getStore (id) {
    return axios.get(`/api/v1/stores/${id}/`).then(({ data: store }) => {
      return store
    })
  }
}

export function setPickupId (pickup) {
  pickup.id = [pickup.store.id, pickup.at].join('/')
}

export function conversationDecodeHtmlEntities (conversation) {
  if (conversation.messages) {
    conversation.messages.forEach(message => {
      message.body = decodeHtmlEntities(message.body)
    })
  }
  if (conversation.lastMessage) {
    conversation.lastMessage.body = decodeHtmlEntities(conversation.lastMessage.body)
  }
}

export function isObject (x) {
  return typeof x === 'object' &&
    x !== null &&
    !(x instanceof RegExp) &&
    !(x instanceof Error) &&
    !(x instanceof Date)
}

export function camelizeKeys (val) {
  if (isObject(val)) {
    if (Array.isArray(val)) {
      return val.map(camelizeKeys)
    }
    else {
      let newVal = {}
      for (const key of Object.keys(val)) {
        newVal[camelCase(key)] = camelizeKeys(val[key])
      }
      return newVal
    }
  }
  else {
    return val
  }
}
<|endoftext|>


<commit_before>Template.leafButtons.helpers({
  leafPushed: function () {
    return Session.get('leafPushed');
  }
});

Template.leafButtons.events({
  'click button': function (event) {
    // Session.set('leafPushed', event.target.id);
    console.log('leafButtons click button: ', event.target.id);
    if (event.target.id === "membersButton") {
      Router.go("/memberProfile");
    } else if (event.target.id === "localBusinessButton") {
      Router.go("/localBusiness");
    }
  }
});

<commit_msg>add button event for my profile<commit_after>Template.leafButtons.events({
  'click button': function (event) {
    if (event.target.id === "myProfileButton") {
      Router.go("/memberProfile");
    } else if (event.target.id === "membersButton") {
      Router.go("/memberProfile");
    } else if (event.target.id === "localBusinessButton") {
      Router.go("/localBusiness");
    }
  }
});

<|endoftext|>


<commit_before>var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var clean = require('gulp-clean');
var ejs = require('gulp-ejs');
var minifyCss = require('gulp-minify-css');
var manifest = require('gulp-manifest');
var args = require('yargs').argv;

var isProduction = (process.env.NODE_ENV == 'production') || args.production;
var VERSION = '0.0.5 Alpha';
var libraries = {
    development: [
        'lib/bootstrap/dist/css/bootstrap.min.css',
        'lib/components-font-awesome/css/font-awesome.min.css',
        'lib/mapbox.js/mapbox.css',
        'lib/angular-carousel/dist/angular-carousel.min.css',
        'lib/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
        'lib/modernizr/modernizr.js',
        'lib/yepnope/yepnope.1.5.0-min.js',
        'lib/moment/min/moment-with-locales.min.js',
        'lib/socket.io-client/socket.io.js',
        'lib/jquery/dist/jquery.js',
        'lib/bootstrap/dist/js/bootstrap.js',
        'lib/mapbox.js/mapbox.uncompressed.js',
        'lib/angular/angular.js',
        'lib/angular-route/angular-route.js',
        'lib/angular-resource/angular-resource.js',
        'lib/angular-touch/angular-touch.js',
        'lib/angular-cookies/angular-cookies.js',
        'lib/angular-animate/angular-animate.js',
        'lib/angular-moment/angular-moment.js',
        'lib/angular-local-storage/dist/angular-local-storage.js',
        'lib/angular-bootstrap/ui-bootstrap.js',
        'lib/angular-bootstrap/ui-bootstrap-tpls.js',
        'lib/angular-carousel/dist/angular-carousel.js',
        'lib/seiyria-bootstrap-slider/js/bootstrap-slider.js',
        /* VK scripts */
        'https://vk.com/js/api/openapi.js',
        'https://vk.com/js/api/share.js?90'
    ],
    production: [
        /* CSS third-party */
        '//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css',
        '//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css',
        '//api.tiles.mapbox.com/mapbox.js/v2.1.3/mapbox.css',
        'lib/angular-carousel/dist/angular-carousel.min.css',
        'lib/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
        /* JS third-party */
        '//code.jquery.com/jquery-2.1.1.min.js',
        '//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js',
        '//api.tiles.mapbox.com/mapbox.js/v2.1.3/mapbox.js',
        '//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment-with-locales.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-resource.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-animate.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-cookies.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-touch.min.js',
        '//cdn.socket.io/socket.io-1.2.1.js',
        'lib/modernizr/modernizr.js',
        'lib/yepnope/yepnope.1.5.0-min.js',
        'lib/angular-local-storage/dist/angular-local-storage.min.js',
        'lib/angular-moment/angular-moment.min.js',
        'lib/angular-bootstrap/ui-bootstrap.min.js',
        'lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
        'lib/angular-carousel/dist/angular-carousel.min.js',
        'lib/seiyria-bootstrap-slider/dist/bootstrap-slider.min.js',
        /* VK scripts */
        'https://vk.com/js/api/openapi.js',
        'https://vk.com/js/api/share.js?90'
    ]
};

gulp.task('clean', function () {
    gulp.src(['dist', 'app.manifest', 'index.html'], {read: false})
        .pipe(clean());
});

gulp.task('build', ['templates', 'css', 'scripts', 'manifest']);

gulp.task('templates', function () {
    var options = {
        settings: [
            { name: 'development', content: !isProduction },
            { name: 'cordova',     content: !!args.cordova },
            { name: 'server_url',  content: args.server_url || '' },
            { name: 'version',     content: VERSION }
        ]
    };
    return gulp.src('index.ejs')
        .pipe(ejs(options))
        .pipe(gulp.dest('.'));
});

gulp.task('manifest', function () {
    var sources = [
        'index.html',
        'src/img/**',
        'src/js/main.js',
        'src/js/app/templates/**'
    ];

    sources = isProduction ?
        sources.concat([ 'dist/spacebox.min.css', 'dist/spacebox.min.js' ]) :
        sources.concat([ 'dist/spacebox.css', 'dist/spacebox.js' ]);

    return gulp.src(sources, {base: './'})
        .pipe(manifest({
            cache: isProduction ? libraries.production : libraries.development,
            hash: true,
            preferOnline: true,
            network: ['http://*', 'https://*', '*'],
            filename: 'app.manifest',
            exclude: 'app.manifest'
        }))
        .pipe(gulp.dest('.'));
});

gulp.task('css', function () {
    return gulp.src('src/css/**/*.css')
        .pipe(concat('spacebox.css'))
        .pipe(gulp.dest('dist'))
        .pipe(rename('spacebox.min.css'))
        .pipe(minifyCss())
        .pipe(gulp.dest('dist'));
});

gulp.task('scripts', function () {
    return gulp.src([ '/src/js/app/app.js', '/src/js/app/**/*.js' ])
        .pipe(concat('spacebox.js'))
        .pipe(gulp.dest('dist'))
        .pipe(rename('spacebox.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dist'));
});<commit_msg>Added watch task for gulp.<commit_after>var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var clean = require('gulp-clean');
var ejs = require('gulp-ejs');
var minifyCss = require('gulp-minify-css');
var manifest = require('gulp-manifest');
var args = require('yargs').argv;

var isProduction = (process.env.NODE_ENV == 'production') || args.production;
var VERSION = '0.0.5 Alpha';
var libraries = {
    development: [
        'lib/bootstrap/dist/css/bootstrap.min.css',
        'lib/components-font-awesome/css/font-awesome.min.css',
        'lib/mapbox.js/mapbox.css',
        'lib/angular-carousel/dist/angular-carousel.min.css',
        'lib/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
        'lib/modernizr/modernizr.js',
        'lib/yepnope/yepnope.1.5.0-min.js',
        'lib/moment/min/moment-with-locales.min.js',
        'lib/socket.io-client/socket.io.js',
        'lib/jquery/dist/jquery.js',
        'lib/bootstrap/dist/js/bootstrap.js',
        'lib/mapbox.js/mapbox.uncompressed.js',
        'lib/angular/angular.js',
        'lib/angular-route/angular-route.js',
        'lib/angular-resource/angular-resource.js',
        'lib/angular-touch/angular-touch.js',
        'lib/angular-cookies/angular-cookies.js',
        'lib/angular-animate/angular-animate.js',
        'lib/angular-moment/angular-moment.js',
        'lib/angular-local-storage/dist/angular-local-storage.js',
        'lib/angular-bootstrap/ui-bootstrap.js',
        'lib/angular-bootstrap/ui-bootstrap-tpls.js',
        'lib/angular-carousel/dist/angular-carousel.js',
        'lib/seiyria-bootstrap-slider/js/bootstrap-slider.js',
        /* VK scripts */
        'https://vk.com/js/api/openapi.js',
        'https://vk.com/js/api/share.js?90'
    ],
    production: [
        /* CSS third-party */
        '//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css',
        '//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css',
        '//api.tiles.mapbox.com/mapbox.js/v2.1.3/mapbox.css',
        'lib/angular-carousel/dist/angular-carousel.min.css',
        'lib/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
        /* JS third-party */
        '//code.jquery.com/jquery-2.1.1.min.js',
        '//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js',
        '//api.tiles.mapbox.com/mapbox.js/v2.1.3/mapbox.js',
        '//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment-with-locales.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-resource.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-animate.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-cookies.min.js',
        '//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-touch.min.js',
        '//cdn.socket.io/socket.io-1.2.1.js',
        'lib/modernizr/modernizr.js',
        'lib/yepnope/yepnope.1.5.0-min.js',
        'lib/angular-local-storage/dist/angular-local-storage.min.js',
        'lib/angular-moment/angular-moment.min.js',
        'lib/angular-bootstrap/ui-bootstrap.min.js',
        'lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
        'lib/angular-carousel/dist/angular-carousel.min.js',
        'lib/seiyria-bootstrap-slider/dist/bootstrap-slider.min.js',
        /* VK scripts */
        'https://vk.com/js/api/openapi.js',
        'https://vk.com/js/api/share.js?90'
    ]
};

gulp.task('clean', function () {
    gulp.src(['dist', 'app.manifest', 'index.html'], {read: false})
        .pipe(clean());
});

gulp.task('build', ['templates', 'css', 'scripts', 'manifest']);

gulp.task('watch', ['build'], function () {
    gulp.watch('src/js/**/*.js', ['scripts', 'manifest']);
    gulp.watch('src/css/**/*.css', ['css', 'manifest']);
});

gulp.task('templates', function () {
    var options = {
        settings: [
            { name: 'development', content: !isProduction },
            { name: 'cordova',     content: !!args.cordova },
            { name: 'server_url',  content: args.server_url || '' },
            { name: 'version',     content: VERSION }
        ]
    };
    return gulp.src('index.ejs')
        .pipe(ejs(options))
        .pipe(gulp.dest('.'));
});

gulp.task('manifest', function () {
    var sources = [
        'index.html',
        'src/img/**',
        'src/js/main.js',
        'src/js/app/templates/**'
    ];

    sources = isProduction ?
        sources.concat([ 'dist/spacebox.min.css', 'dist/spacebox.min.js' ]) :
        sources.concat([ 'dist/spacebox.css', 'dist/spacebox.js' ]);

    return gulp.src(sources, {base: './'})
        .pipe(manifest({
            cache: isProduction ? libraries.production : libraries.development,
            hash: true,
            preferOnline: true,
            network: ['http://*', 'https://*', '*'],
            filename: 'app.manifest',
            exclude: 'app.manifest'
        }))
        .pipe(gulp.dest('.'));
});

gulp.task('css', function () {
    return gulp.src('src/css/**/*.css')
        .pipe(concat('spacebox.css'))
        .pipe(gulp.dest('dist'))
        .pipe(rename('spacebox.min.css'))
        .pipe(minifyCss())
        .pipe(gulp.dest('dist'));
});

gulp.task('scripts', function () {
    return gulp.src([ '/src/js/app/app.js', '/src/js/app/**/*.js' ])
        .pipe(concat('spacebox.js'))
        .pipe(gulp.dest('dist'))
        .pipe(rename('spacebox.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dist'));
});<|endoftext|>


<commit_before><commit_msg>Pull Persistent Logic into Background Page<commit_after>var user1, user2, currentSession, startTime, endTime, currentInterval,pairingDurationMs, timer;
var sessions = [];
var totalTimeWorking = 0;
var views = chrome.extension.getViews({ type: "popup" })
var view = views[0]

function PairingSession(user1, user2){
  this.drive = user1;
  this.navigate = user2;
  this.timeWorked = 0;
  this.timePaused = 0;
}

function TotalSessionInfo(activeTime, pauseTime){
  this.totalTime = pauseTime + activeTime;
  this.activeTime = activeTime;
  this.pauseTime = pauseTime;
  this.user1 = user1;
  this.user2 = user2;
}

function setInterval(interval){
  currentInterval = interval;
  pairingDurationMs = currentInterval * 60000;
}
function pause(){
  if(timer){
    stopTimer();
  } else {
    console.log("unpause");
    startTimerCount();
  }
}

function endPairingSession(){
   if(currentSession.timeWorked === 0){
    endSession();
  }
  var activeTime = 0;
  var inActiveTime = 0;
  sessions.forEach(function(pairSession){
    activeTime += pairSession.timeWorked;
    inActiveTime += pairSession.timePaused;
  })
  stopTimer();
  sessions.push(new TotalSessionInfo(activeTime, inActiveTime));
  console.log(sessions);
}

function startPairing(){
  var date = new Date();
  startTime = date.getTime();
  currentSession = new PairingSession(user1, user2);
  console.log(currentSession);
  sessions.push(currentSession);
  console.log(sessions);
  startTimerCount();
  updateTimerCountdown();
}

function startTimerCount(){
  timer = setInterval(function(){
    totalTimeWorking ++;
    currentInterval --;
    updateTimerCountdown();
    checkDuration();
  }, 60000);
  console.log(startTimer);
}

function stopTimer(){
  console.log("timer", timer);
  clearInterval(timer);
  timer = null;
}

function checkDuration(){
  if(currentInterval === 0){
    endSession();
    alert('Switch it ^');
    startPairing();
  }
}

function endSession(){
  var date = new Date();
  endTime = date.getTime();
  currentInterval = pairingDurationMs / 60000;
  currentSession.timeWorked = currentInterval;
  currentSession.timePaused =  (endTime - startTime - (totalTimeWorking * 60000)) / 60000;
  if(currentSession.timePaused == null || currentSession.timePaused < .1){
    currentSession.timePaused = 0;
  }
  totalTimeWorking = 0;
}

function updateTimerCountdown(){
  view.document.getElementsByClassName('countdown').innerHTML =currentInterval;
}

<|endoftext|>


<commit_before>/**
 * Attention ce fichier est généré automatiquement !
 * DtDefinitionsLabel
 */

const traduction = {

};

export default traduction;
<commit_msg>[tracution] add entity traductions<commit_after>/**
 * Attention ce fichier est généré automatiquement !
 * DtDefinitionsLabel
 */

const traduction = {
    movie: {
        code: 'Code',
        title: 'Titre',
        originalTitle: 'Titre original',
        poster: 'URL de l\'affiche',
        synopsis: 'Synopsis',
        trailerName: 'Nom de la bande annonce',
        trailerHRef: 'URL de la bande annonce',
        shortSynopsis: 'Synopsis court',
        runtime: 'Durée en minutes',
        movieType: 'Type de film',
        productionYear: 'Année de production'
    }
};

export default traduction;
<|endoftext|>