Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
c78e769
Bump ajv from 6.12.6 to 6.14.0
dependabot[bot] Feb 22, 2026
a54ee45
Bump fast-xml-parser from 4.5.3 to 4.5.4
dependabot[bot] Feb 28, 2026
de93f2e
Bump minimatch from 3.1.2 to 3.1.5
dependabot[bot] Mar 2, 2026
0f9c769
Bump tar from 7.5.9 to 7.5.11
dependabot[bot] Mar 11, 2026
e0484dc
Bump undici from 6.23.0 to 6.24.1
dependabot[bot] Mar 14, 2026
0e8b3a6
Add attendance, favorites, and free-auditories
TheDayG0ne Apr 14, 2026
34fa392
docs: add favorites, attendance & schedule alerts
TheDayG0ne Apr 14, 2026
e2953a7
Update package-lock with dependency bumps
TheDayG0ne Apr 14, 2026
3a882cd
Add academic calendar & study profile features
TheDayG0ne Apr 14, 2026
4cfb23c
Add date field, history screen; attendance v2
TheDayG0ne Apr 14, 2026
55efe89
Support all-day & academic events export
TheDayG0ne Apr 14, 2026
9f88b10
Add calendar export, date fields, attendance v2
TheDayG0ne Apr 14, 2026
4c7a28d
Add academic calendar UI, fixtures & date parsing
TheDayG0ne Apr 14, 2026
9270b59
docs: refine data-and-storage wording and formatting
TheDayG0ne Apr 14, 2026
ae3caf8
Docs: normalize table and notifications formatting
TheDayG0ne Apr 14, 2026
e1ff140
Add AcademicEventModal and refactor calendar UI
TheDayG0ne Apr 17, 2026
24477ca
Improve calendar, free-auditories & news UI
TheDayG0ne Apr 17, 2026
3fd1680
Update agent guidelines and enforce docs sync
TheDayG0ne Apr 17, 2026
fdec38e
Use system Modal for AcademicEventModal
TheDayG0ne Apr 17, 2026
3612bb0
Refactor AcademicEventModal to pageSheet modal
TheDayG0ne Apr 17, 2026
edef8fe
Improve NativeDateField UX and styles
TheDayG0ne Apr 17, 2026
d48750e
Improve date picker UI and add ru-RU locale
TheDayG0ne Apr 17, 2026
ef29ef2
Compact week selector for Free Auditories
TheDayG0ne Apr 17, 2026
8f4e82f
Pin datetimepicker to 8.4.4 and add plugin
TheDayG0ne Apr 20, 2026
49a5afb
Merge branch 'master' into update-2.3.2
TheDayG0ne Apr 20, 2026
aec232e
Use local dates; persist schedule notification IDs
TheDayG0ne Apr 20, 2026
33c935f
docs: document schedule keys and homework notes
TheDayG0ne Apr 20, 2026
09f4be9
Add Snake mini-game, achievements and dev tools
TheDayG0ne Apr 20, 2026
df57256
Add 'legend' theme unlocked by achievements
TheDayG0ne Apr 20, 2026
afd4669
Add 'legend' accent and restrict if locked
TheDayG0ne Apr 20, 2026
0c65188
Gate 'legend' accent, show active notice
TheDayG0ne Apr 20, 2026
3146620
Merge branch 'update-2.3.2' into dependabot/npm_and_yarn/undici-6.24.1
TheDayG0ne Apr 20, 2026
db6f6fc
Merge pull request #41 from PRO100BYTE/dependabot/npm_and_yarn/undici…
TheDayG0ne Apr 20, 2026
6c40f4a
Merge branch 'update-2.3.2' into dependabot/npm_and_yarn/tar-7.5.11
TheDayG0ne Apr 20, 2026
16e5258
Merge pull request #39 from PRO100BYTE/dependabot/npm_and_yarn/tar-7.…
TheDayG0ne Apr 20, 2026
3ed43af
Merge branch 'update-2.3.2' into dependabot/npm_and_yarn/fast-xml-par…
TheDayG0ne Apr 20, 2026
8be005d
Merge pull request #36 from PRO100BYTE/dependabot/npm_and_yarn/fast-x…
TheDayG0ne Apr 20, 2026
940fe3a
Merge branch 'update-2.3.2' into dependabot/npm_and_yarn/minimatch-3.1.5
TheDayG0ne Apr 20, 2026
31d53ae
Merge pull request #35 from PRO100BYTE/dependabot/npm_and_yarn/minima…
TheDayG0ne Apr 20, 2026
9c67ee8
Merge pull request #33 from PRO100BYTE/dependabot/npm_and_yarn/ajv-6.…
TheDayG0ne Apr 20, 2026
b7fd771
Update package-lock: RN CLI devDep -> latest
TheDayG0ne Apr 20, 2026
0d44c62
Add 9:16 Rustore design images
TheDayG0ne May 25, 2026
b33b62f
Bump BUILD_VER and BUILD_DATE
TheDayG0ne May 25, 2026
e41b179
Update iOS build instructions in README.md
TheDayG0ne May 25, 2026
e7ccf9b
Bump Expo and related packages
TheDayG0ne May 25, 2026
578c7dc
Merge branch 'update-2.3.2' of https://github.com/PRO100BYTE/MyKHSU i…
TheDayG0ne May 25, 2026
88bcd82
Revise iOS build and testing device details in README
TheDayG0ne May 25, 2026
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
56 changes: 41 additions & 15 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,48 @@
# AGENTS.md

## Цель

Единые подробные инструкции для любых ИИ-агентов, которые вносят изменения в репозиторий MyKHSU.

## Область применения
- Любые правки в components/, hooks/, utils/, assets/.

- Любые правки в `components/`, `hooks/`, `utils/`, `assets/`.
- Любые изменения, которые затрагивают расписание, новости, карту, настройки, уведомления.
- Любые исправления багов, рефакторинг и задачи по улучшению UX в рамках текущей архитектуры.
- Любые изменения кода, требующие синхронизации документации в `docs/`.

## Роли

- Исполнитель: делает изменения в коде.
- Ревьюер: проверяет риски, регрессии, edge-cases.
- Верификатор: проверяет запуск и базовую работоспособность.

## Принципы принятия решений

1. Сначала безопасность и корректность.
2. Затем обратная совместимость и стабильность пользовательских сценариев.
3. Затем читаемость и поддерживаемость.
4. Затем минимальность диффа и скорость.

## Протокол работы агента
1. Прочитать запрос и определить затрагиваемые зоны (components, hooks, utils, assets).

1. Прочитать запрос и определить затрагиваемые зоны (`components`, `hooks`, `utils`, `assets`).
2. Проверить связанные файлы перед правкой, чтобы не сломать зависимости.
3. Внести минимальные атомарные изменения.
4. Выполнить базовую локальную проверку.
5. Описать результат, риски и шаги ручной проверки.
4. Обновить релевантные файлы в `docs/` в рамках той же задачи.
5. Выполнить базовую локальную проверку.
6. Описать результат, риски и шаги ручной проверки.

## Обязательная синхронизация docs/

- При любом изменении кода агент обязан обновить документацию в `docs/`.
- Обновляется минимум один релевантный файл в `docs/` по затронутому поведению.
- Обновляются только затронутые разделы, без лишнего переписывания.
- Если изменение не влияет на поведение, архитектуру или данные, это явно фиксируется в отчете.
- Нельзя завершать задачу с код-правкой без проверки актуальности `docs/`.

## Детализированный workflow

1. Уточнить пользовательский эффект: что изменится на экране и в поведении.
2. Найти точку входа изменения и соседние зависимости.
3. Проверить, нет ли уже реализованной похожей логики.
Expand All @@ -37,60 +53,70 @@
8. Подготовить отчет: что сделано, почему, риски, ручные шаги.

## Инварианты проекта

- Экран расписания должен оставаться рабочим и отзывчивым.
- Навигация между ключевыми экранами не должна ломаться.
- Настройки пользователя и локальное хранилище должны сохраняться корректно.
- Ошибки сети должны обрабатываться с понятным fallback-состоянием.

## Дополнительные инварианты
- Приложение должно запускаться без явных ошибок импорта/синтаксиса.

- Приложение должно запускаться без явных ошибок импорта и синтаксиса.
- Пустые, частичные и отсутствующие данные не должны приводить к падению UI.
- Основные пользовательские действия должны быть воспроизводимы после правки.

## Ограничения на изменения
- Не переименовывай файлы и экспортируемые сущности без необходимости.
- Не добавляй тяжелые зависимости без явного запроса.
- Не изменяй формат существующих данных в storage без миграционного плана.
- Не удаляй legacy-ветки логики, пока не проверено, что они не используются.

- Не переименовывать файлы и экспортируемые сущности без необходимости.
- Не добавлять тяжелые зависимости без явного запроса.
- Не изменять формат существующих данных в storage без миграционного плана.
- Не удалять legacy-ветки логики, пока не проверено, что они не используются.

## Обязательные требования к качеству

- Любая новая асинхронная логика должна иметь блок обработки ошибок.
- Любая ветка с внешними данными должна обрабатывать null/undefined/пустые коллекции.
- Любая ветка с внешними данными должна обрабатывать `null`, `undefined` и пустые коллекции.
- Любая правка UI должна учитывать корректное состояние загрузки и ошибки.
- Любая вынесенная утилита должна иметь понятный интерфейс и предсказуемый возврат.

## Стандарты качества

- Код должен быть читаемым и предсказуемым.
- Любая новая ветка логики должна иметь обработку ошибок.
- Избегай глубокой вложенности условий, упрощай через ранние возвраты.
- Для повторяющейся логики используй утилиты и переиспользуемые функции.
- Избегать глубокой вложенности условий, упрощать через ранние возвраты.
- Для повторяющейся логики использовать утилиты и переиспользуемые функции.

## Примеры безопасной стратегии изменений

- Если меняется формат данных для экрана, сначала добавить адаптер совместимости, затем использовать его в одном месте.
- Если изменяется сетевой ответ, обеспечить fallback на кеш или информативное состояние ошибки.
- Если правится логика фильтра, проверять поведение при пустом списке и при единственном элементе.

## Минимальная валидация
- Запуск приложения: npm run start.

- Запуск приложения: `npm run start`.
- Проверка ключевых сценариев вручную:
- открытие расписания;
- переключение форматов/фильтров (если затронуто);
- переключение форматов и фильтров, если затронуто;
- открытие настроек;
- загрузка новостей/данных при сети и без сети.
- загрузка новостей и данных при сети и без сети.

## Рекомендованная расширенная валидация

- Если затронуты уведомления: проверить отсутствие дублирования и корректный тайминг.
- Если затронуты фоновые задачи: убедиться, что нет частых лишних запусков.
- Если затронуты настройки: проверить чтение ранее сохраненных значений.
- Если затронуты ассеты: убедиться, что не нарушены пути и отображение на основных экранах.

## Красные флаги

- Изменение прошло, но причины потенциальной регрессии не проанализированы.
- Логика изменилась сразу в нескольких файлах без четкой необходимости.
- Появились неиспользуемые импорты, временные костыли и отладочные вставки.
- Нет явного описания, как вручную проверить изменение.

## Шаблон отчета агента

- Что сделано.
- Какие файлы изменены.
- Почему решение выбрано.
Expand Down
55 changes: 53 additions & 2 deletions App.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { getBlurConfig } from './utils/liquidGlass';
import * as Sentry from '@sentry/react-native';
import notificationService from './utils/notificationService';
import backgroundService from './utils/backgroundService';
import { hasUnlockedAllAchievements } from './utils/achievements';

Sentry.init({
dsn: 'https://9954c52fe80999a51a6905e3ee180d11@sentry.sculkmetrics.com/5',
Expand Down Expand Up @@ -146,6 +147,7 @@ export default Sentry.wrap(function App() {
const [systemTheme, setSystemTheme] = useState(Appearance.getColorScheme() || 'light');
const [refresh, setRefresh] = useState(0);
const [refreshKey, setRefreshKey] = useState(0);
const [legendUnlocked, setLegendUnlocked] = useState(false);
const insets = useSafeAreaInsets();

// Refs для дочерних экранов (для управления из хедера)
Expand All @@ -158,6 +160,8 @@ export default Sentry.wrap(function App() {
const scheduleExportHandler = useRef(null);
const [scheduleExportAvailable, setScheduleExportAvailable] = useState(false);
const [scheduleExporting, setScheduleExporting] = useState(false);
const scheduleFavoritesHandler = useRef(null);
const [scheduleFavoritesAvailable, setScheduleFavoritesAvailable] = useState(false);
Comment thread
TheDayG0ne marked this conversation as resolved.
const [mapSubScreen, setMapSubScreen] = useState(null);
const [freshmanSubScreen, setFreshmanSubScreen] = useState(null);
const [settingsSubScreen, setSettingsSubScreen] = useState(null);
Expand Down Expand Up @@ -460,9 +464,22 @@ const handleNewYearModeChange = async (enabled) => {
try {
const savedTheme = await SecureStore.getItemAsync('theme');
const savedAccentColor = await SecureStore.getItemAsync('accentColor');
const allUnlocked = await hasUnlockedAllAchievements().catch(() => false);

setLegendUnlocked(allUnlocked);

if (savedTheme) setTheme(savedTheme);
if (savedAccentColor) setAccentColor(savedAccentColor);
if (savedTheme === 'legend' && !allUnlocked) {
setTheme('dark');
await SecureStore.setItemAsync('theme', 'dark');
} else if (savedTheme) {
setTheme(savedTheme);
}
if (savedAccentColor === 'legend' && !allUnlocked) {
setAccentColor('green');
await SecureStore.setItemAsync('accentColor', 'green');
} else if (savedAccentColor) {
setAccentColor(savedAccentColor);
}
} catch (error) {
console.error('Error loading settings:', error);
}
Expand Down Expand Up @@ -504,6 +521,7 @@ const handleNewYearModeChange = async (enabled) => {
accentColor={accentColor}
theme={getEffectiveTheme()}
holidayInfo={holidayInfo}
legendUnlocked={legendUnlocked}
/>;
}

Expand Down Expand Up @@ -687,6 +705,20 @@ const handleNewYearModeChange = async (enabled) => {
</Text>
</TouchableOpacity>
)}
{activeScreen === SCREENS.SCHEDULE && scheduleFavoritesAvailable && (
<TouchableOpacity
onPress={() => scheduleFavoritesHandler.current?.()}
activeOpacity={0.7}
style={{
marginLeft: 8,
padding: 6,
borderRadius: 10,
backgroundColor: colors.glass,
}}
>
<Icon name="star-outline" size={18} color={colors.primary} />
</TouchableOpacity>
)}
{activeScreen === SCREENS.SCHEDULE && scheduleExportAvailable && (
<TouchableOpacity
onPress={() => scheduleExportHandler.current?.()}
Expand Down Expand Up @@ -783,6 +815,20 @@ const handleNewYearModeChange = async (enabled) => {
</Text>
</TouchableOpacity>
)}
{activeScreen === SCREENS.SCHEDULE && scheduleFavoritesAvailable && (
<TouchableOpacity
onPress={() => scheduleFavoritesHandler.current?.()}
activeOpacity={0.7}
style={{
marginLeft: 8,
padding: 6,
borderRadius: 10,
backgroundColor: colors.glass,
}}
>
<Icon name="star-outline" size={18} color={colors.primary} />
</TouchableOpacity>
)}
{activeScreen === SCREENS.SCHEDULE && scheduleExportAvailable && (
<TouchableOpacity
onPress={() => scheduleExportHandler.current?.()}
Expand Down Expand Up @@ -919,6 +965,10 @@ const handleNewYearModeChange = async (enabled) => {
setScheduleExportAvailable(!!handler);
setScheduleExporting(isExporting);
}}
onFavoritesReady={(handler) => {
scheduleFavoritesHandler.current = handler;
setScheduleFavoritesAvailable(!!handler);
}}
/>
)}
{activeScreen === SCREENS.MAP && (
Expand Down Expand Up @@ -959,6 +1009,7 @@ const handleNewYearModeChange = async (enabled) => {
ref={settingsScreenRef}
theme={effectiveTheme}
accentColor={accentColor}
legendUnlocked={legendUnlocked}
setTheme={setTheme}
setAccentColor={setAccentColor}
key={`settings-${refreshKey}`}
Expand Down
Loading
Loading