summaryrefslogtreecommitdiffstats
path: root/templates/part.settings.php
blob: fbb2a5b1964b410fec458efcbddb01f08343bcc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<div id="app-settings-header">
    <button name="app settings"
            class="settings-button"
            data-apps-slide-toggle="#app-settings-content">
        <?php p($l->t('Settings')); ?>
    </button>
</div>

<div id="app-settings-content">
    <h3><?php p($l->t('Settings')); ?></h3>

    <fieldset class="settings-fieldset">
        <ul class="settings-fieldset-interior">
            <li class="settings-fieldset-interior-item">
                <input type="checkbox"
                       class="checkbox"
                       ng-click="Settings.toggleSetting('preventReadOnScroll')"
                       ng-checked="Settings.getSetting('preventReadOnScroll')"
                       name="preventReadOnScroll"
                       id="settings-preventReadOnScroll">
                <label for="settings-preventReadOnScroll"><?php p($l->t('Disable mark read through scrolling')); ?></label>
            </li>
            <li class="settings-fieldset-interior-item">
                <input type="checkbox"
                       class="checkbox"
                       ng-click="Settings.toggleSetting('compact')"
                       ng-checked="Settings.getSetting('compact')"
                       name="compact"
                       id="settings-compact">
                <label for="settings-compact"><?php p($l->t('Compact view')); ?></label>
            </li>
            <li class="settings-fieldset-interior-item" ng-show="Settings.getSetting('compact')">
                <input type="checkbox"
                       class="checkbox"
                       ng-click="Settings.toggleSetting('compactExpand')"
                       ng-checked="Settings.getSetting('compactExpand')"
                       name="compactExpand"
                       id="settings-compactExpand">
                <label for="settings-compactExpand"><?php p($l->t('Expand articles on key navigation')); ?></label>
            </li>
            <li class="settings-fieldset-interior-item">
                <input type="checkbox"
                       class="checkbox"
                       ng-click="Settings.toggleSetting('showAll')"
                       ng-checked="Settings.getSetting('showAll')"
                       name="showAll"
                       id="settings-showAll">
                <label for="settings-showAll"><?php p($l->t('Show all articles')); ?></label>
            </li>
            <li class="settings-fieldset-interior-item">
                <input type="checkbox"
                       class="checkbox"
                       ng-click="Settings.toggleSetting('oldestFirst')"
                       ng-checked="Settings.getSetting('oldestFirst')"
                       name="oldestFirst"
                       id="settings-oldestFirst">
                <label for="settings-oldestFirst"><?php p($l->t('Reverse ordering (oldest on top)')); ?></label>
            </li>
        </ul>
    </fieldset>

    <div class="import-export">
        <h3><?php p($l->t('Subscriptions (OPML)')); ?></h3>

        <input type="file"
               id="opml-upload"
               name="import"
               news-read-file="Settings.importOPML($fileContent)"/>

        <button title="<?php p($l->t('Import')); ?>"
                class="icon-upload svg button-icon-label"
                news-trigger-click="#opml-upload"
                ng-class="{'entry-loading': Settings.isOPMLImporting}"
                ng-disabled=
                "Settings.isOPMLImporting || Settings.isArticlesImporting">
        </button>

        <a title="<?php p($l->t('Export')); ?>"
           class="button icon-download svg button-icon-label"
           href="<?php p($_['url_generator']->linkToRoute('news.export.opml')); ?>"
           target="_blank"
           rel="noreferrer"
           ng-hide="App.isFirstRun()">
        </a>

        <button
            class="icon-download svg button-icon-label"
            title="<?php p($l->t('Export')); ?>"
            ng-show="App.isFirstRun()"
            disabled>
        </button>

        <p class="error" ng-show="Settings.opmlImportError">
            <?php p(
                $l->t('Error when importing: file does not contain valid OPML')
            ); ?>
        </p>
        <p class="error" ng-show="Settings.opmlImportEmptyError">
            <?php p(
                $l->t('Error when importing: OPML is does neither contain ' .
                    'feeds nor folders')
            ); ?>
        </p>

        <h3><?php p($l->t('Unread/Starred Articles')); ?></h3>

        <input
            type="file"
            id="article-upload"
            name="importarticle"
            news-read-file="Settings.importArticles($fileContent)"/>

        <button title="<?php p($l->t('Import')); ?>"
                class="icon-upload svg button-icon-label"
                ng-class="{'entry-loading': Settings.isArticlesImporting}"
                ng-disabled="Settings.isOPMLImporting || Settings.isArticlesImporting"
                news-trigger-click="#article-upload">
        </button>

        <a title="<?php p($l->t('Export')); ?>"
           class="button icon-download svg button-icon-label"
           href="<?php p($_['url_generator']->linkToRoute('news.export.articles')); ?>"
           target="_blank"
           rel="noreferrer"
           ng-hide="App.isFirstRun()">
        </a>
        <button
            class="icon-download svg button-icon-label"
            title="<?php p($l->t('Export')); ?>"
            ng-show="App.isFirstRun()"
            disabled>
        </button>

        <p class="error" ng-show="Settings.articleImportError">
            <?php p(
                $l->t('Error when importing: file does not contain valid JSON')
            ); ?>
        </p>

    </div>

    <h3><?php p($l->t('Help')); ?></h3>

    <p>
        <a href="#/shortcuts/"><?php p($l->t('Keyboard shortcuts')); ?></a>
    </p>

    <p>
        <a target="_blank"
           rel="noreferrer"
           href="https://github.com/nextcloud/news/tree/master/docs"><?php p($l->t('Documentation')); ?></a>
    </p>
    <p>
        <a target="_blank"
           rel="noreferrer"
           href="https://github.com/nextcloud/news/issues/new"><?php p($l->t('Report a bug')); ?></a>
    </p>

</div>
ret = true; } mutex_unlock(&vmpr->events_lock); return ret; } static void vmpressure_work_fn(struct work_struct *work) { struct vmpressure *vmpr = work_to_vmpressure(work); unsigned long scanned; unsigned long reclaimed; enum vmpressure_levels level; bool ancestor = false; bool signalled = false; spin_lock(&vmpr->sr_lock); /* * Several contexts might be calling vmpressure(), so it is * possible that the work was rescheduled again before the old * work context cleared the counters. In that case we will run * just after the old work returns, but then scanned might be zero * here. No need for any locks here since we don't care if * vmpr->reclaimed is in sync. */ scanned = vmpr->tree_scanned; if (!scanned) { spin_unlock(&vmpr->sr_lock); return; } reclaimed = vmpr->tree_reclaimed; vmpr->tree_scanned = 0; vmpr->tree_reclaimed = 0; spin_unlock(&vmpr->sr_lock); level = vmpressure_calc_level(scanned, reclaimed); do { if (vmpressure_event(vmpr, level, ancestor, signalled)) signalled = true; ancestor = true; } while ((vmpr = vmpressure_parent(vmpr))); } /** * vmpressure() - Account memory pressure through scanned/reclaimed ratio * @gfp: reclaimer's gfp mask * @memcg: cgroup memory controller handle * @tree: legacy subtree mode * @scanned: number of pages scanned * @reclaimed: number of pages reclaimed * * This function should be called from the vmscan reclaim path to account * "instantaneous" memory pressure (scanned/reclaimed ratio). The raw * pressure index is then further refined and averaged over time. * * If @tree is set, vmpressure is in traditional userspace reporting * mode: @memcg is considered the pressure root and userspace is * notified of the entire subtree's reclaim efficiency. * * If @tree is not set, reclaim efficiency is recorded for @memcg, and * only in-kernel users are notified. * * This function does not return any value. */ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed) { struct vmpressure *vmpr = memcg_to_vmpressure(memcg); /* * Here we only want to account pressure that userland is able to * help us with. For example, suppose that DMA zone is under * pressure; if we notify userland about that kind of pressure, * then it will be mostly a waste as it will trigger unnecessary * freeing of memory by userland (since userland is more likely to * have HIGHMEM/MOVABLE pages instead of the DMA fallback). That * is why we include only movable, highmem and FS/IO pages. * Indirect reclaim (kswapd) sets sc->gfp_mask to GFP_KERNEL, so * we account it too. */ if (!(gfp & (__GFP_HIGHMEM | __GFP_MOVABLE | __GFP_IO | __GFP_FS))) return; /* * If we got here with no pages scanned, then that is an indicator * that reclaimer was unable to find any shrinkable LRUs at the * current scanning depth. But it does not mean that we should * report the critical pressure, yet. If the scanning priority * (scanning depth) goes too high (deep), we will be notified * through vmpressure_prio(). But so far, keep calm. */ if (!scanned) return; if (tree) { spin_lock(&vmpr->sr_lock); scanned = vmpr->tree_scanned += scanned; vmpr->tree_reclaimed += reclaimed; spin_unlock(&vmpr->sr_lock); if (scanned < vmpressure_win) return; schedule_work(&vmpr->work); } else { enum vmpressure_levels level; /* For now, no users for root-level efficiency */ if (!memcg || memcg == root_mem_cgroup) return; spin_lock(&vmpr->sr_lock); scanned = vmpr->scanned += scanned; reclaimed = vmpr->reclaimed += reclaimed; if (scanned < vmpressure_win) { spin_unlock(&vmpr->sr_lock); return; } vmpr->scanned = vmpr->reclaimed = 0; spin_unlock(&vmpr->sr_lock); level = vmpressure_calc_level(scanned, reclaimed); if (level > VMPRESSURE_LOW) { /* * Let the socket buffer allocator know that * we are having trouble reclaiming LRU pages. * * For hysteresis keep the pressure state * asserted for a second in which subsequent * pressure events can occur. */ memcg->socket_pressure = jiffies + HZ; } } }