Skip to content

Commit

Permalink
Release/1.0.1 (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
mstephen19 authored Jul 27, 2024
1 parent 788bab0 commit d1beec0
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 29 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/run_tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Run Tests

on:
push:

jobs:
run_tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Yarn Install
run: yarn install
- name: Run Test Script
run: yarn test
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,34 @@
# Ome.tv Automator

Ome.tv Automator automatically sends your messages to thousands of people.

See it on the [Chrome Web Store](https://chromewebstore.google.com/detail/ometv-automator/kdakicmdgfidhnnfjgomlkoikigebpdf).

**Production**:

![Test Status: Production](https://github.com/mstephen19/ome-automator/actions/workflows/run_tests.yaml/badge.svg?branch=main)

**Development**:

![Test Status: Development](https://github.com/mstephen19/ome-automator/actions/workflows/run_tests.yaml/badge.svg?branch=develop)

## Get started

1. Add a message to the sequence (e.g. "Hello"). Multiple messages also supported.
2. Navigate to <https://ome.tv> and click the Ome.tv Automator "Play" button.

You'll notice the Ome.tv "Start" button is automatically clicked. Once you're connected to a stranger, messages from the sequence are sent, in order. Afterwards, "Next" is clicked and the sequence is sent to the next connection, and so on.

## What if a stranger disconnects mid-sequence?

Ome.tv Automator understands when it's disconnected on, and reacts quickly to restart the sequence, once reconnected with someone new.

More information & legal disclaimers available under "Help, Info & Terms" in the Ome.tv Automator popup window

## Screenshots

![Image](./assets/screenshot-1.png)

![Image](./assets/screenshot-2.png)

![Image](./assets/screenshot-3.png)
Binary file added assets/screenshot-1.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/screenshot-2.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/screenshot-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "Ome.tv Automator",
"short_name": "Auto-Ome.tv",
"version": "1.0.0",
"version": "1.0.1",
"description": "Reliably deliver message sequences to Ome.tv connections.",
"icons": {
"16": "public/icon16.png",
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": "ometv",
"private": true,
"version": "0.0.0",
"version": "1.0.1",
"scripts": {
"dev": "vite",
"test": "vitest",
Expand Down
2 changes: 2 additions & 0 deletions src/consts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { AppData, Config, Message, TabData } from './types';

export const EXTENSION_MANIFEST = chrome.runtime.getManifest();

export const defaultAppData: AppData = {
addMessageText: '',
messageSequenceOpen: false,
Expand Down
18 changes: 11 additions & 7 deletions src/content/commands.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Command, CommandMessage } from '../types';
import { TypedEventTarget } from '../utils';
import { pollPredicate, TypedEventTarget } from '../utils';
import { elements } from './elements';

export const tabCommandRouter = () => {
Expand All @@ -14,12 +14,16 @@ export const tabCommandRouter = () => {
events.dispatchEvent(new CustomEvent(command, { detail: tabId }));
});

// Stops if the user clicks the "Stop" button.
elements.stopButton()?.addEventListener('click', () => {
// Passing invalid tab ID (-1)
// Stopping sets the runningTab to null anyways
events.dispatchEvent(new CustomEvent(Command.Stop, { detail: -1 }));
});
(async () => {
await pollPredicate(250, () => Boolean(elements.stopButton()));

// Stops if the user clicks the "Stop" button.
elements.stopButton()?.addEventListener('click', () => {
// Passing invalid tab ID (-1)
// Stopping sets the runningTab to null anyways
events.dispatchEvent(new CustomEvent(Command.Stop, { detail: -1 }));
});
})();

return {
events,
Expand Down
14 changes: 4 additions & 10 deletions src/popup/Accordions/AccordionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Accordion, AccordionDetails, AccordionSummary, Avatar, Divider, styled, Typography } from '@mui/material';
import { Accordion, AccordionDetails, AccordionSummary, Chip, styled, Typography } from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { type ReactNode, useContext } from 'react';
import { AppDataContext } from '../context/AppDataProvider';
Expand All @@ -13,22 +13,16 @@ const AccordionTitle = styled(AccordionSummary)({
},
});

const AccordionTitleAvatar = styled(Avatar)({
width: 20,
height: 20,
fontSize: '1rem',
});

export const AccordionItem = ({
dataKey,
title,
avatar,
chip,
maxHeight,
children,
}: {
dataKey: Exclude<keyof AppData, 'theme' | 'addMessageText'>;
title: string;
avatar?: string;
chip?: string;
maxHeight?: string;
children: ReactNode;
}) => {
Expand All @@ -43,7 +37,7 @@ export const AccordionItem = ({
<AccordionTitle expandIcon={<ExpandMoreIcon />}>
<Typography>{title}</Typography>

{avatar && <AccordionTitleAvatar>{avatar}</AccordionTitleAvatar>}
{chip && <Chip size='small' label={chip} />}
</AccordionTitle>

<AccordionDetails sx={{ maxHeight, overflowY: 'scroll' }}>{children}</AccordionDetails>
Expand Down
16 changes: 12 additions & 4 deletions src/popup/Accordions/MessageSequencer/AddMessageBox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TextField } from '@mui/material';
import { useState, useContext } from 'react';
import { useState, useContext, ChangeEventHandler } from 'react';
import { appDataStore, messageStore } from '../../../storage';
import { sanitize } from '../../../utils';

Expand All @@ -11,12 +11,19 @@ export const AddMessageBox = () => {
const messages = useContext(MessageSequenceContext);
const appData = useContext(AppDataContext);

// const [inputText, setInputText] = useState('');
// Safe to initialize with async retrieved store value because the provider
// doesn't render children until data is initialized.
const [inputText, setInputText] = useState(appData.addMessageText);
const [loading, setLoading] = useState(false);

const [validationError, setValidationError] = useState('');
const showError = Boolean(validationError);

const handleMessageChange: ChangeEventHandler<HTMLInputElement> = async (e) => {
setInputText(e.target.value);
await appDataStore.write({ ...appData, addMessageText: e.target.value });
};

const handleAddMessage = async (unsanitized: string) => {
setLoading(true);

Expand All @@ -39,6 +46,7 @@ export const AddMessageBox = () => {
// Add the message to the end of the list
// Clear out the addMessageText
await Promise.all([messageStore.write([...messages, { id, content }]), appDataStore.write({ ...appData, addMessageText: '' })]);
setInputText('');

setValidationError('');
setLoading(false);
Expand All @@ -60,9 +68,9 @@ export const AddMessageBox = () => {
handleAddMessage(appData.addMessageText);
}
}}
value={appData.addMessageText}
value={inputText}
// ? Store the latest text value in the data store - seamless through popup reloads
onChange={(e) => appDataStore.write({ ...appData, addMessageText: e.target.value })}
onChange={handleMessageChange}
helperText={showError ? validationError : 'Press "Enter" to add your message to the sequence.'}
error={showError}
// sx={{ position: 'sticky', top: 0 }}
Expand Down
5 changes: 3 additions & 2 deletions src/popup/Accordions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import { MessageSequenceContext } from '../context/MessageSequenceProvider';
import { AccordionItem } from './AccordionItem';
import { Divider } from '@mui/material';
import { Help } from './Help';
import { EXTENSION_MANIFEST } from '../../consts';

export const Accordions = () => {
const messages = useContext(MessageSequenceContext);

return (
<>
<AccordionItem dataKey='messageSequenceOpen' title='Message Sequence' avatar={messages.length.toString()} maxHeight='375px'>
<AccordionItem dataKey='messageSequenceOpen' title='Message Sequence' chip={messages.length.toString()} maxHeight='375px'>
<MessageSequencer />
</AccordionItem>

Expand All @@ -27,7 +28,7 @@ export const Accordions = () => {

<Divider />

<AccordionItem dataKey='helpOpen' title='Help, Info & Terms' maxHeight='375px'>
<AccordionItem dataKey='helpOpen' title='Help, Info & Terms' maxHeight='375px' chip={`v${EXTENSION_MANIFEST.version}`}>
<Help />
</AccordionItem>
</>
Expand Down
11 changes: 7 additions & 4 deletions src/popup/TopBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { AppBar, Box, Link, Toolbar, Typography } from '@mui/material';
import { AppBar, Box, Link, Toolbar, Tooltip, Typography } from '@mui/material';
import { AppDataContext } from '../context/AppDataProvider';
import { useContext } from 'react';
import { appDataStore } from '../../storage';
import { ThemeSwitch } from './ThemeSwitch';

import logoGrey from '../../assets/logo-grey.png';
import logoWhite from '../../assets/logo-white.png';
import { EXTENSION_MANIFEST } from '../../consts';

const Logo = ({ theme }: { theme: 'dark' | 'light' }) => (
<Link href='https://ome.tv/' target='_blank' rel='nofollower'>
Expand All @@ -29,9 +30,11 @@ export const TopBar = () => {
<Box sx={{ display: 'flex', gap: '10px', alignItems: 'center' }}>
<Logo theme={appData.theme} />

<Typography fontSize='1rem' sx={{ userSelect: 'none' }}>
Ome.tv Automator
</Typography>
<Tooltip arrow title={EXTENSION_MANIFEST.description}>
<Typography fontSize='1rem' sx={{ cursor: 'pointer' }}>
Ome.tv Automator
</Typography>
</Tooltip>
</Box>

<ThemeSwitch onChange={handleThemeSwitch} checked={appData.theme === 'dark'} />
Expand Down
2 changes: 2 additions & 0 deletions src/popup/context/StoreProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { CircularProgress } from '@mui/material';
* Creates a generic provider for use with a {@link chromeStorage} adapter.
*
* Initializes the store, and updates the context value when changes are detected.
*
* Will not render children until the store has been initialized. Assumes zero store errors.
*/
export function storeProvider<Data>({
context,
Expand Down
1 change: 1 addition & 0 deletions tests/_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ vi.stubGlobal('chrome', {
addListener: chromeTabMessages.addListener,
removeListener: chromeTabMessages.removeListener,
},
getManifest: () => ({}),
},
storage: {
local: {
Expand Down

0 comments on commit d1beec0

Please sign in to comment.