Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CNAME
Original file line number Diff line number Diff line change
@@ -1 +1 @@
octogram.me
octogram.me
84 changes: 48 additions & 36 deletions assets/src/octogram.home.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {calculateSize, clearPage, fixInjectionTags, generateWaveGradient} from "./octogram.utils.js";
import { calculateSize, clearPage, fixInjectionTags, generateWaveGradient } from "./octogram.utils.js";
import * as header from "./octogram.header.js";
import {getStringRef} from "./octogram.translations.js";
import { getStringRef } from "./octogram.translations.js";
import * as footer from "./octogram.footer.js";
import * as changelog from "./octogram.changelog.js";
import * as privacyPolicy from "./octogram.privacy.js";
Expand Down Expand Up @@ -38,19 +38,19 @@ function init() {
pageContainer.appendChild(footer.createElement());

document.body.appendChild(pageContainer);

loadVersions();

if (!particlesWorker) {
particlesWorker = new Worker('/assets/lib/particles-worker.js', { type: 'module' });
}

window.addEventListener('resize', onResize);

const canvasBoundingRect = particlesCanvas.getBoundingClientRect();
particlesCanvas.width = canvasBoundingRect.width;
particlesCanvas.height = canvasBoundingRect.height;

const offscreen = particlesCanvas.transferControlToOffscreen();
particlesWorker.postMessage({ canvas: offscreen }, [offscreen]);
}
Expand All @@ -74,7 +74,7 @@ function onResize() {
}

particlesWorker.postMessage({ canvas: false });

particlesOnResizeTimeout = setTimeout(() => {
const canvasBoundingRect = particlesCanvas.getBoundingClientRect();
particlesWorker.postMessage({ resize: true, width: canvasBoundingRect.width, height: canvasBoundingRect.height });
Expand Down Expand Up @@ -157,62 +157,74 @@ function generateAiFeatures() {
messageTitle.classList.add('title');
messageTitle.textContent = getStringRef('AI_TITLE');
messageTitle.appendChild(lampIcon);

const featuresList = document.createElement('div');
featuresList.classList.add('features-list');
featuresList.appendChild(createFeature(getStringRef('AI_FEAT_1'), getStringRef('AI_FEAT_1_DESC'), 'ManyProvidersFeat1.png'));
featuresList.appendChild(createFeature(getStringRef('AI_FEAT_2'), getStringRef('AI_FEAT_2_DESC'), 'ChatContextFeat2.png'));
featuresList.appendChild(createFeature(getStringRef('AI_FEAT_3'), getStringRef('AI_FEAT_3_DESC'), 'CustomModelsFeat3.png', true));

const featuresContainer = document.createElement('div');
featuresContainer.classList.add('features-container');
featuresContainer.appendChild(messageTitle);
featuresContainer.appendChild(featuresList);

const features = document.createElement('div');
features.classList.add('features');
features.appendChild(featuresContainer);

return features;
}

function createFeature(title, description, image, fromBottom = false) {
const featureTitle = document.createElement('div');
featureTitle.classList.add('feature-title');
featureTitle.textContent = title;

const featureDescription = document.createElement('div');
featureDescription.classList.add('feature-description');
featureDescription.textContent = description;


const textWrapper = document.createElement('div');
textWrapper.classList.add('feature-text');
textWrapper.appendChild(featureTitle);
textWrapper.appendChild(featureDescription);

const shadow = document.createElement('div');
shadow.classList.add('shadow');
const realImage = document.createElement('img');
realImage.classList.add('real-image');
realImage.src = '/assets/images/'+image;
realImage.src = '/assets/images/' + image;
const deviceFrame = document.createElement('img');
deviceFrame.classList.add('frame');
deviceFrame.src = '/assets/images/DeviceFrameTelegram.Android.svg';

const featureImage = document.createElement('div');
featureImage.classList.add('feature-image');
featureImage.appendChild(shadow);
featureImage.appendChild(realImage);
featureImage.appendChild(deviceFrame);

const feature = document.createElement('div');
feature.classList.add('feature');
feature.classList.toggle('from-bottom', fromBottom);
feature.appendChild(featureTitle);
feature.appendChild(featureDescription);
feature.appendChild(featureImage);


if (fromBottom) {
feature.appendChild(featureImage);
feature.appendChild(textWrapper);
} else {
feature.appendChild(textWrapper);
feature.appendChild(featureImage);
}

return feature;
}


function generateFeatures() {
const background = document.createElement('div');
background.classList.add('background');

const leftPartSticker = document.createElement('lottie-player');
leftPartSticker.toggleAttribute('autoplay');
leftPartSticker.toggleAttribute('loop');
Expand All @@ -224,28 +236,28 @@ function generateFeatures() {
leftPart.classList.add('left-part');
leftPart.appendChild(leftPartSticker);
leftPart.appendChild(leftPartTitle);

const rightPart = document.createElement('div');
rightPart.classList.add('right-part');
rightPart.appendChild(createDeviceWithMockup('AppearanceGen1.png'));
rightPart.appendChild(createDeviceWithMockup('AppearanceGen2.png'));
rightPart.appendChild(createDeviceWithMockup('AppearanceGen3.png'));

const featuresContent = document.createElement('div');
featuresContent.classList.add('content');
featuresContent.appendChild(leftPart);
featuresContent.appendChild(rightPart);

const upperWaves = document.createElement('div');
upperWaves.classList.add('waves');
initBackground(upperWaves);

const features = document.createElement('div');
features.classList.add('features-standard');
features.appendChild(background);
features.appendChild(featuresContent);
features.appendChild(upperWaves);

return features;
}

Expand All @@ -254,7 +266,7 @@ function createDeviceWithMockup(image) {
shadow.classList.add('shadow');
const realImage = document.createElement('img');
realImage.classList.add('real-image');
realImage.src = '/assets/images/'+image;
realImage.src = '/assets/images/' + image;
const featureImage = document.createElement('div');
featureImage.classList.add('device-image');
featureImage.appendChild(shadow);
Expand Down Expand Up @@ -294,7 +306,7 @@ function generateDownload() {

const separator = document.createElement('div');
separator.classList.add('separator');
separator.style.setProperty('--text', '"'+getStringRef('DOWNLOAD_OR')+'"');
separator.style.setProperty('--text', '"' + getStringRef('DOWNLOAD_OR') + '"');

const stores = document.createElement('div');
stores.classList.add('stores');
Expand Down Expand Up @@ -335,11 +347,11 @@ function appendStores(stores) {
}

function generateStore({
iconUrl,
id,
href,
isUnavailable = false
}) {
iconUrl,
id,
href,
isUnavailable = false
}) {
const storeIconElement = document.createElement('img');
storeIconElement.src = iconUrl;
const storeIconContainer = document.createElement('div');
Expand Down Expand Up @@ -389,7 +401,7 @@ function loadVersions() {
loadVersionsWithResponse(precachedResponse);
} else {
const XML = new XMLHttpRequest();
XML.open('GET', 'https://api.github.com/repos/OctoGramApp/OctoGram/releases?cache='+Math.random().toString(), true);
XML.open('GET', 'https://api.github.com/repos/OctoGramApp/OctoGram/releases?cache=' + Math.random().toString(), true);
XML.send();
XML.addEventListener('readystatechange', (e) => {
if (e.target.readyState === 4 && e.target.status === 200) {
Expand All @@ -407,7 +419,7 @@ function loadVersions() {
function loadVersionsWithResponse(response) {
let selectedRelease = response[0];
if (selectedRelease['prerelease']) {
for(const release of response) {
for (const release of response) {
if (!release['prerelease']) {
selectedRelease = release;
break;
Expand All @@ -416,7 +428,7 @@ function loadVersionsWithResponse(response) {
}

let sizeSum = 0;
for(const asset of selectedRelease['assets']) {
for (const asset of selectedRelease['assets']) {
sizeSum += asset['size'];
}
sizeSum /= selectedRelease['assets'].length;
Expand Down
26 changes: 13 additions & 13 deletions assets/src/octogram.translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ const TRANSLATIONS_REF = {
CHANGELOG_DOWNLOAD_SUBTITLE_SUGGESTION: 'The {0} version should be the most suitable and stable one for your device.',
CHANGELOG_DOWNLOAD_SELECT: 'Select your option',
CHANGELOG_DOWNLOAD_BUTTON: 'Download',

AI_TITLE: 'Now with AI',
AI_FEAT_1: 'So many providers. Total freedom.',
AI_FEAT_1_DESC: 'Access the power of Gemini, ChatGPT, and OpenRouter — all in one place, ready when you need them most.',
AI_FEAT_2: 'Chat smarter with real context.',
AI_FEAT_2_DESC: 'Automatically use past messages to boost replies. Use Ask on Media to get instant insights from photos, videos, and more.',
AI_FEAT_3: 'Create your own AI. Unlimited possibilities.',
AI_FEAT_3_DESC: 'Design fully customizable models with your own prompts. Tailor OctoGram AI to your unique style and needs.',

FT_T: 'All the\n<b>customizations</b>\nyou like.',

DOWNLOAD_TITLE: 'The experience begins',
Expand Down Expand Up @@ -118,34 +118,34 @@ function getStringRef(name, ...args) {

if (args.length) {
const isSortObject = args.some((e) => typeof e == 'object');
if(isSortObject){
if (isSortObject) {
const splittedString = string.split('{');
let temporaryString = '';

for(const part of splittedString){
if(part[1] === '}' && !isNaN(parseInt(part[0]))){
for (const part of splittedString) {
if (part[1] === '}' && !isNaN(parseInt(part[0]))) {
const isElement = args[part[0]] instanceof HTMLElement;
const repartSet = '<smali data-id="'+part[0]+'"></smali>';
const repartSet = '<smali data-id="' + part[0] + '"></smali>';
temporaryString += isElement && repartSet || args[part[0]];
temporaryString += part.slice(2);
}else{
} else {
temporaryString += part;
}
}

const newGeneratedElement = document.createElement('span');
newGeneratedElement.classList.add('dynamic-translation');
newGeneratedElement.innerHTML = temporaryString;
for(const element of newGeneratedElement.childNodes){
if(element.tagName === 'SMALI' && element.dataset.id){
for (const element of newGeneratedElement.childNodes) {
if (element.tagName === 'SMALI' && element.dataset.id) {
element.replaceWith(args[element.dataset.id]);
}
}

return newGeneratedElement;
}else{
for(const [id, arg] of args.entries()){
string = string.replaceAll('{'+id+'}', arg);
} else {
for (const [id, arg] of args.entries()) {
string = string.replaceAll('{' + id + '}', arg);
}
}
}
Expand All @@ -168,7 +168,7 @@ function getTextNodeByStringRef(name, ...args) {

function getLanguageCode() {
if (typeof window.navigator.language != 'undefined') {
for(const lang of window.navigator.language.split('-')) {
for (const lang of window.navigator.language.split('-')) {
if (AVAILABLE_LANGUAGES.includes(lang.toLowerCase())) {
if (lang.toLowerCase() === 'es') {
return 'es-ES';
Expand Down
Loading