{% import '_icons.html' as icons %} {% if course %}{{ course.name }} - OfflineU{% else %}OfflineU{% endif %}

OfflineU

Your self-hosted course library

{% if course %}
{{ course.name }}
{% elif library_stats and library_stats.total_courses %} {{ icons.icon('dice', 20) }} {% endif %}
{% if course %}

{{ course.name }}

{% if resume_lesson %} ▶ Resume: {{ resume_lesson.title }} {% endif %}
{{ stats.completed_lessons }}/{{ stats.total_lessons }} lessons completed
{{ "%.1f"|format(stats.completion_percentage) }}%
{% if stats.remaining_display %}
~{{ stats.remaining_display }} remaining
{% endif %}
{% if stats.total_lessons %}
{% if has_note %} {{ icons.icon('file-text', 14) }} Download Study Guide {% endif %}
{% endif %} {% if stats.last_accessed_path %}
Last Accessed: {{ stats.last_accessed_path }} Continue
{% endif %}
{% macro render_tree_node(node, depth=0) %} {% set stats = section_stats(node) %}
{{ icons.icon('folder', 16) }} {{ node.name }} {% if stats.total_lessons %}{{ stats.completed_lessons }}/{{ stats.total_lessons }} watched{% else %}Empty{% endif %}
{% if node.children or node.lessons %} {% endif %}
{% if node.children or node.lessons %}
{% for child_name, child_node in node.children.items() %} {{ render_tree_node(child_node, depth + 1) }} {% endfor %} {% for lesson in node.lessons %} {% set lesson_relative_path = lesson.path|replace('\\', '/')|replace(course.path|replace('\\', '/'), '')|replace('//', '/')|replace('/', '', 1) %} {% set percent_watched = 100 if lesson.completed else (((100 * lesson.progress_seconds / lesson.duration_seconds)|round|int) if (lesson.duration_seconds and lesson.progress_seconds) else 0) %}
{% if lesson.lesson_type == 'video' %}{{ icons.icon('video', 16) }} {% elif lesson.lesson_type == 'audio' %}{{ icons.icon('music', 16) }} {% elif lesson.lesson_type == 'quiz' %}{{ icons.icon('clipboard', 16) }} {% elif lesson.lesson_type == 'mixed' %}{{ icons.icon('package', 16) }} {% else %}{{ icons.icon('file-text', 16) }}{% endif %} {{ lesson.title }}
{{ lesson.lesson_type|title }} {% if lesson.duration_seconds and lesson.duration_seconds >= 60 %} {{ lesson.duration_seconds|format_duration }} {% endif %} {% if lesson.completed %} {{ icons.icon('check', 14) }} {% elif percent_watched %} {{ percent_watched }}% watched {% else %} {{ icons.icon('circle', 14) }} {% endif %}
{% if percent_watched %}
{% endif %}
{% endfor %}
{% endif %}
{% endmacro %} {{ render_tree_node(course.root_node) }}
{% else %} {% macro render_view_row(view) %}
{% if view.has_thumbnail %} {% else %} {{ icons.icon('play', 16) }} {% endif %} {{ view.lesson_title }}
{% if view.completed %} {{ icons.icon('check', 14) }} {% elif view.percent_watched %} {{ view.percent_watched }}% watched {% endif %} {{ view.course_name }}{% if view.viewed_display %} · {{ view.viewed_display }}{% endif %}
{% if view.percent_watched %}
{% endif %}
{% endmacro %} {% macro render_course_row(item, meta_text) %}
{% if item.has_thumbnail %} {% else %} {{ icons.icon('graduation-cap', 16) }} {% endif %} {{ item.name }}
{{ meta_text }}
{% endmacro %}

{{ icons.icon('grid') }}Your Courses

{% if library_stats and library_stats.total_courses %}

{{ icons.icon('bar-chart') }}Library Stats

{{ library_stats.total_courses }}
Courses
{{ library_stats.completed_lessons }}/{{ library_stats.lessons_tracked }}
Lessons completed
{{ library_stats.watched_display }}
Watched
{% if library_stats.remaining_display %}
{{ library_stats.remaining_display }}
Remaining
{% endif %}
{{ library_stats.streak_days }}
Day streak
{% if activity_heatmap %}
{% for week in activity_heatmap|batch(7) %}
{% for day in week %} {% set level = 0 if day.count == 0 else (1 if day.count == 1 else (2 if day.count == 2 else 3)) %}
{% endfor %}
{% endfor %}
{% endif %}
{% endif %} {% if next_up %}

{{ icons.icon('list-dots') }}Next Up

{% for item in next_up %}
{% if item.has_thumbnail %} {% else %} {{ icons.icon('graduation-cap', 16) }} {% endif %} {{ item.name }}
{% endfor %}
{% endif %} {% if stale_courses %}

{{ icons.icon('history') }}Pick Back Up

{% for item in stale_courses %} {{ render_course_row(item, 'Last touched ' + item.last_touched_display) }} {% endfor %}
{% endif %} {% if recently_added %}

{{ icons.icon('plus-circle') }}Recently Added

{% for item in recently_added %} {{ render_course_row(item, item.added_display) }} {% endfor %}
{% endif %} {% if recent_views %}

{{ icons.icon('play-circle') }}Recently Viewed

{% for view in recent_views %} {{ render_view_row(view) }} {% endfor %}
{% endif %} {% endif %}