Changeset df95e29


Ignore:
Timestamp:
Oct 25, 2017 9:35:51 AM (3 years ago)
Author:
str4d <str4d@…>
Branches:
master
Children:
da9c06e
Parents:
47d3547
Message:

I2PSnark UI bugfixes

  • Fix broken collapsible panels issue for browsers that don't support the feature by conditionally loading override CSS to expand panels by default and disable hover/active states for panel headings (tickets #2002, #2026)
  • Add UI option to configuration section to enable collapsible panels, and disable the option if a non-compliant browser is detected
  • Fix multiple instances of snark refreshing to the homepage (ticket #2028) (patch supplied by mindless)
  • Tentative fix for caching of images so ajax refresh doesn't reload all image resources
  • Standardize 'Save Configuration' action to return to top of the page (so we can see message log entry)
Files:
6 added
8 edited

Legend:

Unmodified
Added
Removed
  • apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java

    r47d3547 rdf95e29  
    6666    private final File _tmpDir;
    6767    private int _startupDelay;
     68    private boolean _collapsePanels;
    6869    private boolean _shouldUseOT;
    6970    private boolean _shouldUseDHT;
     
    7879    private static final int EEPGET_CONNECT_TIMEOUT_SHORT = 5*1000;
    7980    public static final int DEFAULT_STARTUP_DELAY = 3;
     81    public static final boolean DEFAULT_COLLAPSE_PANELS = true;
    8082    public static final boolean DEFAULT_USE_OPENTRACKERS = true;
    8183    public static final int MAX_CONNECTIONS = 24; // per torrent
     
    107109        _openTrackers = Collections.emptyList();
    108110        _shouldUseDHT = DEFAULT_USE_DHT;
     111        _collapsePanels = DEFAULT_COLLAPSE_PANELS;
    109112        _enableRatings = _enableComments = true;
    110113        _commentsName = "";
     
    688691    }
    689692
     693    /** @since 0.9.32 */
     694    public boolean collapsePanels() {
     695        return _collapsePanels;
     696    }
     697
     698    /** @since 0.9.32 */
     699    public void setCollapsePanels(boolean yes) {
     700        _collapsePanels = yes;
     701    }
     702
    690703    /**
    691704     *  Like DataHelper.toHexString but ensures no loss of leading zero bytes
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    r47d3547 rdf95e29  
    132132    public static final String PROP_THEME = "i2psnark.theme";
    133133    public static final String DEFAULT_THEME = "ubergine";
     134    /** @since 0.9.32 */
     135    public static final String PROP_COLLAPSE_PANELS = "i2psnark.collapsePanels";
    134136    private static final String PROP_USE_OPENTRACKERS = "i2psnark.useOpentrackers";
    135137    public static final String PROP_OPENTRACKERS = "i2psnark.opentrackers";
     
    452454        if (val == null)
    453455            return true;
     456        return Boolean.parseBoolean(val);
     457    }
     458
     459    /**
     460     *  @return default true
     461     *  @since 0.9.32
     462     */
     463    public boolean isCollapsePanelsEnabled() {
     464        String val = _config.getProperty(PROP_COLLAPSE_PANELS);
     465        if (val == null)
     466            return I2PSnarkUtil.DEFAULT_COLLAPSE_PANELS;
    454467        return Boolean.parseBoolean(val);
    455468    }
     
    799812        if (!_config.containsKey(PROP_COMMENTS_NAME))
    800813            _config.setProperty(PROP_COMMENTS_NAME, "");
     814        if (!_config.containsKey(PROP_COLLAPSE_PANELS))
     815            _config.setProperty(PROP_COLLAPSE_PANELS,
     816                                Boolean.toString(I2PSnarkUtil.DEFAULT_COLLAPSE_PANELS));
    801817        updateConfig();
    802818    }
     
    872888        }
    873889    }
    874    
     890
    875891    private void updateConfig() {
    876892        String i2cpHost = _config.getProperty(PROP_I2CP_HOST);
     
    909925        _util.setCommentsEnabled(Boolean.parseBoolean(_config.getProperty(PROP_COMMENTS, "true")));
    910926        _util.setCommentsName(_config.getProperty(PROP_COMMENTS_NAME, ""));
     927        _util.setCollapsePanels(Boolean.parseBoolean(_config.getProperty(PROP_COLLAPSE_PANELS,
     928                                          Boolean.toString(I2PSnarkUtil.DEFAULT_COLLAPSE_PANELS))));
    911929        File dd = getDataDir();
    912930        if (dd.isDirectory()) {
     
    919937        initTrackerMap();
    920938    }
    921    
     939
    922940    private int getInt(String prop, int defaultVal) {
    923941        String p = _config.getProperty(prop);
     
    930948        return defaultVal;
    931949    }
    932    
     950
    933951    /**
    934952     *  all params may be null or need trimming
    935953     */
    936954    public void updateConfig(String dataDir, boolean filesPublic, boolean autoStart, boolean smartSort, String refreshDelay,
    937                              String startDelay, String pageSize, String seedPct, String eepHost, 
     955                             String startDelay, String pageSize, String seedPct, String eepHost,
    938956                             String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
    939957                             String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme,
    940                              String lang, boolean enableRatings, boolean enableComments, String commentName) {
     958                             String lang, boolean enableRatings, boolean enableComments, String commentName, boolean collapsePanels) {
    941959        synchronized(_configLock) {
    942             locked_updateConfig(dataDir, filesPublic, autoStart, smartSort,refreshDelay,
    943                                 startDelay,  pageSize,  seedPct,  eepHost,
    944                                 eepPort,  i2cpHost,  i2cpPort, i2cpOpts,
    945                                 upLimit,  upBW, useOpenTrackers, useDHT, theme,
    946                                 lang, enableRatings, enableComments, commentName);
     960            locked_updateConfig(dataDir, filesPublic, autoStart, smartSort, refreshDelay,
     961                                startDelay, pageSize, seedPct, eepHost,
     962                                eepPort, i2cpHost, i2cpPort, i2cpOpts,
     963                                upLimit, upBW, useOpenTrackers, useDHT, theme,
     964                                lang, enableRatings, enableComments, commentName, collapsePanels);
    947965        }
    948966    }
    949967
    950968    private void locked_updateConfig(String dataDir, boolean filesPublic, boolean autoStart, boolean smartSort, String refreshDelay,
    951                              String startDelay, String pageSize, String seedPct, String eepHost, 
     969                             String startDelay, String pageSize, String seedPct, String eepHost,
    952970                             String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
    953971                             String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme,
    954                              String lang, boolean enableRatings, boolean enableComments, String commentName) {
     972                             String lang, boolean enableRatings, boolean enableComments, String commentName, boolean collapsePanels) {
    955973        boolean changed = false;
    956974        boolean interruptMonitor = false;
     
    9971015            }
    9981016        }
    999        
     1017
    10001018        if (startDelay != null && _context.isRouterContext()) {
    10011019                int minutes = _util.getStartupDelay();
     
    11161134                    oldOpts.put(pair.substring(0, split), pair.substring(split+1));
    11171135            }
    1118            
     1136
    11191137            boolean reconnect = i2cpHost != null && i2cpHost.trim().length() > 0 && port > 0 &&
    11201138                                (port != _util.getI2CPPort() || !oldI2CPHost.equals(i2cpHost));
     
    12631281            }
    12641282        }
     1283        if (_util.collapsePanels() != collapsePanels) {
     1284            _config.setProperty(PROP_COLLAPSE_PANELS, Boolean.toString(collapsePanels));
     1285            if (collapsePanels)
     1286                addMessage(_t("Collapsible panels enabled."));
     1287            else
     1288                addMessage(_t("Collapsible panels disabled."));
     1289            _util.setCollapsePanels(collapsePanels);
     1290            changed = true;
     1291        }
    12651292        if (changed) {
    12661293            saveConfig();
     
    14861513                        fis = null;
    14871514                    } catch (IOException e) {}
    1488                    
     1515
    14891516                    // This test may be a duplicate, but not if we were called
    14901517                    // from the DirMonitor, which only checks for dup torrent file names.
  • apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java

    r47d3547 rdf95e29  
    269269        }
    270270
     271        boolean noCollapse = noCollapsePanels(req);
     272        boolean collapsePanels = _manager.util().collapsePanels();
     273
    271274        setHTMLHeaders(resp);
    272275        PrintWriter out = resp.getWriter();
     
    296299                String downMsg = _context.isRouterContext() ? _t("Router is down") : _t("I2PSnark has stopped");
    297300                // fallback to metarefresh when javascript is disabled
    298                 out.write("<noscript><meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\"></noscript>\n");
     301                out.write("<noscript><meta http-equiv=\"refresh\" content=\"" + delay + ";" + _contextPath + "/" + peerString + "\"></noscript>\n");
    299302                out.write("<script src=\"" + jsPfx + "/js/ajax.js\" type=\"text/javascript\"></script>\n" +
    300303                          "<script type=\"text/javascript\">\n"  +
     
    307310            }
    308311        }
    309         out.write(HEADER_A + _themePath + HEADER_B + "</head>\n");
     312        out.write(HEADER_A + _themePath + HEADER_B);
     313
     314        //  ...and inject CSS to display panels uncollapsed
     315        if (noCollapse || !collapsePanels) {
     316            out.write(HEADER_A + _themePath + HEADER_C);
     317        }
     318        out.write("</head>\n");
     319
    310320        if (isConfigure || delay <= 0)
    311321            out.write("<body>");
     
    382392        resp.setCharacterEncoding("UTF-8");
    383393        resp.setContentType("text/html; charset=UTF-8");
    384         resp.setHeader("Cache-Control", "no-store, max-age=0, no-cache, must-revalidate");
     394        // "no-store, max-age=0" forces all our images to be reloaded on ajax refresh
     395        resp.setHeader("Cache-Control", "max-age=86400, no-cache, must-revalidate");
    385396        resp.setHeader("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'");
    386         resp.setDateHeader("Expires", 0);
     397        resp.setDateHeader("Expires", 86400);
    387398        resp.setHeader("Pragma", "no-cache");
    388399        resp.setHeader("X-Frame-Options", "SAMEORIGIN");
     
    11911202            // commentsName is filtered in SnarkManager.updateConfig()
    11921203            String commentsName = req.getParameter("nofilter_commentsName");
     1204            boolean collapsePanels = req.getParameter("collapsePanels") != null;
    11931205            _manager.updateConfig(dataDir, filesPublic, autoStart, smartSort, refreshDel, startupDel, pageSize,
    11941206                                  seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts,
    11951207                                  upLimit, upBW, useOpenTrackers, useDHT, theme,
    1196                                   lang, ratings, comments, commentsName);
     1208                                  lang, ratings, comments, commentsName, collapsePanels);
    11971209            // update servlet
    11981210            try {
     
    22722284        boolean useRatings = _manager.util().ratingsEnabled();
    22732285        boolean useComments = _manager.util().commentsEnabled();
     2286        boolean collapsePanels = _manager.util().collapsePanels();
    22742287        //int seedPct = 0;
    22752288
    2276         out.write("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" +
     2289        boolean noCollapse = noCollapsePanels(req);
     2290
     2291        out.write("<form action=\"" + _contextPath + "/configure\" method=\"POST\" target=\"_top\">\n" +
    22772292                  "<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n");
    22782293        writeHiddenInputs(out, req, "Save");
     
    23102325        out.write(_t("Smart torrent sorting"));
    23112326        out.write(":</label><td colspan=\"2\"><input type=\"checkbox\" class=\"optbox\" name=\"smartSort\" id=\"smartSort\" value=\"true\" "
    2312                   + (smartSort ? "checked " : "") 
     2327                  + (smartSort ? "checked " : "")
    23132328                  + "title=\"");
    23142329        out.write(_t("Ignore words such as 'a' and 'the' when sorting"));
    2315         out.write("\" >");
     2330        out.write("\" >" +
     2331
     2332                  "<tr><td><label for=\"collapsePanels\">");
     2333        out.write(_t("Collapsible panels"));
     2334        out.write(":</label><td colspan=\"2\"><input type=\"checkbox\" class=\"optbox\" name=\"collapsePanels\" id=\"collapsePanels\" value=\"true\" "
     2335                  + (collapsePanels ? "checked " : "")
     2336                  + "title=\"");
     2337        if (noCollapse) {
     2338            out.write(_t("Your browser does not support this feature."));
     2339            out.write("\" disabled=\"disabled");
     2340        } else {
     2341            out.write(_t("Allow the 'Add Torrent' and 'Create Torrent' panels to be collapsed, and collapse by default in non-embedded mode"));
     2342        }
     2343        out.write("\">");
    23162344
    23172345        if (!_context.isRouterContext()) {
     
    27452773        return buf.toString();
    27462774    }
    2747    
     2775
    27482776    /**
    27492777     * This is for a full URL. For a path only, use encodePath().
     
    27592787    private static final String HEADER_A = "<link href=\"";
    27602788    private static final String HEADER_B = "snark.css?" + CoreVersion.VERSION + "\" rel=\"stylesheet\" type=\"text/css\" >";
    2761 
     2789    private static final String HEADER_C = "nocollapse.css?" + CoreVersion.VERSION + "\" rel=\"stylesheet\" type=\"text/css\" >";
    27622790
    27632791    private static final String TABLE_HEADER = "<table border=\"0\" class=\"snarkTorrents\" width=\"100%\" >\n" +
     
    38523880    }
    38533881
     3882    private static boolean noCollapsePanels(HttpServletRequest req) {
     3883        // check for user agents that can't toggle the collapsible panels...
     3884        String ua = req.getHeader("user-agent");
     3885        return ua != null && (ua.contains("Konq") || ua.contains("konq") ||
     3886                              ua.contains("Qupzilla") || ua.contains("Dillo") ||
     3887                              ua.contains("Netsurf") || ua.contains("Midori"));
     3888    }
     3889
    38543890    /**
    38553891     *  Is "a" equal to "b",
  • history.txt

    r47d3547 rdf95e29  
    2626 * I2PTunnel: Add hostname / destination (b32) information to server section on
    2727   index page (for parity with client tunnels section)
     28 * I2PSnark
     29   - Fix broken collapsible panels issue for browsers that don't support the
     30     feature by conditionally loading override CSS to expand panels by default
     31     and disable hover/active states for panel headings (tickets #2002, #2026)
     32   - Add UI option to configuration section to enable collapsible panels, and
     33     disable the option if a non-compliant browser is detected
     34   - Fix multiple instances of snark refreshing to the homepage (ticket #2028)
     35     (patch supplied by mindless)
     36   - Tentative fix for caching of images so ajax refresh doesn't reload all
     37     image resources
     38   - Standardize 'Save Configuration' action to return to top of the page
     39     (so we can see message log entry)
    2840 * SusiDNS:
    2941   - Reinstate filter removal on addressbook navigation links (ticket #1996)
  • installer/resources/themes/snark/classic/snark.css

    r47d3547 rdf95e29  
    180180     padding: 3px 5px;
    181181     text-align: left;
    182      color: #003;
    183182     border-bottom: 1px solid #89f;
    184183     background: url(images/hat.png) bottom right no-repeat #ddf;
     
    204203     margin-left: -15px;
    205204     font: bold 8pt "Droid Sans Mono", "Andale Mono", "DejaVu Sans Mono", "Lucida Console", monospace;
    206      color: #2c354f;
    207      opacity: 0.95;
     205     color: #4b4b76;
    208206}
    209207
     
    28542852}
    28552853
    2856 #configs tr:nth-child(n+16) {
     2854#configs tr:nth-child(n+17) {
    28572855     display: none;
    28582856}
  • installer/resources/themes/snark/dark/snark.css

    r47d3547 rdf95e29  
    29212921}
    29222922
    2923 #configs tr:nth-child(n+16) {
     2923#configs tr:nth-child(n+17) {
    29242924     display: none;
    29252925}
  • installer/resources/themes/snark/ubergine/snark.css

    r47d3547 rdf95e29  
    170170
    171171.snarkNav:last-child[href="/i2psnark/"] {
    172      border-radius: 2px;
    173172     margin: -5px 0 !important;
    174173     display: inline-block;
     
    187186}
    188187
    189 .nav_main:link:active {
     188.nav_main:link:active, .snarkNav:last-child[href="/i2psnark/"]:active {
    190189     background: #f60 url(images/button_snark_active.png) 11px center no-repeat;
    191190     background-size: 18px auto, 100% 100%;
     
    31643163}
    31653164
    3166 #configs tr:nth-child(n+16) {
     3165#configs tr:nth-child(n+17) {
    31673166     display: none;
    31683167}
  • installer/resources/themes/snark/vanilla/snark.css

    r47d3547 rdf95e29  
    11931193}
    11941194
    1195 #configs, input[type="submit"], .trackerconfig input[type="submit"], input[name="savepri"] {
     1195input[type="submit"], .trackerconfig input[type="submit"], input[name="savepri"], select[name="theme"] {
    11961196     text-transform: capitalize;
    11971197}
     
    22172217}
    22182218
     2219#configs input:disabled, #configs input:disabled:hover, #configs input:disabled:focus {
     2220     cursor: not-allowed;
     2221     filter: sepia(50%) invert(80%) hue-rotate(150deg) !important;
     2222     box-shadow: none;
     2223}
     2224
    22192225td#bwHelp {
    22202226     background: url(images/infocircle.png) left 10px center no-repeat;
     
    30873093}
    30883094
    3089 #configs tr:nth-child(n+16) {
     3095#configs tr:nth-child(n+17) {
    30903096     display: none;
    30913097}
Note: See TracChangeset for help on using the changeset viewer.