mirror of
https://github.com/DMOJ/online-judge.git
synced 2024-11-25 16:32:37 +08:00
Use different default ace theme depending on site theme
This commit is contained in:
parent
861fcaaf26
commit
e00396fc2a
@ -76,6 +76,8 @@
|
||||
editor = ace.edit(div),
|
||||
mode = widget.getAttribute('data-mode'),
|
||||
theme = widget.getAttribute('data-theme'),
|
||||
default_light_theme = widget.getAttribute('data-default-light-theme'),
|
||||
default_dark_theme = widget.getAttribute('data-default-dark-theme'),
|
||||
wordwrap = widget.getAttribute('data-wordwrap'),
|
||||
toolbar = prev(widget),
|
||||
main_block = toolbar.parentNode;
|
||||
@ -98,6 +100,21 @@
|
||||
}
|
||||
if (theme) {
|
||||
editor.setTheme("ace/theme/" + theme);
|
||||
} else {
|
||||
if (window.matchMedia) {
|
||||
const setEditorTheme = function (is_dark) {
|
||||
if (is_dark) {
|
||||
editor.setTheme("ace/theme/" + default_dark_theme);
|
||||
} else {
|
||||
editor.setTheme("ace/theme/" + default_light_theme);
|
||||
}
|
||||
}
|
||||
|
||||
setEditorTheme(window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(ev) {
|
||||
setEditorTheme(ev.matches);
|
||||
})
|
||||
}
|
||||
}
|
||||
if (wordwrap == "true") {
|
||||
editor.getSession().setUseWrapMode(true);
|
||||
|
@ -42,6 +42,8 @@ class AceWidget(forms.Textarea):
|
||||
ace_attrs['data-mode'] = self.mode
|
||||
if self.theme:
|
||||
ace_attrs['data-theme'] = self.theme
|
||||
ace_attrs['data-default-light-theme'] = settings.ACE_DEFAULT_LIGHT_THEME
|
||||
ace_attrs['data-default-dark-theme'] = settings.ACE_DEFAULT_DARK_THEME
|
||||
if self.wordwrap:
|
||||
ace_attrs['data-wordwrap'] = 'true'
|
||||
|
||||
|
@ -106,6 +106,11 @@ DMOJ_THEME_CSS = {
|
||||
'light': 'style.css',
|
||||
'dark': 'dark/style.css',
|
||||
}
|
||||
# At the bare minimum, dark and light ace themes must be declared
|
||||
DMOJ_THEME_DEFAULT_ACE_THEME = {
|
||||
'light': 'github',
|
||||
'dark': 'twilight',
|
||||
}
|
||||
DMOJ_SELECT2_THEME = 'dmoj'
|
||||
|
||||
MARKDOWN_STYLES = {}
|
||||
@ -601,3 +606,7 @@ except IOError:
|
||||
|
||||
# Check settings are consistent
|
||||
assert DMOJ_PROBLEM_MIN_USER_POINTS_VOTE >= DMOJ_PROBLEM_MIN_PROBLEM_POINTS
|
||||
|
||||
# Compute these values after local_settings.py is loaded
|
||||
ACE_DEFAULT_LIGHT_THEME = DMOJ_THEME_DEFAULT_ACE_THEME['light']
|
||||
ACE_DEFAULT_DARK_THEME = DMOJ_THEME_DEFAULT_ACE_THEME['dark']
|
||||
|
@ -308,7 +308,9 @@ class ContestAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
if 'problem_label_script' in form.base_fields:
|
||||
# form.base_fields['problem_label_script'] does not exist when the user has only view permission
|
||||
# on the model.
|
||||
form.base_fields['problem_label_script'].widget = AceWidget('lua', request.profile.ace_theme)
|
||||
form.base_fields['problem_label_script'].widget = AceWidget(
|
||||
mode='lua', theme=request.profile.resolved_ace_theme,
|
||||
)
|
||||
|
||||
perms = ('edit_own_contest', 'edit_all_contest')
|
||||
form.base_fields['curators'].queryset = Profile.objects.filter(
|
||||
|
@ -126,5 +126,7 @@ class ProfileAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
form = super(ProfileAdmin, self).get_form(request, obj, **kwargs)
|
||||
if 'user_script' in form.base_fields:
|
||||
# form.base_fields['user_script'] does not exist when the user has only view permission on the model.
|
||||
form.base_fields['user_script'].widget = AceWidget('javascript', request.profile.ace_theme)
|
||||
form.base_fields['user_script'].widget = AceWidget(
|
||||
mode='javascript', theme=request.profile.resolved_ace_theme,
|
||||
)
|
||||
return form
|
||||
|
@ -27,7 +27,9 @@ class LanguageAdmin(VersionAdmin):
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
form = super(LanguageAdmin, self).get_form(request, obj, **kwargs)
|
||||
if obj is not None:
|
||||
form.base_fields['template'].widget = AceWidget(obj.ace, request.profile.ace_theme)
|
||||
form.base_fields['template'].widget = AceWidget(
|
||||
mode=obj.ace, theme=request.profile.resolved_ace_theme,
|
||||
)
|
||||
return form
|
||||
|
||||
|
||||
|
@ -107,8 +107,9 @@ class SubmissionSourceInline(admin.StackedInline):
|
||||
extra = 0
|
||||
|
||||
def get_formset(self, request, obj=None, **kwargs):
|
||||
kwargs.setdefault('widgets', {})['source'] = AceWidget(mode=obj and obj.language.ace,
|
||||
theme=request.profile.ace_theme)
|
||||
kwargs.setdefault('widgets', {})['source'] = AceWidget(
|
||||
mode=obj and obj.language.ace, theme=request.profile.resolved_ace_theme,
|
||||
)
|
||||
return super().get_formset(request, obj, **kwargs)
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ class ProfileForm(ModelForm):
|
||||
)
|
||||
if not self.fields['organizations'].queryset:
|
||||
self.fields.pop('organizations')
|
||||
self.fields['user_script'].widget = AceWidget(theme=user.profile.ace_theme, mode='javascript')
|
||||
self.fields['user_script'].widget = AceWidget(mode='javascript', theme=user.profile.resolved_ace_theme)
|
||||
|
||||
|
||||
class DownloadDataForm(Form):
|
||||
|
29
judge/migrations/0138_dark_ace_theme.py
Normal file
29
judge/migrations/0138_dark_ace_theme.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Generated by Django 3.2.16 on 2023-02-08 01:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def github_to_auto(apps, schema_editor):
|
||||
Profile = apps.get_model('judge', 'Profile')
|
||||
Profile.objects.filter(ace_theme='github').update(ace_theme='auto')
|
||||
|
||||
|
||||
def auto_to_github(apps, schema_editor):
|
||||
Profile = apps.get_model('judge', 'Profile')
|
||||
Profile.objects.filter(ace_theme='auto').update(ace_theme='github')
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0137_profile_site_theme'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='ace_theme',
|
||||
field=models.CharField(choices=[('auto', 'Follow theme default'), ('ambiance', 'Ambiance'), ('chaos', 'Chaos'), ('chrome', 'Chrome'), ('clouds', 'Clouds'), ('clouds_midnight', 'Clouds Midnight'), ('cobalt', 'Cobalt'), ('crimson_editor', 'Crimson Editor'), ('dawn', 'Dawn'), ('dreamweaver', 'Dreamweaver'), ('eclipse', 'Eclipse'), ('github', 'Github'), ('idle_fingers', 'Idle Fingers'), ('katzenmilch', 'Katzenmilch'), ('kr_theme', 'KR Theme'), ('kuroir', 'Kuroir'), ('merbivore', 'Merbivore'), ('merbivore_soft', 'Merbivore Soft'), ('mono_industrial', 'Mono Industrial'), ('monokai', 'Monokai'), ('pastel_on_dark', 'Pastel on Dark'), ('solarized_dark', 'Solarized Dark'), ('solarized_light', 'Solarized Light'), ('terminal', 'Terminal'), ('textmate', 'Textmate'), ('tomorrow', 'Tomorrow'), ('tomorrow_night', 'Tomorrow Night'), ('tomorrow_night_blue', 'Tomorrow Night Blue'), ('tomorrow_night_bright', 'Tomorrow Night Bright'), ('tomorrow_night_eighties', 'Tomorrow Night Eighties'), ('twilight', 'Twilight'), ('vibrant_ink', 'Vibrant Ink'), ('xcode', 'XCode')], default='auto', max_length=30, verbose_name='Ace theme'),
|
||||
),
|
||||
migrations.RunPython(github_to_auto, auto_to_github, atomic=True),
|
||||
]
|
@ -21,6 +21,7 @@ TIMEZONE = make_timezones()
|
||||
del make_timezones
|
||||
|
||||
ACE_THEMES = (
|
||||
('auto', _('Follow theme default')),
|
||||
('ambiance', 'Ambiance'),
|
||||
('chaos', 'Chaos'),
|
||||
('chrome', 'Chrome'),
|
||||
|
@ -154,7 +154,7 @@ class Profile(models.Model):
|
||||
points = models.FloatField(default=0, db_index=True)
|
||||
performance_points = models.FloatField(default=0, db_index=True)
|
||||
problem_count = models.IntegerField(default=0, db_index=True)
|
||||
ace_theme = models.CharField(max_length=30, verbose_name=_('Ace theme'), choices=ACE_THEMES, default='github')
|
||||
ace_theme = models.CharField(max_length=30, verbose_name=_('Ace theme'), choices=ACE_THEMES, default='auto')
|
||||
site_theme = models.CharField(max_length=10, verbose_name=_('site theme'), choices=SITE_THEMES, default='auto')
|
||||
last_access = models.DateTimeField(verbose_name=_('last access time'), default=now)
|
||||
ip = models.GenericIPAddressField(verbose_name=_('last IP'), blank=True, null=True)
|
||||
@ -226,6 +226,15 @@ class Profile(models.Model):
|
||||
def has_any_solves(self):
|
||||
return self.submission_set.filter(result='AC', case_points__gte=F('case_total')).exists()
|
||||
|
||||
@cached_property
|
||||
def resolved_ace_theme(self):
|
||||
if self.ace_theme != 'auto':
|
||||
return self.ace_theme
|
||||
if self.site_theme != 'auto':
|
||||
return settings.DMOJ_THEME_DEFAULT_ACE_THEME.get(self.site_theme)
|
||||
# This must be resolved client-side using prefers-color-scheme.
|
||||
return None
|
||||
|
||||
_pp_table = [pow(settings.DMOJ_PP_STEP, i) for i in range(settings.DMOJ_PP_ENTRIES)]
|
||||
|
||||
def calculate_points(self, table=_pp_table):
|
||||
|
@ -691,7 +691,7 @@ class ProblemSubmit(LoginRequiredMixin, ProblemMixin, TitleMixin, SingleObjectFo
|
||||
form_data = getattr(form, 'cleaned_data', form.initial)
|
||||
if 'language' in form_data:
|
||||
form.fields['source'].widget.mode = form_data['language'].ace
|
||||
form.fields['source'].widget.theme = self.request.profile.ace_theme
|
||||
form.fields['source'].widget.theme = self.request.profile.resolved_ace_theme
|
||||
|
||||
return form
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user