GitHub Timeline на vue.js

  1. <div id="timeline">
  2.   <h1>GitHub Timeline</h1>
  3.   <div class="progress">
  4.     <div class="line" :style="{ width: (Math.floor(time * 100 / timeMax) + '%') }"></div>
  5.     <div class="background"></div>
  6.   </div>
  7.   <ul>
  8.     <li v-for="event in events">
  9.       <img class="avatar" :src="event.actor.avatar_url" />
  10.       <div class="headline">
  11.         <div class="time">{{ event.created_at|formatDate }}</div>
  12.         <a class="user" :href="'https://github.com/' + event.actor.login">{{ event.actor.login }}</a>
  13.       </div>
  14.       <div class="clearfix"></div>
  15.       <div v-if="event.type === 'ForkEvent'">
  16.         forked repository <repo :name="event.repo.name"></repo>
  17.       </div>
  18.       <div v-else-if="event.type === 'IssuesEvent'">
  19.         {{ event.payload.action }} issue "{{ event.payload.issue.title }}" on <repo :name="event.repo.name"></repo>
  20.       </div>
  21.       <div v-else-if="event.type === 'PullRequestEvent'">
  22.         {{ event.payload.action }} pull request #{{ event.payload.number }} "{{ event.payload.pull_request.title }}" on <repo :name="event.repo.name"></repo>
  23.       </div>
  24.       <div v-else-if="event.type === 'PushEvent'">
  25.         pushed {{ event.payload.commits.length }} commits to <repo :name="event.repo.name"></repo>
  26.       </div>
  27.       <div v-else>
  28.         {{ event.type }} on <repo :name="event.repo.name"></repo>
  29.       </div>
  30.     </li>
  31.   </ul>
  32. </div>
  1. Vue.component('repo', {
  2.   template: '<a :href="\'https://github.com/\' + name">{{ name }}</a>',
  3.   props: ['name']
  4. });
  5.  
  6. var vm = new Vue({
  7.   el: '#timeline',
  8.   data: {
  9.     events: null,
  10.     timeMax: 60,
  11.     time: 0,
  12.     timer: null
  13.   },
  14.  
  15.   created: function() {
  16.     this.fetchData();
  17.   },
  18.  
  19.   filters: {
  20.     formatDate: function(v) {
  21.       return v.replace(/T|Z/g, ' ');
  22.     }
  23.   },
  24.  
  25.   methods: {
  26.     fetchData: function() {
  27.       var xhr = new XMLHttpRequest();
  28.       var self = this;
  29.       xhr.open('GET', 'https://api.github.com/events');
  30.       xhr.onload = function() {
  31.         self.events = JSON.parse(xhr.responseText);
  32.         self.timeMax = xhr.getResponseHeader("X-Poll-Interval");
  33.         self.startTimer();
  34.       };
  35.       xhr.send();
  36.     },
  37.     startTimer: function() {
  38.       var self = this;
  39.       this.time = 0;
  40.       this.timer = setInterval(function() {
  41.         self.time++;
  42.         if (self.time >= self.timeMax) {
  43.           clearInterval(self.timer);
  44.           self.fetchData();
  45.         }
  46.       }, 1000);
  47.     }
  48.   }
  49. });
  1. body {
  2.   font-family: Helvetica, Verdana, Arial, sans-serif;
  3.   font-size: 16px;
  4.   font-weight: 300;
  5. }
  6.  
  7. #timeline h1 {
  8.   text-align: center;
  9. }
  10.  
  11. .progress {
  12.   position: relative;
  13.   display: block;
  14.   height: 2px;
  15.   margin: 0 auto;
  16.   width: 70%;
  17. }
  18. .progress div {
  19.   position: absolute;
  20.   top: 0;
  21.   display: block;
  22.   height: 2px;
  23. }
  24. .progress .background {
  25.   background-color: #c7c7c7;
  26.   width: 100%;
  27. }
  28. .progress .line {
  29.   background-color: #5282d2;
  30.   z-index: 999;
  31. }
  32.  
  33. #timeline {
  34.   width: 90%;
  35.   margin: 0 auto;
  36. }
  37.  
  38. #timeline ul {
  39.   list-style: none;
  40.   margin: 10px 0;
  41.   padding: 0;
  42. }
  43.  
  44. #timeline li {
  45.   display: block;
  46.   position: relative;
  47.   background-color: #FEFEFE;
  48.   border: 2px solid #FEFEFE;
  49.   margin: 0 auto 10px;
  50.   padding: 6px;
  51.   padding-bottom: 5px;
  52.   box-shadow: 0px 1px 2px rgba(34, 25, 25, 0.4);
  53. }
  54.  
  55. .avatar {
  56.   float: left;
  57.   max-width: 48px;
  58.   max-height: 48px;
  59.   margin-bottom: 5px;
  60. }
  61.  
  62. .headline {
  63.   float: left;
  64.   margin-left: 8px;
  65. }
  66.  
  67. .user {
  68.   color: #000;
  69.   font-size: 120%;
  70.   font-weight: bold;
  71. }
  72.  
  73. .small,
  74. .time {
  75.   font-size: 80%;
  76.   color: #777;
  77. }
  78.  
  79. .time {
  80.   margin-bottom: 5px;
  81.   font-size: small;
  82. }
  83.  
  84. .clearfix {
  85.   clear: both;
  86. }
Отображает список последних событий на GitHub'e. Используется vue.js.
Обновление происходит по ajax без перезагрузки страницы. Показывается таймер до обновления данных. Также показан пример компонента <repo> для уменьшения копипасты.
Зеркало на jsfiddle.

GitHub Timeline

  • {{ event.created_at|formatDate }}
    {{ event.actor.login }}
    commented commit in
    {{ event.payload.comment.body }}
    created {{ event.payload.ref_type }}
    deleted {{ event.payload.ref_type }}
    forked repository
    commented issue {{ event.payload.issue.title }} on
    {{ event.payload.comment.body }}
    {{ event.payload.action }} issue "{{ event.payload.issue.title }}" on
    {{ event.payload.action }} pull request #{{ event.payload.number }} "{{ event.payload.pull_request.title }}" on
    pushed {{ event.payload.commits.length }} commits to
    start watching repository
    {{ event.type }} on

Реклама

Мы в соцсетях

tw tg yt gt