├── src ├── App.css ├── chooj.png ├── Guide │ ├── index.ts │ ├── StepFinal.tsx │ ├── StepZero.tsx │ ├── StepSeven.tsx │ ├── Step.css │ ├── StepFive.tsx │ ├── StepSix.tsx │ ├── StepThree.tsx │ ├── StepFour.tsx │ ├── StepOne.tsx │ ├── Guide.tsx │ ├── StepTwo.tsx │ └── server_icon.svg ├── NoItem.css ├── hash_icon.png ├── person_icon.png ├── FarooqAvatar.png ├── Waiting │ ├── index.ts │ ├── cowsay-pleasewait.png │ ├── Waiting.css │ └── Waiting.tsx ├── RoomView │ ├── index.ts │ ├── RoomView.css │ ├── CannotSendMessage.css │ ├── UnsupportedEventItem.css │ ├── ScrollIntoView.tsx │ ├── waiting_curve.svg │ ├── RoomEvent.tsx │ └── RoomView.tsx ├── CallScreen │ ├── index.ts │ ├── waiting.ogg │ ├── incoming.ogg │ ├── CallScreen.css │ └── CallScreen.tsx ├── VoiceInput │ ├── index.ts │ ├── VoiceInput.css │ └── VoiceInput.tsx ├── LoginWithQR │ ├── index.ts │ ├── LoginWithQR.css │ └── LoginWithQR.tsx ├── ChatTextInput │ ├── index.ts │ ├── ChatTextInput.css │ └── ChatTextInput.tsx ├── MessageItems │ ├── index.ts │ └── IRCLikeMessageItem │ │ ├── index.ts │ │ ├── IRCLikeMessageItem.css │ │ └── IRCLikeMessageItem.tsx ├── asset_modules.d.ts ├── ImageViewer.css ├── NoItem.tsx ├── index.tsx ├── index.css ├── index.html ├── Settings.tsx ├── shared.ts ├── types.ts ├── manifest.webapp ├── globals.d.ts ├── sw.ts ├── InvitesView.tsx ├── ImageViewer.tsx ├── App.tsx ├── ChatRoomItem.tsx ├── About.tsx ├── RoomsView.tsx ├── ChatDMItem.tsx ├── LoginHandler.ts ├── DMsView.tsx ├── utils.tsx ├── Login.tsx ├── Matrix.tsx └── fetch.js ├── .babelrc ├── .eslintrc.js ├── tsconfig.service-worker.json ├── tslint.json ├── .parcelrc ├── .gitignore ├── tsconfig.json ├── .github ├── FUNDING.yml └── workflows │ ├── broadcast_commits.yaml │ └── build.yml ├── addAds.js ├── justkai.js ├── package.json └── README.md /src/App.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["inferno"] 3 | } 4 | -------------------------------------------------------------------------------- /src/chooj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farooqkz/chooj/HEAD/src/chooj.png -------------------------------------------------------------------------------- /src/Guide/index.ts: -------------------------------------------------------------------------------- 1 | import Guide from "./Guide"; 2 | 3 | export default Guide; 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["eslint-config-inferno-app"], 3 | }; 4 | -------------------------------------------------------------------------------- /src/NoItem.css: -------------------------------------------------------------------------------- 1 | .noitem { 2 | margin-top: 20vh; 3 | text-align: center; 4 | } 5 | -------------------------------------------------------------------------------- /src/hash_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farooqkz/chooj/HEAD/src/hash_icon.png -------------------------------------------------------------------------------- /src/person_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farooqkz/chooj/HEAD/src/person_icon.png -------------------------------------------------------------------------------- /src/FarooqAvatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farooqkz/chooj/HEAD/src/FarooqAvatar.png -------------------------------------------------------------------------------- /src/Waiting/index.ts: -------------------------------------------------------------------------------- 1 | import Waiting from "./Waiting"; 2 | 3 | export default Waiting; 4 | -------------------------------------------------------------------------------- /src/RoomView/index.ts: -------------------------------------------------------------------------------- 1 | import RoomView from "./RoomView"; 2 | 3 | export default RoomView; 4 | -------------------------------------------------------------------------------- /src/CallScreen/index.ts: -------------------------------------------------------------------------------- 1 | import CallScreen from "./CallScreen"; 2 | 3 | export default CallScreen; 4 | -------------------------------------------------------------------------------- /src/CallScreen/waiting.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farooqkz/chooj/HEAD/src/CallScreen/waiting.ogg -------------------------------------------------------------------------------- /src/VoiceInput/index.ts: -------------------------------------------------------------------------------- 1 | import VoiceInput from "./VoiceInput"; 2 | 3 | export default VoiceInput; 4 | -------------------------------------------------------------------------------- /src/CallScreen/incoming.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farooqkz/chooj/HEAD/src/CallScreen/incoming.ogg -------------------------------------------------------------------------------- /src/LoginWithQR/index.ts: -------------------------------------------------------------------------------- 1 | import LoginWithQR from "./LoginWithQR"; 2 | 3 | export default LoginWithQR; 4 | -------------------------------------------------------------------------------- /src/ChatTextInput/index.ts: -------------------------------------------------------------------------------- 1 | import ChatTextInput from "./ChatTextInput"; 2 | 3 | export default ChatTextInput; 4 | -------------------------------------------------------------------------------- /src/Waiting/cowsay-pleasewait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farooqkz/chooj/HEAD/src/Waiting/cowsay-pleasewait.png -------------------------------------------------------------------------------- /src/MessageItems/index.ts: -------------------------------------------------------------------------------- 1 | import IRCLikeMessageItem from "./IRCLikeMessageItem"; 2 | 3 | export { IRCLikeMessageItem }; 4 | -------------------------------------------------------------------------------- /src/asset_modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.png"; 2 | declare module "*.svg"; 3 | declare module "*.ogg"; 4 | declare module "xmimetype"; 5 | -------------------------------------------------------------------------------- /src/MessageItems/IRCLikeMessageItem/index.ts: -------------------------------------------------------------------------------- 1 | import IRCLikeMessageItem from "./IRCLikeMessageItem"; 2 | 3 | export default IRCLikeMessageItem; 4 | -------------------------------------------------------------------------------- /src/LoginWithQR/LoginWithQR.css: -------------------------------------------------------------------------------- 1 | .videodiv { 2 | display: flex; 3 | justify-content: center; 4 | max-height: 100%; 5 | max-width: 100%; 6 | } 7 | -------------------------------------------------------------------------------- /src/RoomView/RoomView.css: -------------------------------------------------------------------------------- 1 | .eventsandtextinput { 2 | height: calc(100vh - 2.8rem - 40px); 3 | width: 100%; 4 | padding: 0; 5 | display: grid; 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.service-worker.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "lib": ["WebWorker", "ES2017"] 5 | }, 6 | "files": ["src/sw.ts"] 7 | } 8 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint-config-prettier", 3 | "rules": { 4 | "ordered-imports": false, 5 | "interface-name": [true, "never-prefix"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/ImageViewer.css: -------------------------------------------------------------------------------- 1 | .imageviewer { 2 | z-index: 9999; 3 | background-color: rgb(255, 255, 255, 0.35); 4 | position: fixed; 5 | width: 100vw; 6 | height: 100vh; 7 | } 8 | -------------------------------------------------------------------------------- /.parcelrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@parcel/config-default", 3 | "transformers": { 4 | "manifest.webapp": ["@parcel/transformer-raw"], 5 | "*.png": ["@parcel/transformer-raw"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Guide/StepFinal.tsx: -------------------------------------------------------------------------------- 1 | function StepFinal() { 2 | return ( 3 |
4 |

Have fun!

5 |
6 | ); 7 | } 8 | 9 | export default StepFinal; 10 | -------------------------------------------------------------------------------- /src/VoiceInput/VoiceInput.css: -------------------------------------------------------------------------------- 1 | .voiceinput { 2 | width: 100vw; 3 | display: flex; 4 | flex-direction: column; 5 | justify-content: flex-start; 6 | align-items: center; 7 | background-color: #f5c211; 8 | } 9 | -------------------------------------------------------------------------------- /src/Waiting/Waiting.css: -------------------------------------------------------------------------------- 1 | img.waiting { 2 | padding-left: 24px; 3 | padding-right: 24px; 4 | padding-top: 105px; 5 | height: 110px; 6 | width: 192px; 7 | } 8 | 9 | p.waiting { 10 | margin-top: 2px; 11 | text-align: center; 12 | } 13 | -------------------------------------------------------------------------------- /src/RoomView/CannotSendMessage.css: -------------------------------------------------------------------------------- 1 | .cannotsendmessage { 2 | background-color: var(--color-blue-mid-dark); 3 | height: 8vh; 4 | text-align: center; 5 | margin-top: auto; 6 | } 7 | 8 | .cannotsendmessage > p { 9 | font-size: 14px; 10 | margin: auto; 11 | } 12 | -------------------------------------------------------------------------------- /src/NoItem.tsx: -------------------------------------------------------------------------------- 1 | import "./NoItem.css"; 2 | 3 | interface NoItemProps { 4 | text: string; 5 | } 6 | 7 | export default function NoItem({ text }: NoItemProps) { 8 | return ( 9 |
10 |

{text}

11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "inferno"; 2 | import "core-js"; // TODO: import only what is needed not everything 3 | import "abortcontroller-polyfill/dist/polyfill-patch-fetch"; 4 | import "./index.css"; 5 | import App from "./App"; 6 | 7 | render(, document.getElementById("root")); 8 | -------------------------------------------------------------------------------- /src/Guide/StepZero.tsx: -------------------------------------------------------------------------------- 1 | function StepZero() { 2 | return ( 3 |
4 |

5 | Hello! Care to spend 30 seconds to learn about chooj and its underlying 6 | network, Matrix? 7 |

8 |
9 | ); 10 | } 11 | 12 | export default StepZero; 13 | -------------------------------------------------------------------------------- /src/Guide/StepSeven.tsx: -------------------------------------------------------------------------------- 1 | function StepSeven() { 2 | return ( 3 |
4 |

5 | It is possible to bridge groups on a number of other Messengers like 6 | Telegram, Slack, Discord and more with Matrix! 7 |

8 |
9 | ); 10 | } 11 | 12 | export default StepSeven; 13 | -------------------------------------------------------------------------------- /src/Guide/Step.css: -------------------------------------------------------------------------------- 1 | .step { 2 | text-align: center; 3 | margin-top: 12vh; 4 | } 5 | 6 | .step > p { 7 | margin-top: -6vh; 8 | } 9 | 10 | .step > div { 11 | margin-top: 10vh; 12 | } 13 | 14 | .step > div > img { 15 | position: relative; 16 | } 17 | 18 | .step > div > svg { 19 | left: 0; 20 | position: absolute; 21 | } 22 | -------------------------------------------------------------------------------- /src/Guide/StepFive.tsx: -------------------------------------------------------------------------------- 1 | function StepFive() { 2 | return ( 3 |
4 |

5 | You can also register an account on some homeserver of your own choice. 6 | However, chooj currently does not support guest access or account 7 | registration. But it's coming soon! 8 |

9 |
10 | ); 11 | } 12 | 13 | export default StepFive; 14 | -------------------------------------------------------------------------------- /src/Guide/StepSix.tsx: -------------------------------------------------------------------------------- 1 | function StepSix() { 2 | return ( 3 |
4 |

5 | With Matrix, you can chat, send photos, videos and other files and do 6 | voice or video chat! Voice chat is Work In Progress in chooj. There are 7 | Matrix apps for Android, iOS, Windows, Linux, Mac. 8 |

9 |
10 | ); 11 | } 12 | 13 | export default StepSix; 14 | -------------------------------------------------------------------------------- /src/Guide/StepThree.tsx: -------------------------------------------------------------------------------- 1 | function StepThree() { 2 | return ( 3 |
4 |

5 | You can join any of these "homeservers" or host your own homeserver for 6 | yourself, and possibly family and friends. To use chooj, to connect to 7 | the Matrix network, you should connect to a Matrix homeserver. 8 |

9 |
10 | ); 11 | } 12 | 13 | export default StepThree; 14 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | #callscreen { 2 | display: block !important; 3 | height: 100%; 4 | width: 100%; 5 | top: 0; 6 | left: 0; 7 | } 8 | 9 | #toast { 10 | background-color: black; 11 | min-height: 18px; 12 | bottom: auto; 13 | color: white; 14 | font-size: 12px; 15 | top: 0; 16 | left: 0; 17 | text-align: center; 18 | position: absolute; 19 | width: 100%; 20 | z-index: 99999; 21 | display: none; 22 | } 23 | -------------------------------------------------------------------------------- /src/RoomView/UnsupportedEventItem.css: -------------------------------------------------------------------------------- 1 | .event { 2 | padding-top: 2px; 3 | padding-bottom: 2px; 4 | height: auto; 5 | width: 100%; 6 | } 7 | 8 | .event--focused { 9 | padding-top: 2px; 10 | padding-bottom: 2px; 11 | height: auto; 12 | width: 100%; 13 | background-color: black; 14 | color: white; 15 | } 16 | 17 | .event > p { 18 | font-size: 12px !important; 19 | } 20 | 21 | .event--focused > p { 22 | font-size: 12px !important; 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | 24 | *.orig 25 | package-lock.json 26 | .parcel-cache 27 | -------------------------------------------------------------------------------- /src/Guide/StepFour.tsx: -------------------------------------------------------------------------------- 1 | function StepFour() { 2 | return ( 3 |
4 |

5 | You can use chooj with an existing account on some homeserver to chat in 6 | different rooms on the Matrix network. If you haven't got an account, 7 | don't worry! You can use guest access through a homeserver to join rooms 8 | which allow guest access. 9 |

10 |
11 | ); 12 | } 13 | 14 | export default StepFour; 15 | -------------------------------------------------------------------------------- /src/VoiceInput/VoiceInput.tsx: -------------------------------------------------------------------------------- 1 | import { msToHigherScale } from "../utils"; 2 | import "./VoiceInput.css"; 3 | 4 | interface VoiceInputProps { 5 | title: string; 6 | seconds: number; 7 | } 8 | 9 | function VoiceInput({ title, seconds }: VoiceInputProps) { 10 | return ( 11 |
12 |
{title}
13 |
{msToHigherScale(seconds * 1000)}
14 |
15 | ); 16 | } 17 | 18 | export default VoiceInput; 19 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | chooj 12 | 13 | 14 |
15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/CallScreen/CallScreen.css: -------------------------------------------------------------------------------- 1 | .callscreendiv { 2 | display: block !important; 3 | position: absolute; 4 | height: 100vh; 5 | width: 100vw; 6 | top: 0; 7 | left: 0; 8 | right: 0; 9 | bottom: 0; 10 | z-index: 9999; 11 | background-color: rgba(183, 82, 100, 0.75); 12 | } 13 | 14 | .callscreendiv > div > img { 15 | height: 64px; 16 | width: 64px; 17 | border-radius: 25%; 18 | } 19 | 20 | .callscreen-content { 21 | display: flex; 22 | justify-content: space-around; 23 | flex-direction: column; 24 | flex-wrap: nowrap; 25 | align-items: center; 26 | height: 70vh; 27 | } 28 | -------------------------------------------------------------------------------- /src/ChatTextInput/ChatTextInput.css: -------------------------------------------------------------------------------- 1 | .chattextinput { 2 | display: flex; 3 | justify-content: center; 4 | flex-direction: center; 5 | background-color: var(--color-blue); 6 | } 7 | 8 | .chattextinput > input { 9 | width: 100%; 10 | font-size: 15px; 11 | margin: 2px; 12 | border-radius: 4px; 13 | } 14 | 15 | .chattextinput--focused { 16 | display: flex; 17 | justify-content: center; 18 | flex-direction: center; 19 | background-color: var(--color-carrotorange); 20 | } 21 | 22 | .chattextinput--focused > input { 23 | width: 100%; 24 | font-size: 15px; 25 | margin: 2px; 26 | border-radius: 4px; 27 | } 28 | -------------------------------------------------------------------------------- /src/RoomView/ScrollIntoView.tsx: -------------------------------------------------------------------------------- 1 | interface ScrollIntoViewProps { 2 | children: any; 3 | shouldScroll: boolean; 4 | } 5 | 6 | function ScrollIntoView({ children, shouldScroll }: ScrollIntoViewProps) { 7 | if (children instanceof Array || !children) { 8 | throw new TypeError("There must be exactly one child. No less, no more!"); 9 | } 10 | return ( 11 |
{ 15 | if (div) div.scrollIntoView(); 16 | } 17 | : null 18 | } 19 | $HasVNodeChildren 20 | > 21 | {children} 22 |
23 | ); 24 | } 25 | 26 | export default ScrollIntoView; 27 | -------------------------------------------------------------------------------- /src/Settings.tsx: -------------------------------------------------------------------------------- 1 | interface Preferences { 2 | adShowFreq: "startup" | number; 3 | serversForPublicDirectory: string[]; 4 | mediaLoading: "always" | "only_on_wifi" | "only_on_request"; 5 | inviteAutoAccept: boolean; 6 | } 7 | 8 | function Settings() { 9 | return ( 10 |

11 | Press center key to enable push notifification in Chooj. 12 |
13 | This is unreliable, experimental and CANNOT BE UNDONE 14 | . 15 |
16 | You cannot disable or enable notifications per room or sender through 17 | Chooj. 18 |
19 | If enabling push notifications was causing problems for you, you may 20 | reinstall Chooj. 21 |

22 | ); 23 | } 24 | 25 | export default Settings; 26 | -------------------------------------------------------------------------------- /src/shared.ts: -------------------------------------------------------------------------------- 1 | import { MatrixClient } from "matrix-js-sdk"; 2 | import { RoomsViewState } from "./types"; 3 | 4 | class Shared { 5 | public stateStores: Map = new Map(); 6 | // This is used to save state of components 7 | // on unmount and later retrieve it when 8 | // the component is constructed. 9 | private _mClient: MatrixClient | null; 10 | 11 | constructor() { 12 | this._mClient = null; 13 | } 14 | 15 | get mClient(): MatrixClient { 16 | if (!this._mClient) { 17 | throw new Error("mClient is null!"); 18 | } 19 | return this._mClient; 20 | } 21 | 22 | set mClient(val: MatrixClient) { 23 | this._mClient = val; 24 | } 25 | } 26 | 27 | let shared = new Shared(); 28 | 29 | export default shared; 30 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { Room } from "matrix-js-sdk"; 2 | 3 | interface RoomsViewState { 4 | cursor: number; 5 | rooms: Room[]; 6 | } 7 | 8 | interface RoomsViewProps { 9 | selectedRoomCb: (roomId: null | string) => void; 10 | } 11 | 12 | type startCall = (roomId: string, type: string, userId: string) => void; 13 | 14 | interface Homeserver { 15 | base_url: string; 16 | } 17 | 18 | interface IdentityServer { 19 | base_url: string; 20 | } 21 | 22 | interface WellKnown { 23 | "m.homeserver": Homeserver; 24 | "m.identity_server"?: IdentityServer; 25 | } 26 | 27 | interface LoginData { 28 | user_id: string; 29 | access_token: string; 30 | well_known: WellKnown; 31 | } 32 | 33 | export { RoomsViewState, RoomsViewProps, startCall, LoginData, WellKnown }; 34 | -------------------------------------------------------------------------------- /src/Waiting/Waiting.tsx: -------------------------------------------------------------------------------- 1 | import "./Waiting.css"; 2 | import cow from "url:./cowsay-pleasewait.png"; 3 | 4 | let tips: string[] = [ 5 | "Use call key in People tab to quickly call someone", 6 | "In About tab, you can see credits", 7 | "Contact developer by pressing Call key in About tab", 8 | "Press Backspace in Call screen to end the ongoing call", 9 | ]; 10 | 11 | function randomTip() { 12 | return tips[Math.floor(Math.random() * tips.length)]; 13 | } 14 | 15 | function Waiting({ noTip }: { noTip?: boolean }) { 16 | return ( 17 | <> 18 | 19 |

20 | {noTip ? "" : randomTip()} 21 |

22 | 23 | ); 24 | } 25 | 26 | export default Waiting; 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noImplicitAny": true, 5 | "strictNullChecks": true, 6 | "strict": true, 7 | "jsx": "preserve", 8 | "baseUrl": "./src", 9 | "noUnusedParameters": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "noUnusedLocals": true, 13 | "lib": ["es2017", "dom"], 14 | "allowSyntheticDefaultImports": true, 15 | "types": ["inferno"], 16 | "skipLibCheck": true, 17 | "esModuleInterop": true, 18 | "moduleResolution": "node", 19 | "target": "es2022", 20 | "paths": { 21 | "KaiUI": ["./node_modules/KaiUI"] 22 | } 23 | }, 24 | "exclude": [ 25 | "build", 26 | "src/sw.ts", 27 | "/node_modules" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: 14 | 15 | -------------------------------------------------------------------------------- /.github/workflows/broadcast_commits.yaml: -------------------------------------------------------------------------------- 1 | on: [push] 2 | 3 | jobs: 4 | send-message: 5 | runs-on: ubuntu-latest 6 | name: Send message via Matrix 7 | steps: 8 | - name: Send message to test channel 9 | id: matrix-chat-message 10 | uses: fadenb/matrix-chat-message@v0.0.6 11 | with: 12 | homeserver: "mozilla.modular.im" 13 | token: ${{ secrets.ACCESS_TOKEN }} 14 | channel: "!OQyTyXWouXhUmgvaQW:mozilla.org" 15 | message: | 16 | Thee in luck! New push to Chooj repository which means new development build available! 17 | 18 | Download from https://farooqkz.de1.hashbang.sh/matrix-client-builds/${{ github.sha }}.zip to sideload OR 19 | 20 | Download from https://farooqkz.de1.hashbang.sh/matrix-client-builds/${{ github.sha }}-omnisd.zip to install with OmniSD. 21 | -------------------------------------------------------------------------------- /src/MessageItems/IRCLikeMessageItem/IRCLikeMessageItem.css: -------------------------------------------------------------------------------- 1 | .ircmsg { 2 | padding-top: 2px; 3 | padding-bottom: 2px; 4 | height: auto; 5 | width: 100%; 6 | } 7 | 8 | .ircmsg > p { 9 | font-size: 14px !important; 10 | } 11 | 12 | .ircmsg--focused { 13 | padding-top: 2px; 14 | padding-bottom: 2px; 15 | height: auto; 16 | width: 100%; 17 | font-size: 15px !important; 18 | background-color: black; 19 | color: white; 20 | } 21 | 22 | .ircmsg--focused > p { 23 | font-size: 15px !important; 24 | } 25 | 26 | @keyframes being_sent { 27 | from { 28 | background-color: black; 29 | } 30 | to { 31 | background-color: red; 32 | } 33 | } 34 | 35 | .sending { 36 | animation-name: being_sent; 37 | animation-duration: 2s; 38 | animation-direction: alternate; 39 | animation-iteration-count: infinite; 40 | } 41 | 42 | .not_sent { 43 | color: red; 44 | } 45 | -------------------------------------------------------------------------------- /src/ChatTextInput/ChatTextInput.tsx: -------------------------------------------------------------------------------- 1 | import "./ChatTextInput.css"; 2 | 3 | interface ChatTextInputProps { 4 | isFocused: boolean; 5 | message: string; 6 | onChangeCb: (message: string) => void; 7 | } 8 | 9 | function ChatTextInput({ isFocused, message, onChangeCb }: ChatTextInputProps) { 10 | const onChange = (evt: ClipboardEvent | Event) => { 11 | evt.target && onChangeCb(evt.target.value); 12 | }; 13 | 14 | return ( 15 |
16 | { 24 | if (!input) return; 25 | if (isFocused) input.focus(); 26 | else input.blur(); 27 | }} 28 | /> 29 |
30 | ); 31 | } 32 | 33 | export default ChatTextInput; 34 | -------------------------------------------------------------------------------- /src/manifest.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.0.0", 3 | "name": "chooj", 4 | "description": "Matrix client for KaiOS", 5 | "theme_color": "#d6dbc9", 6 | "launch_path": "/index.html", 7 | "developer": { 8 | "name": "Farooq Karimi Zadeh", 9 | "url": "https://github.com/farooqkz/chooj" 10 | }, 11 | "type": "certified", 12 | "icons": { 13 | "512": "/chooj.png" 14 | }, 15 | "permissions": { 16 | "audio-capture": "Used for voice calls", 17 | "video-capture": "Used for video calls as well as logging in with QR", 18 | "desktop-notification": "", 19 | "systemXHR": "", 20 | "audio-channel-telephony": "Used for voice calls", 21 | "audio-channel-notification": "", 22 | "audio-channel-ringer": "Used for ringtone for incoming voice calls", 23 | "attention": "Used to show attention screen for incoming voice calls", 24 | "push": "Used for receiving push notification", 25 | "serviceworker": "", 26 | "device-storage:pictures": { 27 | "access": "readwrite" 28 | } 29 | }, 30 | "messages": [{ "push": "/index.html" }, { "push-register": "/index.html" }], 31 | "origin": "app://kaios.chooj.app" 32 | } 33 | -------------------------------------------------------------------------------- /addAds.js: -------------------------------------------------------------------------------- 1 | const fs = require("node:fs"); 2 | const { Parser } = require("htmlparser2"); 3 | const { DomHandler, Element } = require("domhandler"); 4 | const render = require("dom-serializer").default; 5 | 6 | 7 | var sdkPath; 8 | let collect = false; 9 | for (let arg of process.argv) { 10 | if (collect) { 11 | sdkPath = arg; 12 | break; 13 | } 14 | if (arg === "--path") { 15 | collect = true; 16 | } 17 | } 18 | 19 | let html = fs.readFileSync("build/index.html", { encoding: "utf-8" }); 20 | const handler = new DomHandler((error, dom) => { 21 | if (error) { 22 | console.error("Cannot parse index.html into DOM"); 23 | process.exit(1); 24 | } 25 | let head = dom[1].children.filter((child) => child.name === "head")[0]; 26 | if (!head) { 27 | console.error("No found..."); 28 | process.exit(1); 29 | } 30 | head.children.push(new Element("script", { src: "/kaiads.js", defer: "" })); 31 | fs.writeFileSync("./build/index.html", render(dom)); 32 | console.log("Successfully added the