mirror of https://github.com/iSoron/uhabits.git
parent
b6ed33b1e6
commit
a060cbe578
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.ui.habits.show.views;
|
||||
|
||||
import android.content.*;
|
||||
import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import butterknife.*;
|
||||
|
||||
public class OverviewCardView extends LinearLayout
|
||||
implements ModelObservable.Listener
|
||||
{
|
||||
@Nullable
|
||||
private Habit habit;
|
||||
|
||||
@NonNull
|
||||
private Cache cache;
|
||||
|
||||
@BindView(R.id.scoreRing)
|
||||
RingView scoreRing;
|
||||
|
||||
@BindView(R.id.scoreLabel)
|
||||
TextView scoreLabel;
|
||||
|
||||
@BindView(R.id.monthDiffLabel)
|
||||
TextView monthDiffLabel;
|
||||
|
||||
@BindView(R.id.yearDiffLabel)
|
||||
TextView yearDiffLabel;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
private int color;
|
||||
|
||||
public OverviewCardView(Context context)
|
||||
{
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public OverviewCardView(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModelChange()
|
||||
{
|
||||
refreshCache();
|
||||
}
|
||||
|
||||
public void setHabit(@Nullable Habit habit)
|
||||
{
|
||||
this.habit = habit;
|
||||
color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow()
|
||||
{
|
||||
super.onAttachedToWindow();
|
||||
refreshCache();
|
||||
if(habit != null) habit.getObservable().addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow()
|
||||
{
|
||||
if(habit != null) habit.getObservable().removeListener(this);
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
inflate(getContext(), R.layout.show_habit_overview, this);
|
||||
ButterKnife.bind(this);
|
||||
cache = new Cache();
|
||||
|
||||
if(isInEditMode()) initEditMode();
|
||||
}
|
||||
|
||||
private void initEditMode()
|
||||
{
|
||||
color = ColorUtils.getAndroidTestColor(1);
|
||||
cache.todayScore = Score.MAX_VALUE * 0.6f;
|
||||
cache.lastMonthScore = Score.MAX_VALUE * 0.42f;
|
||||
cache.lastYearScore = Score.MAX_VALUE * 0.75f;
|
||||
updateScore();
|
||||
}
|
||||
|
||||
private void refreshCache()
|
||||
{
|
||||
new BaseTask()
|
||||
{
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
{
|
||||
if(habit == null) return;
|
||||
ScoreList scores = habit.getScores();
|
||||
|
||||
|
||||
long today = DateUtils.getStartOfToday();
|
||||
long lastMonth = today - 30 * DateUtils.millisecondsInOneDay;
|
||||
long lastYear = today - 365 * DateUtils.millisecondsInOneDay;
|
||||
|
||||
cache.todayScore = (float) scores.getTodayValue();
|
||||
cache.lastMonthScore = (float) scores.getValue(lastMonth);
|
||||
cache.lastYearScore = (float) scores.getValue(lastYear);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
{
|
||||
updateScore();
|
||||
super.onPostExecute(aVoid);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
void updateScore()
|
||||
{
|
||||
float todayPercentage = cache.todayScore / Score.MAX_VALUE;
|
||||
float monthDiff = todayPercentage - (cache.lastMonthScore / Score.MAX_VALUE);
|
||||
float yearDiff = todayPercentage - (cache.lastYearScore / Score.MAX_VALUE);
|
||||
|
||||
scoreRing.setColor(color);
|
||||
scoreRing.setPercentage(todayPercentage);
|
||||
|
||||
scoreLabel.setTextColor(color);
|
||||
scoreLabel.setText(String.format("%.0f%%", todayPercentage * 100));
|
||||
|
||||
title.setTextColor(color);
|
||||
|
||||
monthDiffLabel.setText(formatPercentageDiff(monthDiff));
|
||||
yearDiffLabel.setText(formatPercentageDiff(yearDiff));
|
||||
|
||||
int inactiveColor = InterfaceUtils.getStyledColor(getContext(),
|
||||
R.attr.mediumContrastTextColor);
|
||||
|
||||
monthDiffLabel.setTextColor(monthDiff >= 0 ? color : inactiveColor);
|
||||
yearDiffLabel.setTextColor(yearDiff >= 0 ? color : inactiveColor);
|
||||
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
private String formatPercentageDiff(float percentageDiff)
|
||||
{
|
||||
return String.format("%s%.0f%%", (percentageDiff >= 0 ? "+" : "\u2212"),
|
||||
Math.abs(percentageDiff) * 100);
|
||||
}
|
||||
|
||||
private class Cache
|
||||
{
|
||||
public float todayScore;
|
||||
|
||||
public float lastMonthScore;
|
||||
|
||||
public float lastYearScore;
|
||||
}
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.ui.habits.show.views;
|
||||
|
||||
import android.annotation.*;
|
||||
import android.content.*;
|
||||
import android.content.res.*;
|
||||
import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import butterknife.*;
|
||||
|
||||
public class SubtitleCardView extends LinearLayout
|
||||
implements ModelObservable.Listener
|
||||
{
|
||||
@BindView(R.id.questionLabel)
|
||||
TextView questionLabel;
|
||||
|
||||
@BindView(R.id.frequencyLabel)
|
||||
TextView frequencyLabel;
|
||||
|
||||
@BindView(R.id.reminderLabel)
|
||||
TextView reminderLabel;
|
||||
|
||||
@Nullable
|
||||
private Habit habit;
|
||||
|
||||
public SubtitleCardView(Context context)
|
||||
{
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public SubtitleCardView(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModelChange()
|
||||
{
|
||||
refreshData();
|
||||
}
|
||||
|
||||
public void setHabit(@Nullable Habit habit)
|
||||
{
|
||||
this.habit = habit;
|
||||
refreshData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow()
|
||||
{
|
||||
super.onAttachedToWindow();
|
||||
if (habit != null) habit.getObservable().addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow()
|
||||
{
|
||||
if (habit != null) habit.getObservable().removeListener(this);
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
Context context = getContext();
|
||||
inflate(context, R.layout.show_habit_subtitle, this);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
if (isInEditMode()) initEditMode();
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void initEditMode()
|
||||
{
|
||||
questionLabel.setTextColor(ColorUtils.getAndroidTestColor(1));
|
||||
questionLabel.setText("Have you meditated today?");
|
||||
reminderLabel.setText("08:00");
|
||||
}
|
||||
|
||||
private void refreshData()
|
||||
{
|
||||
if (habit == null) return;
|
||||
int color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
|
||||
reminderLabel.setText(getResources().getString(R.string.reminder_off));
|
||||
questionLabel.setVisibility(VISIBLE);
|
||||
|
||||
questionLabel.setTextColor(color);
|
||||
questionLabel.setText(habit.getDescription());
|
||||
frequencyLabel.setText(toText(habit.getFrequency()));
|
||||
|
||||
if (habit.hasReminder()) updateReminderText(habit.getReminder());
|
||||
|
||||
if (habit.getDescription().isEmpty())
|
||||
questionLabel.setVisibility(View.GONE);
|
||||
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
String toText(Frequency freq)
|
||||
{
|
||||
Resources resources = getResources();
|
||||
Integer num = freq.getNumerator();
|
||||
Integer den = freq.getDenominator();
|
||||
|
||||
if (num.equals(den)) return resources.getString(R.string.every_day);
|
||||
|
||||
if (num == 1)
|
||||
{
|
||||
if (den == 7) return resources.getString(R.string.every_week);
|
||||
if (den % 7 == 0)
|
||||
return resources.getString(R.string.every_x_weeks, den / 7);
|
||||
return resources.getString(R.string.every_x_days, den);
|
||||
}
|
||||
|
||||
String times_every = resources.getString(R.string.times_every);
|
||||
return String.format("%d %s %d %s", num, times_every, den,
|
||||
resources.getString(R.string.days));
|
||||
}
|
||||
|
||||
private void updateReminderText(Reminder reminder)
|
||||
{
|
||||
reminderLabel.setText(
|
||||
DateUtils.formatTime(getContext(), reminder.getHour(),
|
||||
reminder.getMinute()));
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
~
|
||||
~ This file is part of Loop Habit Tracker.
|
||||
~
|
||||
~ Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by the
|
||||
~ Free Software Foundation, either version 3 of the License, or (at your
|
||||
~ option) any later version.
|
||||
~
|
||||
~ Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
~ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
~ more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along
|
||||
~ with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:habit="http://isoron.org/android">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="@style/CardHeader"
|
||||
android:text="@string/overview"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llOverview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="5">
|
||||
|
||||
<org.isoron.uhabits.ui.habits.show.views.RingView
|
||||
android:id="@+id/scoreRing"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
habit:percentage="0"
|
||||
habit:textSize="12"
|
||||
habit:thickness="5"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="4"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scoreLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/score"
|
||||
android:textColor="?mediumContrastTextColor"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="4"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/monthDiffLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/month"
|
||||
android:textColor="?mediumContrastTextColor"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="4"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yearDiffLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/year"
|
||||
android:textColor="?mediumContrastTextColor"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</merge>
|
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
~
|
||||
~ This file is part of Loop Habit Tracker.
|
||||
~
|
||||
~ Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by the
|
||||
~ Free Software Foundation, either version 3 of the License, or (at your
|
||||
~ option) any later version.
|
||||
~
|
||||
~ Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
~ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
~ more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along
|
||||
~ with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?windowBackgroundColor"
|
||||
android:clipToPadding="false"
|
||||
android:fillViewport="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
style="@style/Toolbar"
|
||||
app:title="Meditation"
|
||||
android:background="@color/deep_orange_700"
|
||||
app:popupTheme="?toolbarPopupTheme"
|
||||
android:elevation="1dp"/>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/CardList"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<org.isoron.uhabits.ui.habits.show.views.SubtitleCardView
|
||||
android:id="@+id/subtitleView"
|
||||
style="@style/ShowHabit.Subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<org.isoron.uhabits.ui.habits.show.views.OverviewCardView
|
||||
android:paddingTop="12dp"
|
||||
style="@style/Card" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
~
|
||||
~ This file is part of Loop Habit Tracker.
|
||||
~
|
||||
~ Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by the
|
||||
~ Free Software Foundation, either version 3 of the License, or (at your
|
||||
~ option) any later version.
|
||||
~
|
||||
~ Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
~ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
~ more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along
|
||||
~ with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<TextView
|
||||
android:id="@+id/questionLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textColor="?mediumContrastTextColor"
|
||||
android:textSize="@dimen/regularTextSize"
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/frequencyIcon"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:alpha="0.3"
|
||||
android:src="?iconFrequency"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/frequencyLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/every_day"
|
||||
android:textColor="?mediumContrastTextColor"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/reminderIcon"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:alpha="0.3"
|
||||
android:src="?iconReminder"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reminderLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="1dp"
|
||||
android:textColor="?mediumContrastTextColor"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
</merge>
|
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
~
|
||||
~ This file is part of Loop Habit Tracker.
|
||||
~
|
||||
~ Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by the
|
||||
~ Free Software Foundation, either version 3 of the License, or (at your
|
||||
~ option) any later version.
|
||||
~
|
||||
~ Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
~ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
~ more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along
|
||||
~ with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<style name="ShowHabit" />
|
||||
|
||||
<style name="ShowHabit.Subtitle">
|
||||
<item name="android:background">?headerBackgroundColor</item>
|
||||
<item name="android:orientation">vertical</item>
|
||||
<item name="android:elevation">2dp</item>
|
||||
<item name="android:paddingBottom">10dp</item>
|
||||
<item name="android:paddingEnd">10dp</item>
|
||||
<item name="android:paddingLeft">60dp</item>
|
||||
<item name="android:paddingRight">10dp</item>
|
||||
<item name="android:paddingStart">60dp</item>
|
||||
<item name="android:paddingTop">15dp</item>
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in new issue