Skip to content

Commit

Permalink
Initial setup
Browse files Browse the repository at this point in the history
Renders results

Adds styling

Adds styles

Adds toast

Finished app

Finished without useEffects

Show correct number of new unfollowers/followers

Finished app

Adds readme and workflow

Fixes deployment workflow
  • Loading branch information
agusmoles committed Oct 26, 2023
1 parent 6ab4476 commit ecb1e3d
Show file tree
Hide file tree
Showing 22 changed files with 4,376 additions and 0 deletions.
44 changes: 44 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"env": {
"node": true,
"browser": true,
"es6": true
},
"settings": {
"react": {
"version": "detect"
}
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"plugin:react-hooks/recommended",
"plugin:react/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2021,
"sourceType": "module"
},
"plugins": ["react", "prettier", "@typescript-eslint"],
"rules": {
"react/prop-types": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
],
"react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
"react-hooks/exhaustive-deps": "error" // Checks effect dependencies
},
"ignorePatterns": ["**/node_modules/*"]
}
48 changes: 48 additions & 0 deletions .github/workflows/build_and_deploy_pages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Build and update pages
on:
push:
branches:
- main
workflow_dispatch:

concurrency:
group: "pages"
cancel-in-progress: false

permissions:
contents: read
pages: write
id-token: write

jobs:
update_and_deploy:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3

- name: Use node
uses: actions/setup-node@v3
with:
node-version-file: ".nvmrc"
cache: "npm"

- name: Install dependencies
run: npm install

- name: Update pages
run: |
npm run build
- name: Setup Pages
uses: actions/configure-pages@v3

- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: "./public"

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/node_modules
/.pnp
.pnp.js
.vscode/*
.DS_Store
.env*
.env.local
.env.development.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.sass-cache/
.eslintcache
dist
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build
coverage
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": false,
"printWidth": 80,
"arrowParens": "always",
"endOfLine": "lf"
}
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Instagram Unfollowers

A nifty tool that lets you see who doesn't follow you back on Instagram.
Browser-based and requires no downloads or installations!

## **WARNING**

This version utilizes the Instagram API for better performance.

## Usage

### Steps:

1. Copy the following code from this url. (This has been moved to this site, because the repository was taking too long to load with so many characters.The web site only shows the compiled and minified code. )

###

2. Press the COPY button to copy the code.

<img src="./assets/copy_code.png" alt="Initial screen" />

3. Once you have copied the code, you can close this page and go to the [instagram](https://www.instagram.com/) website
4. Log in into your account and open the developer console or (Ctrl+Shift+J(Windows) || ⌘+⌥+I (Mac os)), paste the code and press enter.

5. You will be met with the following interface:

<img src="./assets/initial.png" alt="Initial screen" />

6. Click "SCAN" to start scanning for users who do not follow you back.
7. Once it finishes printing the users, you will be met with the following screen which will show you the results:

<img src="./assets/results.png" alt="Results screen" />

8. If you wish to un-follow any of these users, you can select 1 or more of them by clicking each user image.


## DEV

When introducing new changes to `main.tsx`, make sure to run the "build" command in-order to automatically format, compress, and convert your code. (In the future will be automatic).

## Legal

**Disclaimer:** This is not affiliated, associated, authorized, endorsed by, or in any way officially connected with Instagram.

Use it at your own risk!.
Binary file added assets/copy_code.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/initial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/results.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"scripts": {
"webpack-build": "webpack --mode production",
"update-readme": "node scripts/update-index.js public/index.html dist/index.js",
"build": "yarn webpack-build && yarn update-readme"
},
"babel": {
"plugins": [
"@babel/plugin-transform-react-jsx"
]
},
"devDependencies": {
"@babel/cli": "7.23.0",
"@babel/core": "7.23.2",
"@babel/plugin-transform-react-jsx": "7.22.15",
"@typescript-eslint/eslint-plugin": "6.8.0",
"@typescript-eslint/parser": "6.8.0",
"css-loader": "6.8.1",
"eslint": "8.52.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-prettier": "5.0.1",
"eslint-plugin-react": "7.33.2",
"eslint-plugin-react-hooks": "4.6.0",
"prettier": "3.0.3",
"style-loader": "3.3.3",
"ts-loader": "9.5.0",
"typescript": "5.2.2",
"webpack": "5.89.0",
"webpack-cli": "5.1.4"
},
"dependencies": {
"preact": "10.18.1",
"react-toastify": "^9.1.3"
}
}
77 changes: 77 additions & 0 deletions public/index.html

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions scripts/update-index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require("fs");

const indexPath = process.argv[2];
const minifiedCodePath = process.argv[3];

const CODE_BLOCK_START = 'const instagramScript = "';
const CODE_BLOCK_END = '"; //__END_OF_SCRIPT__';

const replaceRange = (s, start, end, substitute) => {
return s.substring(0, start) + substitute + s.substring(end);
};

const indexData = fs.readFileSync(indexPath, { encoding: "utf8", flag: "r" });
let minifiedCode = fs.readFileSync(minifiedCodePath, {
encoding: "utf8",
flag: "r",
});

const replaceStartIndex =
indexData.indexOf(CODE_BLOCK_START) + CODE_BLOCK_START.length;
const replaceEndIndex = indexData.lastIndexOf(CODE_BLOCK_END);
minifiedCode = minifiedCode.replace(/"/g, '\\"');
minifiedCode = minifiedCode.replace(/\\n/g, "");

const parsedReadme = replaceRange(
indexData,
replaceStartIndex,
replaceEndIndex,
minifiedCode
);
fs.writeFileSync(indexPath, parsedReadme);
28 changes: 28 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ScanningFilter, State } from "./model/app";

export const INSTAGRAM_HOSTNAME = "www.instagram.com";

export const INITIAL_SCANNING_STATE: State = {
status: "scanning",
searchTerm: "",
percentage: 0,
results: [],
selectedResults: [],
filters: ["nonFollowers"],
};

export const FILTERS: ScanningFilter[] = [
"followers",
"nonFollowers",
"newNonFollowers",
"verified",
"private",
];

export const FILTERS_NAMES: Record<ScanningFilter, string> = {
followers: "Show Followers",
newNonFollowers: "Show New Non Followers",
nonFollowers: "Show Non Followers",
verified: "Show Verified",
private: "Show Private",
};
26 changes: 26 additions & 0 deletions src/hooks/useLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useState } from "react";

export const useLocalStorage = <T>(key: string, initialValue: T) => {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});

const setValue = (value: T | ((val: T) => T)) => {
try {
const valueToStore =
value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(error);
}
};

return [storedValue, setValue] as const;
};
Loading

0 comments on commit ecb1e3d

Please sign in to comment.