Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] profile card #8

Open
serapath opened this issue Jan 12, 2018 · 92 comments
Open

[feature] profile card #8

serapath opened this issue Jan 12, 2018 · 92 comments

Comments

@serapath
Copy link
Member

@serapath serapath mentioned this issue Jan 12, 2018
10 tasks
@serapath
Copy link
Member Author

more inspiration

@serapath
Copy link
Member Author

@noraliucode
Copy link

May I try on this issue? :)

@ninabreznik
Copy link
Member

ninabreznik commented Jan 13, 2018 via email

@noraliucode
Copy link

Fantastic. Will try to compose those codes together.

@serapath
Copy link
Member Author

cool :-)

@serapath serapath changed the title profile card feature: profile card Jan 20, 2018
@serapath serapath changed the title feature: profile card [feature] profile card Jan 20, 2018
@ninabreznik
Copy link
Member

I also added a first draft of a card https://codepen.io/ninabreznik/pen/JMggRB?editors=0011

Next step is to use @kiecoo 's module for getting the data

@ninabreznik
Copy link
Member

ninabreznik commented Feb 22, 2018

@kiecoo So, the next step would be to add your module to my Profile card and then also adapt this profile card a bit more to fit the data nicely.

To use your module inside of Profile card, you need to write in the first lines, next to bel and csjs-inject etc.

var githubData = require('name-of-your-module')

Then if you do

console.log(githubData)

you should see the object you provide through this module into the Profile card

@kiecoo
Copy link

kiecoo commented Feb 22, 2018

I would go ahead to add my module into Profile card~

@kiecoo
Copy link

kiecoo commented Feb 28, 2018

@ninabreznik About the Profile card

【What I am trying to do】
With doing the profile card to make it "flippable" as Alex told me, I am trying using the npm module of bel-card & bel-profile


【the problems I met】
I got stuck that I couldn't let "the module of bel-profile &bel-card " run successfully in codepen, could you help me to have a look about what I did wrong?

(the reason of putting in codepen is that I could use codepen to make myself to understand competely detail of these two modules at first so that I could make sure that I would use them in the right situation

@ninabreznik
Copy link
Member

@kiecoo I'm reposting the code here

PROFILE CARD 1

var bel = require('bel')
var csjs = require('csjs-inject')

/* --------------------------------------------------------
                          FONTS
---------------------------------------------------------- */

var fonts             = ['https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css', 'https://fonts.googleapis.com/css?family=Ubuntu']
var fontAwesome       = bel`<link href=${fonts[0]} rel='stylesheet' type='text/css'>`
var fontUbuntu        = bel`<link href=${fonts[1]} rel="stylesheet">`
var font_ubuntu       = 'Ubuntu, sans-serif'
document.head.appendChild(fontAwesome)
document.head.appendChild(fontUbuntu)
/* --------------------------------------------------------
                        VARIABLES
---------------------------------------------------------- */
// DATA
var data = {
  "username": "ninabreznik",
  "projects": [
    "http://www.refugeeswork.com",
    "http://www.wizardamigos.com",
    "http://fairydust.agency"
  ],
  "background": [
    "Javascript",
   "Entrepreneurship",
    "Community building"
  ],
  "interests": [
    "p2p web",
    "self employment",
    "javascript",
    "blockchain"
  ],
  "github": "https://github.com/ninabreznik"
}

// VARIABLES
var profileImageUrl   = 'https://nomadlist.com/assets/img/cities/phuket-thailand-500px.jpg'
var githubUrl = data['github']

//  COlORS
var blue = '#365899'
var grey = '#616770'
var lightGrey = '#90949c'

//STATE
var projectsExpanded = false;

// CSS
var css = csjs`
  .main {
    font-family: ${font_ubuntu};
    display: flex;
    align-items: start;
  }
  .button:hover {
    background: none !important;
  }
  .imageContainer {
    display: flex;
  }
  .textContainer {
    margin-left: 5%;
    min-width: 250px;
    line-height: 18px;
  }
  .username {
    font-weight: bold;
    text-decoration: none;
    color: ${blue};
    font-size: 14px;
    font-weight: bold;
    line-height: 20px;
    padding-bottom: 1px;
  }
  .profileImage {
    border-radius: 50%;
    width: 72px;
    height: 72px;
  }
  .background {
    font-size: 0.7em;
  }
  .interests {
    color: ${lightGrey};
    font-size: 12px;
  }
  .interestItems {
    color: ${lightGrey};
    font-size: 12px;
    margin-left: 2px;
  }
  .backgroundItem {
    color: ${grey};
    border: .5px solid ${lightGrey};
    border-radius: 3px;
    padding: 2px;
    font-size: 11px;
    margin-left: 3px;
    align-items: center;
    letter-spacing: -0.01em;
    font-weight: bold;
  }
  .projectsContainer {
    color: ${blue};
    cursor: pointer;
    text-decoration: none;
    font-size: 12px;
  }
  .projectsTitle:hover,
  .username:hover {
    text-decoration: underline;
  }
  .projectList {
    line-height: 25px;
  }
  .projectItem {
    text-decoration: none;
  }
  .line {
    border-top: 1px #dddfe2 solid;
    margin: 5px 0;
  }
`

function profile () {
  return bel`
    <div class=${css.main}>
        <div class=${css.imageContainer}>
          <img src=${profileImageUrl} class=${css.profileImage}>
        </div>
        <div class=${css.textContainer}>
          <a href=${githubUrl} class=${css.username}>@${data['username']}></a>
          ${showBackground(data)}
          ${showProjects(data)}
          ${showInterests(data)}
        </div>
    </div>`
}

/* --------------------------------------------------------
                          HELPERS
  ---------------------------------------------------------- */
function showBackground (data) {
 return bel`
  <div>
    <div class=${css.background}>
      <i class="fa fa-shield" aria-hidden="true"></i>
      ${data['background'].map((el)=>bel`<span class=${css.backgroundItem}>${el + ' '}</span>`)}
    </div>
  </div>`
}

function showProjects (data) {
var len = data['projects'].length
return bel`
  <div>
    <div class=${css.projectsContainer} onclick=${event => showHideProjects(event.currentTarget, data)}>
      <div class=${css.projectsTitle}>${len} projects listed</div>
    </div>
  </div>
`
}

function showHideProjects (el, data) {
console.log(el)
if (projectsExpanded === true) {
  var list = document.querySelector('#list')
  el.removeChild(list)
  projectsExpanded = false
} else {
  var projectList = bel`
    <div class=${css.projectList} id='list'>
      <div class=${css.line}></div>
      ${data['projects'].map((el)=>bel`<div class=${css.projectItem}>${el + ' '}</div>`)}
      <div class=${css.line}></div>
    </div>`
  el.appendChild(projectList)
  projectsExpanded = true
}
}

function showInterests (data) {
return bel`
  <div class=${css.interests}>
    <span class=${css.tag}>List of interests:</span>
    ${data['interests'].map((el)=>bel`<span class=${css.interestItems}>${el + ' '}</span>`)}
  </div>`
}

var html = profile()
document.body.appendChild(html)

PROFILE CARD 2

var bel = require('bel')
var csjs = require('csjs-inject')

/* --------------------------------------------------------
                          FONTS
---------------------------------------------------------- */

var fonts             = ['https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css', 'https://fonts.googleapis.com/css?family=Ubuntu']
var fontAwesome       = bel`<link href=${fonts[0]} rel='stylesheet' type='text/css'>`
var fontUbuntu        = bel`<link href=${fonts[1]} rel="stylesheet">`
var font_ubuntu       = 'Ubuntu, sans-serif'
document.head.appendChild(fontAwesome)
document.head.appendChild(fontUbuntu)
/* --------------------------------------------------------
                        VARIABLES
---------------------------------------------------------- */
// DATA
var data = {
  "username": "ninabreznik",
  "projects": [
    "http://www.refugeeswork.com",
    "http://www.wizardamigos.com",
    "http://fairydust.agency"
  ],
  "background": [
    "Javascript",
   "Entrepreneurship",
    "Community building"
  ],
  "interests": [
    "p2p web",
    "self employment",
    "javascript",
    "blockchain"
  ],
  "github": "https://github.com/ninabreznik"
}

// VARIABLES
var profileImageUrl   = 'https://nomadlist.com/assets/img/cities/phuket-thailand-500px.jpg'
var githubUrl = data['github']

//  COlORS
var blue = '#365899'
var grey = '#616770'
var lightGrey = '#90949c'

//STATE
var projectsExpanded = false;

// CSS
var css = csjs`
  .main {
    font-family: ${font_ubuntu};
    display: flex;
    align-items: start;
  }
  .button:hover {
    background: none !important;
  }
  .imageContainer {
    display: flex;
  }
  .textContainer {
    margin-left: 5%;
    min-width: 250px;
    line-height: 18px;
  }
  .username {
    font-weight: bold;
    text-decoration: none;
    color: ${blue};
    font-size: 14px;
    font-weight: bold;
    line-height: 20px;
    padding-bottom: 1px;
  }
  .profileImage {
    border-radius: 50%;
    width: 72px;
    height: 72px;
  }
  .background {
    font-size: 0.7em;
  }
  .interests {
    color: ${lightGrey};
    font-size: 12px;
  }
  .interestItems {
    color: ${lightGrey};
    font-size: 12px;
    margin-left: 2px;
  }
  .backgroundItem {
    color: ${grey};
    border: .5px solid ${lightGrey};
    border-radius: 3px;
    padding: 2px;
    font-size: 11px;
    margin-left: 3px;
    align-items: center;
    letter-spacing: -0.01em;
    font-weight: bold;
  }
  .projectsContainer {
    color: ${blue};
    cursor: pointer;
    text-decoration: none;
    font-size: 12px;
  }
  .projectsTitle:hover,
  .username:hover {
    text-decoration: underline;
  }
  .projectList {
    line-height: 25px;
  }
  .projectItem {
    text-decoration: none;
  }
  .line {
    border-top: 1px #dddfe2 solid;
    margin: 5px 0;
  }
`

function profile () {
  return bel`
    <div class=${css.main}>
        <div class=${css.imageContainer}>
          <img src=${profileImageUrl} class=${css.profileImage}>
        </div>
        <div class=${css.textContainer}>
          <a href=${githubUrl} class=${css.username}>@${data['username']}></a>
          ${showBackground(data)}
          ${showProjects(data)}
          ${showInterests(data)}
        </div>
    </div>`
}

/* --------------------------------------------------------
                          HELPERS
  ---------------------------------------------------------- */
function showBackground (data) {
 return bel`
  <div>
    <div class=${css.background}>
      <i class="fa fa-shield" aria-hidden="true"></i>
      ${data['background'].map((el)=>bel`<span class=${css.backgroundItem}>${el + ' '}</span>`)}
    </div>
  </div>`
}

function showProjects (data) {
var len = data['projects'].length
return bel`
  <div>
    <div class=${css.projectsContainer} onclick=${event => showHideProjects(event.currentTarget, data)}>
      <div class=${css.projectsTitle}>${len} projects listed</div>
    </div>
  </div>
`
}

function showHideProjects (el, data) {
console.log(el)
if (projectsExpanded === true) {
  var list = document.querySelector('#list')
  el.removeChild(list)
  projectsExpanded = false
} else {
  var projectList = bel`
    <div class=${css.projectList} id='list'>
      <div class=${css.line}></div>
      ${data['projects'].map((el)=>bel`<div class=${css.projectItem}>${el + ' '}</div>`)}
      <div class=${css.line}></div>
    </div>`
  el.appendChild(projectList)
  projectsExpanded = true
}
}

function showInterests (data) {
return bel`
  <div class=${css.interests}>
    <span class=${css.tag}>List of interests:</span>
    ${data['interests'].map((el)=>bel`<span class=${css.interestItems}>${el + ' '}</span>`)}
  </div>`
}

var html = profile()
document.body.appendChild(html)

@serapath
Copy link
Member Author

serapath commented Mar 1, 2018

@kiecoo

The code examples nina has already show how to use the component in the end ... otherwise, let me try to explain whats going on :-)

Your codepens both have module.exports = ....
So it is totally normal that nothing shows.

The whole code defines the component so that you can use it, but you do not use it yet.

So what i recommend and what you need is something like moving the line module.exports = ... to the end of the codepen ...and then basically comment it out and rather just use it :P

// .... lots of lines of code on codepen to define the component ...
// ....
// ....at some point the codepen end and now you have:

// module.exports = card

var el = card()
document.body.appendChild(el)

@kiecoo
Copy link

kiecoo commented Mar 2, 2018

@serapath @ninabreznik
thank you so much
with your help, finally I could let both of them work successfully (so happy~)


version in codepen (work successfully)
bel-card: codepen
bel-profile: codepen

@kiecoo
Copy link

kiecoo commented Mar 7, 2018

profile-card + gitterBox

@serapath @ninabreznik

1-basic layout (profile-card + gitterBox iframe)

codepen: https://codepen.io/kiecoo/pen/qxeyPv
view of photo: https://drive.google.com/open?id=149XAIXc_mopHadXZFd9Mhe3h7iuRX6d8


2-add function-of-gitter (profile-card + gitterBox iframe + function of gitter

what I got stuck

(1) build new module of gitter

(in the future using :var chatprofilecard = require('chat-profile-card'))

have problem of move the code into github & still fail after trying different ways to solve
I have tried 2 ways to let chatBox to success & both of them failed

<1.repo of makeGitterChatbox> :output is all blank**

In html:

using

makeGitterChatbox(exampleProfile)

<2. repo of try-gitter-chatBox> :output is all pink(just show background of body)

**

In html:

using

var x = makeGitterChatbox(exampleProfile)
document.body.appendChild(x)

instead of

makeGitterChatbox(exampleProfile)

(2) combine them directly

have problem of position: codepen

@serapath
Copy link
Member Author

i see.
The second approach is correct

var x = makeGitterChatbox(exampleProfile)
document.body.appendChild(x)

i am not sure why you only see pink
actually on your codepen it looks good to me.

what do you think exactly is missing?
what do you expect to be different? :-)

@kiecoo
Copy link

kiecoo commented Mar 14, 2018

<2. repo of try-gitter-chatBox> :output is all pink (just show background of body)

In html:

using

var x = makeGitterChatbox(exampleProfile)
document.body.appendChild(x)

instead of

makeGitterChatbox(exampleProfile)

(1) codepen

(1-1) layout-expected-to-be
(1-2) layout-now
(position of gitterChatBox is different) XD

(2) github problem

When I run it, I see the same problem

only see pink,but on codepen it looks good

last week I tried few ways to solve the problem of only-see-pink, and still failed.
I couldn't find the reason which cause that.
would it cause bigger problems when combing all in the future ? or it would not? (I am not sure)

@serapath
Copy link
Member Author

serapath commented Mar 14, 2018

  1. regarding the layout, i think you need to fiddle with CSS here. Obviously the resizing worked already

    • this is probably a hard one, but the following css properties might be interesting to explore:
      • container: position: relative; contained element: position: absolute
      • top/bottom/right/left: +/-50%;
      • you can search for those css properties on google to find a better description how they work :-)
  2. maybe the github problem is related to the API limit or the signup/signin?

    • you should have as many and small modules as possible :-)

So there are several ways to find the problem (= this is called "debugging")
The first one is to

  1. open the "developer tools"
  2. set break point(s) in the beginning of your app's code and reload the page
  3. then step through each line of the execution until you find the place where the app does something unexpected that causes the problem

The second one is:

  1. write a console.log('before') somewhere in the beginning of your code and
  2. write a console.log('after') somewhere later in your code where you think that code should have been executed, but judging by what you see, it has not been executed.
  3. then reload the page and check the "devtools console" and look if before and/or after has been printed.
  4. You would expect, because of the problem that exists, that only before has been printed, but not after...
  5. now you move the console.log('before') a few lines further in your code and repeat from STEP 3.

...at some point you might reach the point in your code where - against your expectations - the console.log('before') does not get printed anymore...

This is where you could console.log some local variables or conditions and reload the page to get a better picture about why the code is not behaving the way you would want it to behave :-)

@kiecoo
Copy link

kiecoo commented Mar 15, 2018

so good. the positionProblem has solved by the way you recommended


2-profile-card + gitterBox iframe +function of gitter

(1) build new module of gitter : problem of all-pink
(2) combine them directly : problem of position

about (2) combine them directly : solved successfully

.iframe {
    position: fixed;
    top: -38px;
    left: 75px;
    ....
    .....
}

@serapath
Copy link
Member Author

You might need to use relative positions using percentages % rather than fixed ones like px, because when somebody has a different screen resolution or resizes the window, it might not work out anymore.
... but maybe it does in case your container element also has a fixed size.

@serapath
Copy link
Member Author

for me it looks a bit small, because my screen has a big resolution and it also seems to be slightly wrong positioned.
http://i.imgur.com/Phy7sDU.png

@kiecoo
Copy link

kiecoo commented Mar 16, 2018

yesterday I tried using percentages % at the beginning but I met problems when screen changing
screen-changing-problems

in order to solve screen-changing-problems , I google the solution to change using px . but now it seems cause another problem you told now. Maybe I would need to search another solution which could solve both of these problems

@serapath
Copy link
Member Author

yes it's actually not that easy. These are the problems that also Nina had.

The main feature that is supposed to solve this in the future goes under the name: container queries or element queries ...for now it's always a little bit about hacks and often it's possible to find some ways to make it work, but sometimes the only solution is to use JavaScript to listen to changes to the current window size and whenever it's resized to check again the current window size and measure all the widths and heights and positions and set custom styling that is calculated.

Using JavaScript to make sure the styling works and is responsive is usually overkill and should be avoided, but sometimes it's the only solution.


As far as i remember i once tried to fix the styling for a resized chat on an older version of our e-learning app and you could try to use the "developer tools" to check the css of the chat iframe and the container to figure out if you can copy some tricks from there.

The link is: http://app.wizardamigos.com/

@kiecoo
Copy link

kiecoo commented Mar 16, 2018

@serapath @ninabreznik
could you have a look below links to help me check if the-solution-I-tried is suitable for the problem we met?

2-profile-card + gitterBox iframe +function of gitter

(1) build new module of gitter : problem of all-pink
(2) combine them directly : problem of position

2-(2)____ solution_v2【positionQ-gitterChatBox 】


I finally tried this solution that I didn't see the position problem happening when I tested on window & Mac. I also tested on Chrome & Safari and on resizing-the-screen situation.

could you help to test this solution if it also work successfully on your computer? :-)

@serapath
Copy link
Member Author

yes it works.
just - i find it to be very small in size, so it's hard to read.
...the front side is nice to read, but the back side with the chat - but also the "lorem ipsum" text is only readable with a magnifier. ...but otherwise the chat is centered and works for me. very sweet :-)

@kiecoo
Copy link

kiecoo commented Mar 18, 2018

I tried to brainstorm some ways to solve, but there are only 2 ideas I could think about . I am not sure if they are suitable to solve ? if Alex have better ways to suggest me , just feel free to let me know & I could try


<idea 1> enlarge the whole size of card? (twice bigger or other size better?)
for example:
1. now: width: 300px; height: 280px;
2. one and a half times as big as original size ? width: 450px; height: 420px;
3 other size.......

<idea 2>
keep the card size now, move the "lorem ipsum" text into the front side in order to let gitterbox bigger

or other better ideas.........

@serapath
Copy link
Member Author

i don't know yet. Generally it works i guess.
So maybe the best would be to leave it like it is and try to put it all together to have the /profiles page working and then we can post it on the chat and on the facebook group and ask for feedback and recommendations from others for how to improve it :-)

Switching out one profile card component for another is good, but i would recommend to first get a working version - the current card looks ok to me :-)

@kiecoo
Copy link

kiecoo commented Mar 18, 2018

leave it and try to put it all together & ask for feedback then see how to improve it

I think your suggestion is better :-)


Switching out one profile card component for another

does Switching-out mean that we make this-single-card into a module to let it to be a component? When we need show 10 or 20 people's profile in a page , we would use the module of this-single-card

(i am afraid that i misread what you said. if it is the same what you suggested , I would do it first)

@serapath
Copy link
Member Author

Not sure I understand your last question, but when you have var el = page(data)

you can write

var el = page(data)
fx_done(el)

regarding errors, it's common practice to pass some kind of error as the first argument of callbacks so you know if everything went write

For example, it would be better to write you code like this:

// not like this:
profile(done)
function done (el) { document.body.appendChild(el) }

// but rather like this:
profile(done)
function done (error, el) {
  if (error) return console.error(error) // or `document.body.innerHTML = `<h1>${error}</h1>`
  document.body.appendChild(el)
}

That way, you can write your code in function profile (done) { ... } so that when everything works out (e.g. you get the right data from github), you in the end call done(null, el), but if something goes wrong, you can call done("github api limit reached")

Does that make sense?

@kiecoo
Copy link

kiecoo commented May 16, 2018

@serapath

I am still a little bit confused (but I don't know where the all places made me confused are), so the first thing I did is following what you said to edit code first (not debug yet)
could you help you to check if what I editted is right? (I think somewhere I editted was wrong where I mistakenly understand what you said )

After you checked:
before next-debugging and moving forward to next step, I think I need to spend time to see the whole code of this step to try to understand all which String together from part of code.


I am trying to find which part of concept I don't understand well to make me confused
But what I could find where I confused are only 2 places.

Q1:

after using "funciton loadData" instead of L210 .( remove L210 means " we also affect 'next')
I know I need to move 'next' to somewhere inside of function LoadData, but I don't know where to put 'next

Q2:

you can write
var el = page(data)
fx_done(el)

does it mean ‘move ‘fx_done(el)
’from L272 to L203 ?

@kiecoo
Copy link

kiecoo commented May 17, 2018

@serapath

haha,thank you so much.
After studying 3rd time of your explanation with using devtools to try the code line by line how it affect the output ,it let me understand the following code (so good~)

 
profile(done)
function done (error, el) {
  if (error) return console.error(error) // or `document.body.innerHTML = `<h1>${error}</h1>`
  document.body.appendChild(el)
}

That way, you can write your code in function profile (done) { ... } so that when everything works out (e.g. you get the right data from github), you in the end call done(null, el), but if something goes wrong, you can call done("github api limit reached")


the questions I had now just are the Q1. Q2 in previous comment. thank you :-)

@serapath
Copy link
Member Author

kiecoo/de3-2@7f5d813#diff-eacf331f0ffc35d4b482f1d15a887d3bR203

  • you don't need lines 205 and 205 this should be happening in line 292

Q2

does it mean ‘move ‘fx_done(el)

yes, you have it in line 202 and 203 :-)

Q1
I'm not sure i understand what you ask.
What i would recommend you is to try to fix identation of your code.

  • never more than one empty line between code
  • code in the same scope has the same amount of spaces in front
  • every level of indentation is 2 spaces

This makes it all a lot easier to read.

Below follows your code with the right formatting

@serapath
Copy link
Member Author

serapath commented May 17, 2018

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://unpkg.com/npm-require"></script>
  </head>
  <body>
    <script>
      var bel = require('bel')
      var csjs = require('csjs-inject')

      /******************************************************************************
        THEME
      ******************************************************************************/
      var fonts = [
        'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',
        'https://fonts.googleapis.com/css?family=Ubuntu'
      ]
      var fontAwesome = bel`<link href=${fonts[0]} rel="stylesheet" type='text/css'>`
      var fontUbuntu  = bel`<link href=${fonts[1]} rel="stylesheet">`
      var font_ubuntu = 'Ubuntu, sans-serif'
      document.head.appendChild(fontAwesome)
      document.head.appendChild(fontUbuntu)

      var backgroundWhite = '#f6f6f6'
      var fontGrey        = '#606060'
      var borderGrey      = '#fafafa'
      var green           = '#2a9c6d'
      var red             = '#d41304'

      var css = csjs`
      .card {
        display: flex;
        align-items: center;
        justify-content: center;
        font-family: ${font_ubuntu};
        background-color: ${backgroundWhite};
        border: 2px solid ${borderGrey};
        box-shadow: 0 1px 2px rgba(34,25,25,0.4);
        width: 300px;
        height: 280px;
        padding: 1em;
      }
      .cardContainer,
      .cardContainer_hover {
        display: flex;
        align-items: center;
        flex-direction: column;
        -webkit-animation: transitionIn 0.3s ease-in;
        -moz-animation: transitionIn 0.3s ease-in;
        -o-animation: transitionIn 0.3s ease-in;
        animation: transitionIn 0.3s ease-in;
      }
      .profileImage {
        border-radius: 50%;
        width: 10em;
        height: 10em;
      }
      .cardTitle {
        margin-top: 1em;
        font-weight: bold;
        font-size: 2em;
      }
      .cardSubtitle {
        margin-top: .3em;
        font-size: 1.3em;
        color: ${green};
      }
      .cardText {
        font-size: .2em;
        line-height: 110%;
        text-weight: bold;
        border: 2px dotted ${green};
        border-radius: 5px;
        padding: .5em;
        text-align: center;
      }
      .btn {
        margin: 25px;
        width: 80%;
        min-width: 184px;
        max-width: 184px;
        height: 42px;
        background-color: #fcfcfc;
        border-radius: 2px;
        box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .2);
        cursor: pointer;
        cursor: hand;
        align-self: center;
        user-select: none;
        transition: all 400ms ease 0s;
        display: flex;
      }
      .iconwrapper {
        position: absolute;
        margin-top: 1px;
        margin-left: 1px;
        width: 40px;
        height: 40px;
        border-radius: 2px;
        user-select: none
      }
      .btntext {
        margin: 11px 14px 40px 40px;
        color: #757575;
        font-size: 14px;
        letter-spacing: .2px;
        font-family: Roboto;
        user-select: none
      }
      .btn:active {
        box-shadow: 0 1px 1px #757575;
        background: #F8F8F8;
        color: #fff;
        user-select: none
      }
      .cardSocial {
        color: black;
        padding: .3em ;
        transform:scale(2);
      }
      .cardSocial a {
        text-decoration: none;
      }
      .cardSocial_fontawesome {
        color: ${green};
        font-size: 2em;
        padding: .3em;
      }
      .cardSocial_fontawesome:hover {
        opacity: 0.9;
      }
      .cardGitterChat {
        height: 170px;
        width: 113px;
        overflow: hidden;
        margin-top: 1em;
        padding: .1px .1px;
        text-decoration: none;
        border-radius: .1px;
        background-color: ${green};
      }
      .cardGitterChat:hover {
        opacity: 0.9;
        cursor: pointer;
      }
      @keyframes transitionIn {
        0% {opacity: 0.1}
        100% {opacity: 1}
      }
      .iframe {
        position:relative;
        top: -39%;
        left: -40%;
         height: 300px;
        width: 200px;
        transform: scale(0.55);
        margin-top: .1px;
        text-align:center;
        color:${green};
        background:${green};
        height: 300px;
        width: 200px;
        transform: scale(0.55);
        margin:.1px ;
        padding:.1px;
      }
      `
      var getGithubData    = require('./index.js')
      var makeSignupButton = require('./githubsignin.js')


      /******************************************************************************
        SIGNUP BUTTON
      ******************************************************************************/
      var GITHUB_CLIENT_ID = '62483029222d02636782'
      var button = makeSignupButton(GITHUB_CLIENT_ID)
      document.body.appendChild(button)

      /******************************************************************************
        SIGNUP BUTTON
      ******************************************************************************/
      function profile (fx_done) {
        var code = location.search.split('=')[1]
        console.log(code)
        if (code) {
          loadCode (error, code)
        } else {
          // show page with github signin button
        }

        // this is triggered when the user clicks the button
        function loadCode (error, code) {
          if (error) return console.error(error)
          console.log(`github responded with "${code}", so let's fetch a lot of data :-)`)
          getGithubData(code, loadData)
        }
        function loadData (error, data) {
          if (error) return console.error(error)
          console.log(`github sent us lots of data, so lets use it to build the page :-)`)

          // I don't know how to deal with these 4 lines & function next(L212)
          var el = page(data)
          fx_done(el)
          document.body.innerHTML = '' // to clear and remove the signup button
          document.body.appendChild(el)
        }
        // getGithubData (next)
        /*
          Q1: after using "funciton loadData" instead of this line.
              (so we also affect 'next')
              I know I need to move 'next' to somewhere inside of
              function LoadData, but I don't know where to put 'next
        */
        function next (x_data) {
          // var element1 = bel`<div>${data.map(x => bel`<p>${x.user}</p>`)}</div>`
          // done(element1)
          x_data.forEach(putEl)
          function putEl(y_data) {
            var username = y_data.username
            var name     = y_data.username
            var cardText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru '
            var imageUrl = 'https://nomadlist.com/assets/img/cities/phuket-thailand-500px.jpg'
            var city     = 'Berlin'
            var twitter  = `https://twitter.com/${username}`
            var github   = `https://github.com/${username}`
            var codepen  = `https://codepen.io/${username}`
            function makeLinkUrl (username) {
              return  `https://gitter.im/${username}/~embed`
            }
            var cardContainer = bel`
              <div class=${css.cardContainer}>
                <img src=${imageUrl} class=${css.profileImage}>
                <div class=${css.cardTitle}>${name}</div>
                <div class=${css.cardSubtitle}>@${username}</div>
              </div>`
            var cardContainer_hover = bel`
              <div class=${css.cardContainer_hover}>
                <div class=${css.cardGitterChat} ><iframe class=${css.iframe} src=${ makeLinkUrl (username)}></iframe></div>
                <div class=${css.cardSocial}>
                  <a href=${twitter} target='_blank'>
                    <i class="${css.cardSocial_fontawesome} fa fa-twitter" aria-hidden="true"></i>
                  </a>
                  <a href=${github} target='_blank'>
                    <i class="${css.cardSocial_fontawesome} fa fa-github" aria-hidden="true"></i>
                  </a>
                  <a href=${codepen} target='_blank'>
                    <i class="${css.cardSocial_fontawesome} fa fa-codepen" aria-hidden="true"></i>
                  </a>
                </div>
                <div class=${css.cardText}>${cardText}</div>
              </div>`
            var el = bel`
              <div class=${css.card} onmouseenter=${hoverCard} onmouseleave=${unhoverCard}>
                ${cardContainer}
              </div>`
            /**************************************************************************
              HELPERS
            **************************************************************************/
            function hoverCard (event) {
              el.appendChild(cardContainer_hover)
              el.removeChild(cardContainer)
            }
            function unhoverCard (event) {
              el.removeChild(cardContainer_hover)
              el.appendChild(cardContainer)
            }
            //  fx_done(el)
          }
        }
      }

      profile(done)

      // function done (el) { document.body.appendChild(el) }
      function done (error, el) {
        if (error) return console.error(error) // or `document.body.innerHTML = `<h1>${error}</h1>`
        document.body.appendChild(el)
      }

    </script>
  </body>
</html>

@serapath
Copy link
Member Author

  1. I recommend to always use 2 spaces to indent your whole file the way it is indented above
  2. you might wanna try to have line length of a maximum of 80 characters per line if possible
  3. it can help to seperate code sections with a comment that looks like
/**************************************************************************************
  TITLE
    optional is some description
    the **** characters surrounding this comment should be
    also max 80 chars long :-)

    oh and code and basically anything should at most be seperated
    by one empty line and not multiple ones :-)
**************************************************************************************/

@serapath
Copy link
Member Author

Could you try to write your Q2 again?

@kiecoo
Copy link

kiecoo commented May 18, 2018

about Q2

Could you try to write your Q2 again?

Q2
does it mean ‘move ‘fx_done(el)
yes, you have it in line 202 and 203 :-)

I think the answer you replied me is good.
It had solved my Q2

more about Q1

after using getGithubData(code, loadData)instead//getGithubData (next).( remove getGithubData (next) means " we also affect 'next')
I know I need to move 'next' to somewhere inside of function LoadData, but I don't know where to put 'next

could you help me to see if what-I-editted-in-line-284 is right?

@kiecoo
Copy link

kiecoo commented May 18, 2018

@serapath

new question Q3---about line 190

  • when I run code & stop at line 187
    there is a signup-button existing at the output

  • so the question is :
    in line 190, would I still need to write code to let a signup-button showing up again?
    if it needs to write again, the following code is correct or not?

// putting the following code in line 190 if it needs to write again
 document.body.innerHTML = ''
 document.body.appendChild(button)

Q4
it shows error: error is not defined

when running the code, it got stuck on 'error is not defined'
I don't have the method to deal with


if you need repo-link :still in the origin one

@serapath
Copy link
Member Author

Q1

you know all the answers already, because if you can imagine what needs to be done.

  1. you get all data for users from github
  2. you create card elements for each user
  3. you put them into the visible web page

...so that means' loadData(...) is next(...) ...because in next you process all data and make all the user cards. You only need either loadData(...) or next(...)... you can delete one of them and rename the other how you like it most.

Q3

haha :-) very close ...you just have to move the button code to line 190
So before you show anything in the page ...basically the first thing you do when the page loads is: check for the code

Q4

Then just don't use the error param and rename it to loadCode(code) and later function loadCode (code) { ... } ....always try to write as little code as possible. The art in programming is to write as little code as possible -because the less code you write, the less memory it uses, the less computation it needs, the less others or your future self have to read, the less bugs it can have :-)

less is more in programming :-) only add something when you really really need it and you know exactly why you need it.

otherwise:

  • there is a convention, that when you do something and it can either succeed or fail - like you request data from github, but maybe you got the response, that the server is currently not available, then you might continue differently (e.g. show the error message), instead of (e.g. show the result).

So when you write functions or use callbacks :-) ...there is a convention, that if it is possible that a callback might either receive the wanted result or an error, the error should be the first argument

getData("http://github.com/kiecoo", function callback (error, data) {
  // the `callback` function here needs to react to the `data` or the `error` that is returned from
  // `getData(...)` call
  // so in this case, either there was an error during `getData(....)` or it succeeded.
})

...but if you don't have this error problem (like above), then just remove it :-)

@kiecoo
Copy link

kiecoo commented May 19, 2018

@serapath

  • I am not sure if what you wrote is similar like this

  • detail

(1)

Then just don't use the error param and rename it to loadCode(code) and later function loadCode (code) { ... }

so line188 & 194 , I removed the error

(2)

getData("http://github.com/kiecoo", function callback (error, data) {
  // the `callback` function here needs to react to the `data` or the `error` that is returned from
  // `getData(...)` call
  // so in this case, either there was an error during `getData(....)` or it succeeded.
})

so line197 & 199 , I didn't remove the error
(because I followed your example &convert it into the getGithubData(code, function loadData (error, data) {......}), then separate into line197 & 199)


  • could you help me to see if I got the correct way in (1)(2) or I mistakenly understand something?

@serapath
Copy link
Member Author

yes, it is similar to this :-) exactly.


+1

+1

yes, exactly :-)

@kiecoo
Copy link

kiecoo commented May 21, 2018

@serapath

  • [aim]
    try to solve: the output didn't show the card as what-it-supposed-to-be

  • [bug]

  • [method to try ]

    • in function getGithubData (fy_next) {...}
      I want fy_next= loadData instead fy_next=code='3014b83781d86ca7d0de'

    I guess I need edit about this code: function getGithubData ('???',fy_next) {....}
    (but I don't what is supposed to put in the place of '???' )

    • or should I use getGithubData(loadData) instead getGithubData(code, loadData)?

repo: https://github.com/kiecoo/de4

@serapath
Copy link
Member Author

right...

so your code is very close to how it is supposed to be (maybe indentation in your example is still fucked up, but yeah .....it works) :P
...so...

function next (x_data) {
          // var element1 = bel`<div>${data.map(x => bel`<p>${x.user}</p>`)}</div>`
          // done(element1)
          x_data.forEach(putEl)
          function putEl(y_data) {
          }
}

The good thing is, that next(...) is working synchronous. Nothing that happens here is async, so you can indeed return something, so the code

          var el = next(data)  
          fx_done(el) 

is fine.


You have two choices:

  1. either you change next(...) to async and give it a callback and use it
  2. or you make function next (...) { ... } return something (e.g. the element)

@1 async

you could do:

  next(data, fx_done)
  // AND
  function next (data, done) {
    done(bel`<div>${data.map(putEl)}</div>`)
    function putEl (y_data) {
      // make card
      return card
    }
  }

OR

@2 sync

  var el = next(data)  
  fx_done(el) 
  // AND
  function next (data) {
    var el = bel`<div>${data.map(putEl)}</div>`
    function putEl (y_data) {
      // make card
      return card
    }
    return el
  }

@kiecoo
Copy link

kiecoo commented May 23, 2018

@serapath

  • what I got stuck:
    fail to combine all snippets you gave me before
  • the bug
    I found that the bug maybe on that I did something wrong in function loadData

because

@serapath
Copy link
Member Author

I'm a bit confused about lines 208, 209 and 210 ...they should not be in there.
line 207 is good enough

kiecoo/de4@92cc920#diff-eacf331f0ffc35d4b482f1d15a887d3b

@serapath
Copy link
Member Author

Also in line 202 you do not provide the done function as an argument to next ...
It is still a mixture of sync and async style.

function loadData (error, data) {
  if (error) return console.error(error)
  console.log(`github sent us lots of data, so lets use it to build the page :-)`)
  document.body.innerHTML = '' // to clear and remove the signup button
  next(data, fx_done)     
}
function next (data, done) {
  done(bel`<div>${data.map(putEl)}</div>`)
  function putEl (y_data) {
    // make card
    return card
  }
}

@serapath
Copy link
Member Author

which basically says to the next function, that after it has finished calculating all elements, ... call done which is fx_done and pass in the element containing all the cards for profiles.

The fx_done function is actually from line 284 ...so there is where it continues and appends the list of cards to the DOM (the visual area of the web browser)

@kiecoo
Copy link

kiecoo commented May 26, 2018

@serapath
I got stuck
when inputting data from get-userprofiles-from-github

@kiecoo
Copy link

kiecoo commented May 26, 2018

I think I seemed to try out a possible way to let me jump out what I got stuck on the previous comment.
so I could try more & just ignore the previous comment.
I will renew after trying further.
thank you

@kiecoo
Copy link

kiecoo commented May 26, 2018

@serapath
after I tried ,I found the output is unstable


I don't know how I could do further to let it become stable to show card

@serapath
Copy link
Member Author

haha, the error code is 403. you can google "http status 403" and you will see it is the one which has to do with request limit of 60 per hour.

i guess you only get here after getting the code from github, BUT... do you still have note about the bookmark that describes how to setup github authentication and then how to use the code to be able to not trigger that 60 requests limit per hour?

@kiecoo
Copy link

kiecoo commented May 27, 2018

@serapath
haha, I mistakenly think that after github turn the page into "Redirect URI", github already allowed us more request & already solved request limit of 60 per hour.


  • yes,I have the link of how to setup github authentication and then how to use the code to be able to not trigger that 60 requests limit per hour

  • in the link above:

2nd part 【fetch-token by using client_id & client_secret & code】

(2)using the "code" to fetch "Access Token" (what I searched is below,I am not sure if it is suitable for our project)


     var readline = require('readline');
var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var CLIENT_ID = '256637951185-p1b226vo2mfem77mbuiccj74eefj3m2v.apps.googleusercontent.com',
    CLIENT_SECRET = 'YOUR CLIENT SECRET',
    REDIRECT_URL = 'urn:ietf:wg:oauth:2.0:oob',
    SCOPE = ['https://www.googleapis.com/auth/drive',
        'https://www.googleapis.com/auth/plus.me',
    ];  
var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
var auth = new OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);
var url = auth.generateAuthUrl({scope: SCOPE});
var getAccessToken = function(code) {
    auth.getToken(code, function(err, tokens) {
        if (err) {
            console.log('Error while trying to retrieve access token', err);
            return;
        }   
        auth.credentials = tokens;
        console.log(tokens);
    }); 
};
console.log('Visit the url: ', url);
rl.question('Enter the code here:', getAccessToken);


I don't know how to convert this code into suitable code to fit in our project.
(the only thing to convert I know is put our-GITHUB_CLIENT_ID into the code above
could you help me to show more hints about it? thank you~

@serapath
Copy link
Member Author

serapath commented May 28, 2018

yes, you get a code but then all we do is logging it here https://github.com/kiecoo/de4/blob/master/index.html#L193
This was the first step :-)

Now another step was to setup the heroku app with a custom code i think.... didn't you do that too?
Do you still have notes about it and the loggin to heroku and the URL of that heroku app and where it is running online? :-)

Other than that, you can also check a previous comment of our discussion from the 24th of february
#9 (comment)

Again - i recommend to copy paste usefull code snippets from our discussion or from your code into hackmd documents and bookmark them so you can have little cheatsheets for all the topics, where one topic would be about how to setup github authentication.

Over time, when you learn more stuff, you can slowly re-structure them into folders and subfolders in your bookmarkbar that make more sense to you. So you can slowly grow you overview and understanding of programming topics :-)

@kiecoo
Copy link

kiecoo commented May 28, 2018

@serapath

about Now another step was to setup the heroku app with a custom code i think.... didn't you do that too? Do you still have notes about it and the loggin to heroku and the URL of that heroku app and where it is running online? :-)

I am not sure if the following is what exactly you mention.


yes, I had one hackmd document before (which focuses on the topic of heroku & Oauth)
but it is not all in English XD

@serapath
Copy link
Member Author

Doesn't matter if not all of your docs are in english... ppl can always use a auto-translate feature :-)


i think this one: https://get-profiles.herokuapp.com/

you have to read the README.md of the https://github.com/prose/gatekeeper repository i think. Some of the steps there are already done.

  1. you have it running on heroku
  2. you already have the code from github

.... now you need to send it to your backend which is probably the heroku one :-) ....is it?
I assume that get-profiles.heroku.com is running an instance of the gatekeeper project...You can use either window.fetch or you can var minixhr = require('minixhr') and use it send the code to your backend to get back the necessary token. I think the example on the gatekeeper README is using jQuery's ajax method, but you don't need it. fetch or minixhr will do the same with less code

you would just do somethingl like:

const minixhr = require('minixhr')

// ...
minixhr(`https://get-profiles.herokuapp.com//${code}`, function (json) {
  var data = JSON.parse(json)
  console.log(data.token)
})

@kiecoo
Copy link

kiecoo commented May 31, 2018

@serapath

yes, you get a code but then all we do is logging it here https://github.com/kiecoo/de4/blob/master/index.html#L193
This was the first step :-)

code of access token

const minixhr = require('minixhr')
// ...
minixhr(https://get-profiles.herokuapp.com//${code}, function (json) {
var data = JSON.parse(json)
console.log(data.token)
})

Q1
does it means that I put the code on previous comment in L193?


Q2
I found it would not show the console.log of L201 & L206 in the bottom of photo


repo link:https://github.com/kiecoo/de4

@serapath
Copy link
Member Author

=> Q1

looks good.
first step towards success would be to get the token from your heroku backend.
I see you put the minixhr code to call your heroku backend in line 203 but it should be in 193

=> Q2

I'm not sure what you are saying here regarding the console.log but it logs the code you got from github after signin, which is good.
Now you just have to use minixhr to call your heroku backend with that code after line 193 ...

...and ONLY when you get the data.token successfully, THEN you should continue getting data from github, so you ahve to write getGithubData(data => loadData(null, data)) in the callback of minixhr that gives you the token from your heroku backend.

@kiecoo
Copy link

kiecoo commented Jun 1, 2018

Q2

  • Q2-1
    after putting code after line 193, I found that console.log(data.token)didn't work(it says data is not defined)

  • Q2-2

write getGithubData(data => loadData(null, data)) in the callback of minixhr

could you show me more about write getGithubData(data => loadData(null, data)) in the callback of minixhr?
(is it adding something like function ABC (callback) {.....} in the following or maybe something else?)

          //access token	
          minixhr(`https://get-profiles.herokuapp.com//${code}`, function (json) {
            var data = JSON.parse(json)
            console.log(data.token)

            // add  something like :   function ABC (callback) {.....}

          })

@serapath
Copy link
Member Author

serapath commented Jun 1, 2018

=> Q2-1

maybe line 196 has should include /${code} and not //${code ...but not sure if that alone solves the problem. But also i see the debugger is stopping in line 193 in that screenshot ... at that point it's normal that data.token is not defined yet. Rather the debugger needs to stop in line 198

=> @2-2

no not exactly, but rather replace // add something like : function ABC (callback) {.....} with something like getGithubData(data.token, data => loadData(null, data))
..so you only start calling it after you already have the token.
You also have to pass the token to getGithubData(...) and then change the implementation to make use of that token when calling githubs api, so that you get the increased request limits of 5000 instead of 60 :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants