├── .gitignore ├── README.md ├── app.js ├── app.json ├── app.wxss ├── pages ├── detail │ ├── detail.js │ ├── detail.wxml │ └── detail.wxss └── index │ ├── index.js │ ├── index.wxml │ └── index.wxss └── utils ├── api.js ├── formate.js └── parallel.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Github Card with MINA(微信小程序) 2 | 3 | ### Note 4 | 5 | This Project just have fun with `小程序`, will be deprecated from now. Sorry! 6 | 7 | > using the github API and producing the card for github user 8 | 9 | ![github](https://cloud.githubusercontent.com/assets/6913898/21589837/f90d4ed4-d130-11e6-8116-28b9001cdda0.gif) 10 | 11 | Inspired by [Resume](https://resume.github.io/) 12 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | App({ 2 | onLaunch: function() { 3 | console.log('onLaunch'); 4 | }, 5 | 6 | storageName: '__github_info__' 7 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/index/index", 4 | "pages/detail/detail" 5 | ], 6 | "window":{ 7 | "backgroundTextStyle":"light", 8 | "navigationBarBackgroundColor": "#eee", 9 | "navigationBarTitleText": "github", 10 | "navigationBarTextStyle":"black" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monkindey/wx-github/48ab76e27769a4867a8f74379d2ae648a18b0ff7/app.wxss -------------------------------------------------------------------------------- /pages/detail/detail.js: -------------------------------------------------------------------------------- 1 | var formate = require('../../utils/formate'); 2 | var getYear = formate.getYear; 3 | var computePopularity = formate.computePopularity; 4 | var app = getApp(); 5 | 6 | 7 | Page({ 8 | data: { 9 | user: {}, 10 | repo: [], 11 | prs: [], 12 | language: [] 13 | }, 14 | 15 | onShareAppMessage: function() { 16 | return { 17 | title: '自定义分享标题', 18 | desc: '自定义分享描述', 19 | path: '/page/user?id=123' 20 | } 21 | }, 22 | 23 | collectPr: function(prs) { 24 | prs = prs.reduce(function(p, c) { 25 | if(!p[c.repository_url]) { 26 | p[c.repository_url] = { 27 | popularity: 1 28 | }; 29 | }else { 30 | p[c.repository_url].popularity += 1; 31 | } 32 | return p; 33 | }, {}); 34 | 35 | return Object.keys(prs).map(function(v) { 36 | return { 37 | name: v.replace('https://api.github.com/repos/', ''), 38 | popularity: prs[v].popularity 39 | } 40 | }); 41 | }, 42 | 43 | /** 44 | * [{ language }] => [{ xxx: { popularity: xxx }}] 45 | */ 46 | collectLanguage: function(repo) { 47 | var language = {}; 48 | var total = 0; 49 | repo.forEach(function(r) { 50 | var lang = r.language; 51 | if(!lang) { 52 | return false; 53 | }else if(!language[lang]) { 54 | language[lang] = { 55 | popularity: 1 56 | }; 57 | }else { 58 | language[lang].popularity += 1; 59 | } 60 | total++; 61 | }); 62 | 63 | return Object.keys(language).map(function(l) { 64 | return { 65 | name: l, 66 | percent: Math.round(language[l].popularity / total * 100), 67 | popularity: language[l].popularity 68 | } 69 | }) 70 | }, 71 | 72 | onLoad: function() { 73 | var detail = wx.getStorageSync(app.storageName) || {}; 74 | var repo = detail.repo.filter(function(r) { 75 | return !r.fork 76 | }); 77 | 78 | var prs = this.collectPr(detail.pr.items); 79 | 80 | detail.user.year = getYear(detail.user.created_at); 81 | 82 | repo.sort(function(p, c) { 83 | return (computePopularity(p) > computePopularity(c)) 84 | }).reverse(); 85 | 86 | prs.sort(function(p, c) { 87 | return p.popularity > c.popularity; 88 | }).reverse(); 89 | 90 | this.setData({ 91 | user: detail.user, 92 | repo: repo.slice(0, 5), 93 | prs: prs.slice(0, 5), 94 | language: this.collectLanguage(repo) 95 | }) 96 | } 97 | }) -------------------------------------------------------------------------------- /pages/detail/detail.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ user.name }} 7 | 8 | 9 | 10 | Profile 11 | On Github since {{ user.year }}, {{ user.name }} is a developer based in {{ user.location }} with {{ user.public_repos }} public repositories and {{ user.followers }} followers. 12 | 13 | 14 | 15 | 16 | Language 17 | 18 | 19 | {{ item.name }}({{ item.percent }}%) 20 | 21 | 22 | 23 | 24 | 25 | Repositories 26 | 27 | 28 | {{ item.name }} 29 | {{ item.description }} 30 | This repository has {{ item.stargazers_count }} starsstar {{ item.forks_count }} forksfork 31 | 32 | 33 | 34 | 35 | 36 | 37 | Contributions 38 | 39 | 40 | {{ item.name }} 41 | {{ user.name }} has contributed for {{ item.popularity }} commit(s) 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /pages/detail/detail.wxss: -------------------------------------------------------------------------------- 1 | /** 2 | * 颜色 #4fc08d #4078c0 3 | */ 4 | page { 5 | color: #666; 6 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 7 | } 8 | 9 | 10 | /* common */ 11 | .title { 12 | font-size: 18px; 13 | display: block; 14 | border-left: 3px solid #4078c0; 15 | padding: 5rpx; 16 | text-indent: 15rpx; 17 | margin-top: 20rpx; 18 | } 19 | 20 | .highlight { 21 | color: #4fc08d; 22 | } 23 | 24 | .detail-view { 25 | display: flex; 26 | flex-direction: column; 27 | padding: 20rpx; 28 | } 29 | 30 | .avatar-view { 31 | margin-top: 20px; 32 | margin-bottom: 20px; 33 | display: flex; 34 | justify-content: center; 35 | } 36 | 37 | .avatar { 38 | border: 1rpx solid #ccc; 39 | height: 200rpx; 40 | width: 200rpx; 41 | border-radius: 200rpx; 42 | } 43 | 44 | .basic { 45 | margin-bottom: 20rpx; 46 | text-align: center; 47 | } 48 | 49 | .basic .name { 50 | color: #ccc; 51 | display: block; 52 | } 53 | 54 | .basic .email { 55 | font-size: 13px; 56 | margin-top: 6rpx; 57 | color: #4078c0; 58 | } 59 | 60 | .profile-detail { 61 | text-indent: 34rpx; 62 | font-size: 13px; 63 | display: block; 64 | padding: 0; 65 | line-height: 1.3; 66 | margin-top: 5rpx; 67 | } 68 | 69 | .repo { 70 | font-size: 13px; 71 | margin-top: 15rpx; 72 | } 73 | 74 | .repo-name { 75 | font-size: 15px; 76 | font-weight: 500; 77 | color: #4fc08d; 78 | } 79 | 80 | .repo-desc, .repo-desc { 81 | display: block; 82 | } 83 | 84 | .repo-desc, .language-percent { 85 | color: #ccc; 86 | font-size: 12px; 87 | } 88 | 89 | 90 | -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | var parallel = require('../../utils/parallel').default; 2 | var app = getApp(); 3 | 4 | Page({ 5 | data: { 6 | name: '', 7 | detail: {} 8 | }, 9 | 10 | bindInputName: function(e) { 11 | this.setData({ 12 | name: e.detail.value 13 | }) 14 | }, 15 | 16 | bindSearch: function() { 17 | var userUrl = 'https://api.github.com/users/' + this.data.name; 18 | var repoUrl = 'https://api.github.com/users/' + this.data.name + '/repos?per_page=100'; 19 | var prUrl = 'https://api.github.com/search/issues?q=type:pr+is:merged+author:' 20 | + this.data.name + '&per_page=100' 21 | var me = this; 22 | 23 | wx.showToast({ 24 | title: '加载中', 25 | icon: 'loading', 26 | duration: 20000 27 | }); 28 | 29 | var tasks = [userUrl, repoUrl, prUrl].map(function(url) { 30 | return function() { 31 | return fetch(url) 32 | } 33 | }); 34 | 35 | parallel(tasks, function(user, repo, pr) { 36 | wx.hideToast(); 37 | wx.setStorageSync(app.storageName, { 38 | user: user, 39 | repo: repo, 40 | pr: pr 41 | }); 42 | wx.navigateTo({ 43 | url: '../detail/detail' 44 | }) 45 | }) 46 | } 47 | }) -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | page { 2 | color: #666; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 4 | height: 100%; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | 10 | view { 11 | width: 80%; 12 | } 13 | 14 | .input-name { 15 | margin-bottom: 20rpx; 16 | } -------------------------------------------------------------------------------- /utils/api.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monkindey/wx-github/48ab76e27769a4867a8f74379d2ae648a18b0ff7/utils/api.js -------------------------------------------------------------------------------- /utils/formate.js: -------------------------------------------------------------------------------- 1 | function getYear(date) { 2 | return new Date(date).getFullYear(); 3 | } 4 | 5 | function computePopularity(repo) { 6 | return repo.stargazers_count * 2 + parseInt(repo.forks_count) 7 | } 8 | 9 | module.exports = { 10 | getYear: getYear, 11 | computePopularity: computePopularity 12 | } 13 | 14 | -------------------------------------------------------------------------------- /utils/parallel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 并行处理异步操作 3 | */ 4 | export default function parallel(tasks, callback) { 5 | var len = tasks.length; 6 | var results = []; 7 | tasks.forEach(function(task, i) { 8 | // 去fetch每一个url 9 | task().then(function(res) { 10 | if(res.ok) { 11 | return res.json(); 12 | } 13 | }).then(function(json) { 14 | len--; 15 | results[i] = json; 16 | if(len === 0) { 17 | callback.apply(null, results); 18 | } 19 | }) 20 | }) 21 | } --------------------------------------------------------------------------------