Skip to content

Commit

Permalink
added: autoskip support
Browse files Browse the repository at this point in the history
  • Loading branch information
emirkabal committed Apr 17, 2024
1 parent 47dabef commit 25649ae
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Better Instagram Videos is a browser extension available on the Chrome Web Store
- Playback/seek control
- Volume control (remembered)
- Downloadable video
- Autoskip support
- Supports all videos on the Instagram except stories section

## Usage
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "better-instagram-videos",
"description": "Easily control the playback and volume of any Instagram videos.",
"version": "1.0.5",
"version": "1.0.6",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
33 changes: 33 additions & 0 deletions src/content-script/components/Buttons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import "./Controller/style.css"
import { useEffect, useState } from "react"

export default function Buttons() {
const id = Math.random().toString(36).substring(7)
const [autoskip, setAutoskip] = useState(false)

useEffect(() => {
const autoskip = localStorage.getItem("bigv-autoskip")
if (autoskip) setAutoskip(autoskip === "true")
}, [])

useEffect(() => {
localStorage.setItem("bigv-autoskip", autoskip.toString())
}, [autoskip])

return (
<>
<div className="bigv-buttons">
<label htmlFor={id}>
<input
id={id}
type="checkbox"
checked={autoskip}
onChange={() => setAutoskip(!autoskip)}
/>
<span className="bigv-slider"></span>
Autoskip
</label>
</div>
</>
)
}
11 changes: 11 additions & 0 deletions src/content-script/components/Controller/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ export default function Controller({ video, igData }: Props) {
videoRef.current.addEventListener("play", () => {
updateMuted()
})

videoRef.current.addEventListener("ended", () => {
const autoSkip = localStorage.getItem("bigv-autoskip")
if (
autoSkip === "true" &&
document.location.pathname.startsWith("/reels")
) {
const snap = document.querySelector('[role="main"]>:last-child')
if (snap) snap.scrollBy(0, 1000)
}
})
}, [])

useEffect(() => {
Expand Down
62 changes: 62 additions & 0 deletions src/content-script/components/Controller/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,65 @@
*:focus-visible {
outline: none !important;
}

.bigv-buttons {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
margin-bottom: 36px;
}

.bigv-buttons label {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
line-height: 2;
user-select: none;
cursor: pointer;
scale: 0.72;
}

.bigv-buttons label input {
opacity: 0;
width: 0;
height: 0;
}

.bigv-buttons label .bigv-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
border-radius: 34px;
}

.bigv-buttons label .bigv-slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: white;
border-radius: 50%;
}

.bigv-buttons label input:checked + .bigv-slider {
background-color: #2196f3;
}

.bigv-buttons label input:focus + .bigv-slider {
box-shadow: 0 0 1px #2196f3;
}

.bigv-buttons label input:checked + .bigv-slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
18 changes: 18 additions & 0 deletions src/content-script/modules/IGReels.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { createRoot } from "react-dom/client"
import IntervalInjector, { IntervalInjectorOptions } from "./IntervalInjector"
import Buttons from "../components/Buttons"

export default class IGReels extends IntervalInjector {
constructor(options?: IntervalInjectorOptions) {
Expand All @@ -10,4 +12,20 @@ export default class IGReels extends IntervalInjector {
svg.parentElement?.remove()
})
}

public injected(): void {
if (!this.lastInjected) return

const container =
this.lastInjected[1]?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement?.querySelector(
"&>:last-child"
)
if (!container) return

const buttons = document.createElement("div")
buttons.setAttribute("bigv-inject", "")
container.insertAdjacentElement("afterbegin", buttons)

createRoot(buttons).render(<Buttons />)
}
}
12 changes: 8 additions & 4 deletions src/content-script/modules/Injector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ export default class Injector {
*/
public wayToInject() {}

get lastInjected() {
return this.injectedList[this.injectedList.length - 1]
}

private clear() {
if (
this.injectedList.length > this.MIN_REMOVE_COUNT &&
Expand Down Expand Up @@ -126,17 +130,17 @@ export default class Injector {
!video ||
!video?.parentElement ||
!video?.src ||
video?.hasAttribute("better-ig-injected")
video?.hasAttribute("bigv-injected")
)
return

this.beforeInject()
this.clear()

video.setAttribute("better-ig-injected", "")
video.setAttribute("bigv-injected", "")

const controller = document.createElement("div")
controller.setAttribute("better-ig-inject", "")
controller.setAttribute("bigv-inject", "")

video.parentElement.style.setProperty("position", "relative")
video.parentElement.appendChild(controller)
Expand All @@ -160,6 +164,6 @@ export default class Injector {
}

public isInjected(video: HTMLVideoElement) {
return video.hasAttribute("better-ig-injected")
return video.hasAttribute("bigv-injected")
}
}
4 changes: 2 additions & 2 deletions src/content-script/modules/IntervalInjector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ export default class IntervalInjector extends Injector {
const video = videos[i]
if (
this.isInjected(video as HTMLVideoElement) ||
video.hasAttribute("better-ig-attached-listeners")
video.hasAttribute("bigv-attached-listeners")
)
continue
video.setAttribute("better-ig-attached-listeners", "")
video.setAttribute("bigv-attached-listeners", "")
;["play", "timeupdate", "playing"].forEach((event) => {
video.addEventListener(event, () => {
this.inject(video as HTMLVideoElement, video.parentElement!)
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "__MSG_appName__",
"description": "__MSG_appDescription__",
"default_locale": "en",
"version": "1.0.5",
"version": "1.0.6",
"action": {},
"icons": {
"16": "icons/logo16.png",
Expand Down

0 comments on commit 25649ae

Please sign in to comment.