{"id":16434016,"url":"https://github.com/brodanoel/devseverywhere","last_synced_at":"2025-07-15T10:36:26.946Z","repository":{"id":69838517,"uuid":"90202563","full_name":"BrodaNoel/devseverywhere","owner":"BrodaNoel","description":"Just something for fun and explore new yerbas.","archived":false,"fork":false,"pushed_at":"2017-08-20T18:24:43.000Z","size":270,"stargazers_count":6,"open_issues_count":10,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T18:58:17.120Z","etag":null,"topics":["axios","es6","firebase","firebase-auth","firebase-hosting","google-maps","jest","jest-tests","jsx","react","react-redux","reactjs","redux","twitter-api","webpack"],"latest_commit_sha":null,"homepage":"https://devseverywhere.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BrodaNoel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-03T23:41:01.000Z","updated_at":"2018-10-25T19:03:54.000Z","dependencies_parsed_at":"2023-06-01T01:30:16.464Z","dependency_job_id":null,"html_url":"https://github.com/BrodaNoel/devseverywhere","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BrodaNoel%2Fdevseverywhere","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BrodaNoel%2Fdevseverywhere/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BrodaNoel%2Fdevseverywhere/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BrodaNoel%2Fdevseverywhere/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BrodaNoel","download_url":"https://codeload.github.com/BrodaNoel/devseverywhere/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245078067,"owners_count":20557274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["axios","es6","firebase","firebase-auth","firebase-hosting","google-maps","jest","jest-tests","jsx","react","react-redux","reactjs","redux","twitter-api","webpack"],"created_at":"2024-10-11T08:47:54.594Z","updated_at":"2025-03-23T08:31:48.209Z","avatar_url":"https://github.com/BrodaNoel.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DevsEverywhere\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f32cb1327d9449e9bdf0e91d67c7823c)](https://www.codacy.com/app/brodanoel/devseverywhere?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=BrodaNoel/devseverywhere\u0026utm_campaign=badger)\n[![Travis-CI Badge](https://travis-ci.org/BrodaNoel/devseverywhere.svg?branch=master)](https://travis-ci.org/BrodaNoel/devseverywhere)\n\nThis is just... something for fun. You can test it in [devseverywhere.com](https://devseverywhere.com).\n\nThis project was created to understand better:\n* ES6\n* ReactJS\n  * Routing _(more info [here](https://github.com/ReactTraining/react-router/tree/master/packages/react-router-dom))_\n  * Jest\n* Redux\n  * Reselect (including custom Memoize functions) _(more info [here](http://redux.js.org/docs/recipes/ComputingDerivedData.html) and [here](https://github.com/reactjs/reselect))_\n  * Thunk _(more info [here](https://github.com/gaearon/redux-thunk))_\n* Flow\n  * Flow-Typed\n* Axios\n* Webpack\n* Travis-CI\n* GoogleMapsAPI\n* TwitterAPI\n* Firebase Functions\n* Firebase Hosting\n* Firebase Auth\n* Victory Graphs\n* and more.\n\nIf you need something, you know what you have to do.\n\n# Collaborating\n* Fork\n* Clone\n* Add `dev.devseverywhere.com` in your `host` file (pointing to 127.0.0.1)\n* `nvm use` (or install the proper Node version shown in .nvmrc file)\n* `npm run start`\n* Happy coding!\n\n\u003e Note: You'll find more information in `EnvironmentDocumentation.md` file.\n\n# Implementing\n\n## The frontend\nIf you want to implement this site with your own configurations, cards, ApiKeys, etc, just edit the `src/config/index.jsx` file.\nThere you have most of the implementation configs.\n\n## The backend\nFor each `getTweets` call, your backend should return this object.\nCheck the Express implementation to understand better how it works.\n```js\n{\n  tweets, // Array of tweets\n  isDone: \u003cBoolean\u003e, // if isDone is true, it's because there are no more tweets\n  metadata: {\n    min: \u003cString\u003e, // String, because this is a int64, and JavaScript doesn't support it\n  },\n  q, // Optional. This is the query you received has a parameter. Useful to debugging\n  params // Optional. These are the parameters you received. Useful to debugging\n}\n```\n\nThis is an example of how it should be implemented using Express:\n```js\nconst Twitter = require('twitter');\n\nvar config = {\n    connector: {\n        consumer_key: 'your-tweeter-key',\n        consumer_secret: 'your-tweeter-secret',\n        access_token_key: null,\n        access_token_secret: null\n    },\n    postsPerCall: 100\n};\n\napp.post('/getTweets', (req, res) =\u003e {\n  try {\n    config.connector.access_token_key = req.body.key;\n    config.connector.access_token_secret = req.body.secret;\n    twitterCollector = new Twitter(config.connector);\n\n    utils.searchTweets(\n      req.query.q,\n      {\n        max: req.query.max,\n        count: req.query.count || config.tweetsPerCall\n      }\n    )\n    .then(data =\u003e {\n      res.send(data);\n    })\n    .catch(error =\u003e {\n      res.status(503).send({\n        error,\n        req: {\n          query: req.query,\n          body: req.body\n        }\n      });\n    });\n\n  } catch (e) {\n    res.status(503).send({\n      error: e.name + ': ' + e.message,\n      req: {\n        query: req.query,\n        body: req.body\n      }\n    });\n  }\n});\n\nconst utils = {\n  searchTweets: function searchTweets(q, params) {\n    return new Promise(function(done, fail) {\n      twitterCollector.get(\n        'search/tweets',\n        {\n          q: q,\n          count: params.count,\n          max_id: params.max === null ? null : num(params.max).toString()\n        },\n        function(error, tweets, response) {\n          if (error) {\n            fail({\n              error\n            });\n            return;\n          }\n\n          var responseMin = null;\n\n          if (tweets.statuses.length \u003e 0) {\n            responseMin = tweets.statuses[0].id_str;\n\n            tweets.statuses.forEach(t =\u003e {\n              // t.id_str \u003c responseMin\n              if (num(t.id_str).cmp(num(responseMin)) === -1) {\n                responseMin = t.id_str;\n              }\n            });\n          }\n\n          // This is just to avoid returning the WHOLE Tweet object, and return only\n          // what we need in the frontend.\n          tweets.statuses = tweets.statuses.map(function(x) {\n            return {\n              coordinates: x.coordinates,\n              created_at: x.created_at,\n              place: x.place,\n              favorite_count: x.favorite_count,\n              retweet_count: x.retweet_count,\n              user: {\n                verified: x.user.verified,\n                followers_count: x.user.followers_count,\n                friends_count: x.user.friends_count\n              }\n            };\n          });\n\n          done({\n            tweets,\n            isDone: (params.count - tweets.statuses.length) \u003e 0,\n            metadata: {\n              min: responseMin,\n            },\n            q,\n            params\n          });\n        }\n      );\n    });\n  }\n};\n```\n\n# Pending things\nCheck the [issues tab](https://github.com/BrodaNoel/devseverywhere/issues) to see what's coming.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrodanoel%2Fdevseverywhere","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrodanoel%2Fdevseverywhere","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrodanoel%2Fdevseverywhere/lists"}